From 458942d94e6ea5bd0af5926a25c29c235979b5af Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Tue, 30 Apr 2019 09:20:02 -0400 Subject: [PATCH] tcg: Implement tcg_gen_extract2_{i32,i64} Will be helpful for s390x. Input 128 bit and output 64 bit only, which is sufficient for now. Backports commit 2089fcc9e7b4174d1c351eaa7d277c02188a6dd2 from qemu --- qemu/aarch64.h | 2 ++ qemu/aarch64eb.h | 2 ++ qemu/arm.h | 2 ++ qemu/armeb.h | 2 ++ qemu/header_gen.py | 2 ++ qemu/m68k.h | 2 ++ qemu/mips.h | 2 ++ qemu/mips64.h | 2 ++ qemu/mips64el.h | 2 ++ qemu/mipsel.h | 2 ++ qemu/powerpc.h | 2 ++ qemu/riscv32.h | 2 ++ qemu/riscv64.h | 2 ++ qemu/sparc.h | 2 ++ qemu/sparc64.h | 2 ++ qemu/tcg/tcg-op.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ qemu/tcg/tcg-op.h | 6 ++++++ qemu/x86_64.h | 2 ++ 18 files changed, 82 insertions(+) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index f0856cec..6beaf65b 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_aarch64 #define tcg_gen_extract_i32 tcg_gen_extract_i32_aarch64 #define tcg_gen_extract_i64 tcg_gen_extract_i64_aarch64 +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_aarch64 +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_aarch64 #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_aarch64 #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_aarch64 #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index f57b03ed..d2056df3 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_aarch64eb #define tcg_gen_extract_i32 tcg_gen_extract_i32_aarch64eb #define tcg_gen_extract_i64 tcg_gen_extract_i64_aarch64eb +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_aarch64eb +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_aarch64eb #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_aarch64eb #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_aarch64eb #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index ecc5bf33..e4b75f9b 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_arm #define tcg_gen_extract_i32 tcg_gen_extract_i32_arm #define tcg_gen_extract_i64 tcg_gen_extract_i64_arm +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_arm +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_arm #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_arm #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_arm #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 621dab13..96c1644f 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_armeb #define tcg_gen_extract_i32 tcg_gen_extract_i32_armeb #define tcg_gen_extract_i64 tcg_gen_extract_i64_armeb +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_armeb +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_armeb #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_armeb #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_armeb #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 006f89ad..895bf3b8 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2832,6 +2832,8 @@ symbols = ( 'tcg_gen_extr_i64_i32', 'tcg_gen_extract_i32', 'tcg_gen_extract_i64', + 'tcg_gen_extract2_i32', + 'tcg_gen_extract2_i64', 'tcg_gen_extrh_i64_i32', 'tcg_gen_extrl_i64_i32', 'tcg_gen_extu_i32_i64', diff --git a/qemu/m68k.h b/qemu/m68k.h index 55becd57..9111abba 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_m68k #define tcg_gen_extract_i32 tcg_gen_extract_i32_m68k #define tcg_gen_extract_i64 tcg_gen_extract_i64_m68k +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_m68k +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_m68k #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_m68k #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_m68k #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_m68k diff --git a/qemu/mips.h b/qemu/mips.h index 6a95822b..69471ac4 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_mips #define tcg_gen_extract_i32 tcg_gen_extract_i32_mips #define tcg_gen_extract_i64 tcg_gen_extract_i64_mips +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_mips +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_mips #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_mips #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_mips #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index a6b9a501..ab28888b 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_mips64 #define tcg_gen_extract_i32 tcg_gen_extract_i32_mips64 #define tcg_gen_extract_i64 tcg_gen_extract_i64_mips64 +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_mips64 +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_mips64 #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_mips64 #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_mips64 #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 8c1cdd35..5c8a7563 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_mips64el #define tcg_gen_extract_i32 tcg_gen_extract_i32_mips64el #define tcg_gen_extract_i64 tcg_gen_extract_i64_mips64el +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_mips64el +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_mips64el #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_mips64el #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_mips64el #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index aaae8f54..b3952ce3 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_mipsel #define tcg_gen_extract_i32 tcg_gen_extract_i32_mipsel #define tcg_gen_extract_i64 tcg_gen_extract_i64_mipsel +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_mipsel +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_mipsel #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_mipsel #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_mipsel #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 7a426a92..cf3c43e8 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_powerpc #define tcg_gen_extract_i32 tcg_gen_extract_i32_powerpc #define tcg_gen_extract_i64 tcg_gen_extract_i64_powerpc +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_powerpc +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_powerpc #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_powerpc #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_powerpc #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_powerpc diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 01e1b951..ad6f292c 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_riscv32 #define tcg_gen_extract_i32 tcg_gen_extract_i32_riscv32 #define tcg_gen_extract_i64 tcg_gen_extract_i64_riscv32 +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_riscv32 +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_riscv32 #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_riscv32 #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_riscv32 #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 27530506..ec3082b0 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_riscv64 #define tcg_gen_extract_i32 tcg_gen_extract_i32_riscv64 #define tcg_gen_extract_i64 tcg_gen_extract_i64_riscv64 +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_riscv64 +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_riscv64 #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_riscv64 #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_riscv64 #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index f809bec0..d291ddf8 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_sparc #define tcg_gen_extract_i32 tcg_gen_extract_i32_sparc #define tcg_gen_extract_i64 tcg_gen_extract_i64_sparc +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_sparc +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_sparc #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_sparc #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_sparc #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 9230abd8..017c4491 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_sparc64 #define tcg_gen_extract_i32 tcg_gen_extract_i32_sparc64 #define tcg_gen_extract_i64 tcg_gen_extract_i64_sparc64 +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_sparc64 +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_sparc64 #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_sparc64 #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_sparc64 #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_sparc64 diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index cd4d18e3..c88eebeb 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -816,6 +816,28 @@ void tcg_gen_sextract_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg, tcg_gen_sari_i32(s, ret, ret, 32 - len); } +/* + * Extract 32-bits from a 64-bit input, ah:al, starting from ofs. + * Unlike tcg_gen_extract_i32 above, len is fixed at 32. + */ +void tcg_gen_extract2_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah, + unsigned int ofs) +{ + tcg_debug_assert(ofs <= 32); + if (ofs == 0) { + tcg_gen_mov_i32(s, ret, al); + } else if (ofs == 32) { + tcg_gen_mov_i32(s, ret, ah); + } else if (al == ah) { + tcg_gen_rotri_i32(s, ret, al, ofs); + } else { + TCGv_i32 t0 = tcg_temp_new_i32(s); + tcg_gen_shri_i32(s, t0, al, ofs); + tcg_gen_deposit_i32(s, ret, t0, ah, 32 - ofs, ofs); + tcg_temp_free_i32(s, t0); + } +} + void tcg_gen_movcond_i32(TCGContext *s, TCGCond cond, TCGv_i32 ret, TCGv_i32 c1, TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2) { @@ -2311,6 +2333,28 @@ void tcg_gen_sextract_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg, tcg_gen_sari_i64(s, ret, ret, 64 - len); } +/* + * Extract 64 bits from a 128-bit input, ah:al, starting from ofs. + * Unlike tcg_gen_extract_i64 above, len is fixed at 64. + */ +void tcg_gen_extract2_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah, + unsigned int ofs) +{ + tcg_debug_assert(ofs <= 64); + if (ofs == 0) { + tcg_gen_mov_i64(s, ret, al); + } else if (ofs == 64) { + tcg_gen_mov_i64(s, ret, ah); + } else if (al == ah) { + tcg_gen_rotri_i64(s, ret, al, ofs); + } else { + TCGv_i64 t0 = tcg_temp_new_i64(s); + tcg_gen_shri_i64(s, t0, al, ofs); + tcg_gen_deposit_i64(s, ret, t0, ah, 64 - ofs, ofs); + tcg_temp_free_i64(s, t0); + } +} + void tcg_gen_movcond_i64(TCGContext *s, TCGCond cond, TCGv_i64 ret, TCGv_i64 c1, TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2) { diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index e5134191..1445992b 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -326,6 +326,8 @@ void tcg_gen_extract_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg, unsigned int ofs, unsigned int len); void tcg_gen_sextract_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg, unsigned int ofs, unsigned int len); +void tcg_gen_extract2_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah, + unsigned int ofs); void tcg_gen_brcond_i32(TCGContext *s, TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l); void tcg_gen_brcondi_i32(TCGContext *s, TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l); void tcg_gen_setcond_i32(TCGContext *s, TCGCond cond, TCGv_i32 ret, @@ -511,6 +513,8 @@ void tcg_gen_extract_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg, unsigned int ofs, unsigned int len); void tcg_gen_sextract_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg, unsigned int ofs, unsigned int len); +void tcg_gen_extract2_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah, + unsigned int ofs); void tcg_gen_brcond_i64(TCGContext *s, TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l); void tcg_gen_brcondi_i64(TCGContext *s, TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l); void tcg_gen_setcond_i64(TCGContext *s, TCGCond cond, TCGv_i64 ret, @@ -1081,6 +1085,7 @@ void tcg_gen_stl_vec(TCGContext *, TCGv_vec r, TCGv_ptr base, TCGArg offset, TCG #define tcg_gen_deposit_z_tl tcg_gen_deposit_z_i64 #define tcg_gen_extract_tl tcg_gen_extract_i64 #define tcg_gen_sextract_tl tcg_gen_sextract_i64 +#define tcg_gen_extract2_tl tcg_gen_extract2_i64 #define tcg_const_tl tcg_const_i64 #define tcg_const_local_tl tcg_const_local_i64 #define tcg_gen_movcond_tl tcg_gen_movcond_i64 @@ -1191,6 +1196,7 @@ void tcg_gen_stl_vec(TCGContext *, TCGv_vec r, TCGv_ptr base, TCGArg offset, TCG #define tcg_gen_deposit_z_tl tcg_gen_deposit_z_i32 #define tcg_gen_extract_tl tcg_gen_extract_i32 #define tcg_gen_sextract_tl tcg_gen_sextract_i32 +#define tcg_gen_extract2_tl tcg_gen_extract2_i32 #define tcg_const_tl tcg_const_i32 #define tcg_const_local_tl tcg_const_local_i32 #define tcg_gen_movcond_tl tcg_gen_movcond_i32 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 3167ffab..ff2b7826 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2826,6 +2826,8 @@ #define tcg_gen_extr_i64_i32 tcg_gen_extr_i64_i32_x86_64 #define tcg_gen_extract_i32 tcg_gen_extract_i32_x86_64 #define tcg_gen_extract_i64 tcg_gen_extract_i64_x86_64 +#define tcg_gen_extract2_i32 tcg_gen_extract2_i32_x86_64 +#define tcg_gen_extract2_i64 tcg_gen_extract2_i64_x86_64 #define tcg_gen_extrh_i64_i32 tcg_gen_extrh_i64_i32_x86_64 #define tcg_gen_extrl_i64_i32 tcg_gen_extrl_i64_i32_x86_64 #define tcg_gen_extu_i32_i64 tcg_gen_extu_i32_i64_x86_64