diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 5c93d2aa..a9096713 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_aarch64 #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_aarch64 #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_aarch64 +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_aarch64 +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_aarch64 #define tcg_gen_discard_i64 tcg_gen_discard_i64_aarch64 #define tcg_gen_div_i32 tcg_gen_div_i32_aarch64 #define tcg_gen_div_i64 tcg_gen_div_i64_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 4851c476..d15170b0 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_aarch64eb #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_aarch64eb #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_aarch64eb +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_aarch64eb +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_aarch64eb #define tcg_gen_discard_i64 tcg_gen_discard_i64_aarch64eb #define tcg_gen_div_i32 tcg_gen_div_i32_aarch64eb #define tcg_gen_div_i64 tcg_gen_div_i64_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 040ca47c..c2a170d6 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_arm #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_arm #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_arm +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_arm +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_arm #define tcg_gen_discard_i64 tcg_gen_discard_i64_arm #define tcg_gen_div_i32 tcg_gen_div_i32_arm #define tcg_gen_div_i64 tcg_gen_div_i64_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 08eb026d..12d4b980 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_armeb #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_armeb #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_armeb +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_armeb +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_armeb #define tcg_gen_discard_i64 tcg_gen_discard_i64_armeb #define tcg_gen_div_i32 tcg_gen_div_i32_armeb #define tcg_gen_div_i64 tcg_gen_div_i64_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index f2ed8554..77bbd45c 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3017,6 +3017,8 @@ symbols = ( 'tcg_gen_concat_i32_i64', 'tcg_gen_deposit_i32', 'tcg_gen_deposit_i64', + 'tcg_gen_deposit_z_i32', + 'tcg_gen_deposit_z_i64', 'tcg_gen_discard_i64', 'tcg_gen_div_i32', 'tcg_gen_div_i64', diff --git a/qemu/m68k.h b/qemu/m68k.h index c596083b..83032ea0 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_m68k #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_m68k #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_m68k +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_m68k +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_m68k #define tcg_gen_discard_i64 tcg_gen_discard_i64_m68k #define tcg_gen_div_i32 tcg_gen_div_i32_m68k #define tcg_gen_div_i64 tcg_gen_div_i64_m68k diff --git a/qemu/mips.h b/qemu/mips.h index e83204fa..7d81c2de 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_mips #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_mips #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_mips +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_mips +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_mips #define tcg_gen_discard_i64 tcg_gen_discard_i64_mips #define tcg_gen_div_i32 tcg_gen_div_i32_mips #define tcg_gen_div_i64 tcg_gen_div_i64_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index de7d83db..ecd20397 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_mips64 #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_mips64 #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_mips64 +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_mips64 +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_mips64 #define tcg_gen_discard_i64 tcg_gen_discard_i64_mips64 #define tcg_gen_div_i32 tcg_gen_div_i32_mips64 #define tcg_gen_div_i64 tcg_gen_div_i64_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 7436b1e9..e985dba5 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_mips64el #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_mips64el #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_mips64el +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_mips64el +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_mips64el #define tcg_gen_discard_i64 tcg_gen_discard_i64_mips64el #define tcg_gen_div_i32 tcg_gen_div_i32_mips64el #define tcg_gen_div_i64 tcg_gen_div_i64_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 155921fe..923af6c9 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_mipsel #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_mipsel #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_mipsel +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_mipsel +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_mipsel #define tcg_gen_discard_i64 tcg_gen_discard_i64_mipsel #define tcg_gen_div_i32 tcg_gen_div_i32_mipsel #define tcg_gen_div_i64 tcg_gen_div_i64_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 5beebd13..ca3f560c 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_powerpc #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_powerpc #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_powerpc +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_powerpc +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_powerpc #define tcg_gen_discard_i64 tcg_gen_discard_i64_powerpc #define tcg_gen_div_i32 tcg_gen_div_i32_powerpc #define tcg_gen_div_i64 tcg_gen_div_i64_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 6f446cea..8fcc76fb 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_sparc #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_sparc #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_sparc +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_sparc +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_sparc #define tcg_gen_discard_i64 tcg_gen_discard_i64_sparc #define tcg_gen_div_i32 tcg_gen_div_i32_sparc #define tcg_gen_div_i64 tcg_gen_div_i64_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 880c8f76..615b4509 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_sparc64 #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_sparc64 #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_sparc64 +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_sparc64 +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_sparc64 #define tcg_gen_discard_i64 tcg_gen_discard_i64_sparc64 #define tcg_gen_div_i32 tcg_gen_div_i32_sparc64 #define tcg_gen_div_i64 tcg_gen_div_i64_sparc64 diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index 7128010f..f8b6bcbe 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -532,10 +532,11 @@ void tcg_gen_deposit_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 ar TCGv_i32 t1; tcg_debug_assert(ofs < 32); + tcg_debug_assert(len > 0); tcg_debug_assert(len <= 32); tcg_debug_assert(ofs + len <= 32); - if (ofs == 0 && len == 32) { + if (len == 32) { tcg_gen_mov_i32(s, ret, arg2); return; } @@ -559,6 +560,64 @@ void tcg_gen_deposit_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 ar tcg_temp_free_i32(s, t1); } +void tcg_gen_deposit_z_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg, + unsigned int ofs, unsigned int len) +{ + tcg_debug_assert(ofs < 32); + tcg_debug_assert(len > 0); + tcg_debug_assert(len <= 32); + tcg_debug_assert(ofs + len <= 32); + + if (ofs + len == 32) { + tcg_gen_shli_i32(s, ret, arg, ofs); + } else if (ofs == 0) { + tcg_gen_andi_i32(s, ret, arg, (1u << len) - 1); + } else if (TCG_TARGET_HAS_deposit_i32 + && TCG_TARGET_deposit_i32_valid(ofs, len)) { + TCGv_i32 zero = tcg_const_i32(s, 0); + tcg_gen_op5ii_i32(s, INDEX_op_deposit_i32, ret, zero, arg, ofs, len); + tcg_temp_free_i32(s, zero); + } else { + /* To help two-operand hosts we prefer to zero-extend first, + which allows ARG to stay live. */ + switch (len) { + case 16: + if (TCG_TARGET_HAS_ext16u_i32) { + tcg_gen_ext16u_i32(s, ret, arg); + tcg_gen_shli_i32(s, ret, ret, ofs); + return; + } + break; + case 8: + if (TCG_TARGET_HAS_ext8u_i32) { + tcg_gen_ext8u_i32(s, ret, arg); + tcg_gen_shli_i32(s, ret, ret, ofs); + return; + } + break; + } + /* Otherwise prefer zero-extension over AND for code size. */ + switch (ofs + len) { + case 16: + if (TCG_TARGET_HAS_ext16u_i32) { + tcg_gen_shli_i32(s, ret, arg, ofs); + tcg_gen_ext16u_i32(s, ret, ret); + return; + } + break; + case 8: + if (TCG_TARGET_HAS_ext8u_i32) { + tcg_gen_shli_i32(s, ret, arg, ofs); + tcg_gen_ext8u_i32(s, ret, ret); + return; + } + break; + } + tcg_gen_andi_i32(s, ret, arg, (1u << len) - 1); + tcg_gen_shli_i32(s, ret, ret, ofs); + } +} + void tcg_gen_extract_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg, unsigned int ofs, unsigned int len) { @@ -1724,10 +1783,11 @@ void tcg_gen_deposit_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 ar TCGv_i64 t1; tcg_debug_assert(ofs < 64); + tcg_debug_assert(len > 0); tcg_debug_assert(len <= 64); tcg_debug_assert(ofs + len <= 64); - if (ofs == 0 && len == 64) { + if (len == 64) { tcg_gen_mov_i64(s, ret, arg2); return; } @@ -1766,6 +1826,91 @@ void tcg_gen_deposit_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 ar tcg_temp_free_i64(s, t1); } +void tcg_gen_deposit_z_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg, + unsigned int ofs, unsigned int len) +{ + tcg_debug_assert(ofs < 64); + tcg_debug_assert(len > 0); + tcg_debug_assert(len <= 64); + tcg_debug_assert(ofs + len <= 64); + + if (ofs + len == 64) { + tcg_gen_shli_i64(s, ret, arg, ofs); + } else if (ofs == 0) { + tcg_gen_andi_i64(s, ret, arg, (1ull << len) - 1); + } else if (TCG_TARGET_HAS_deposit_i64 + && TCG_TARGET_deposit_i64_valid(ofs, len)) { + TCGv_i64 zero = tcg_const_i64(s, 0); + tcg_gen_op5ii_i64(s, INDEX_op_deposit_i64, ret, zero, arg, ofs, len); + tcg_temp_free_i64(s, zero); + } else { + if (TCG_TARGET_REG_BITS == 32) { + if (ofs >= 32) { + tcg_gen_deposit_z_i32(s, TCGV_HIGH(ret), TCGV_LOW(arg), + ofs - 32, len); + tcg_gen_movi_i32(s, TCGV_LOW(ret), 0); + return; + } + if (ofs + len <= 32) { + tcg_gen_deposit_z_i32(s, TCGV_LOW(ret), TCGV_LOW(arg), ofs, len); + tcg_gen_movi_i32(s, TCGV_HIGH(ret), 0); + return; + } + } + /* To help two-operand hosts we prefer to zero-extend first, + which allows ARG to stay live. */ + switch (len) { + case 32: + if (TCG_TARGET_HAS_ext32u_i64) { + tcg_gen_ext32u_i64(s, ret, arg); + tcg_gen_shli_i64(s, ret, ret, ofs); + return; + } + break; + case 16: + if (TCG_TARGET_HAS_ext16u_i64) { + tcg_gen_ext16u_i64(s, ret, arg); + tcg_gen_shli_i64(s, ret, ret, ofs); + return; + } + break; + case 8: + if (TCG_TARGET_HAS_ext8u_i64) { + tcg_gen_ext8u_i64(s, ret, arg); + tcg_gen_shli_i64(s, ret, ret, ofs); + return; + } + break; + } + /* Otherwise prefer zero-extension over AND for code size. */ + switch (ofs + len) { + case 32: + if (TCG_TARGET_HAS_ext32u_i64) { + tcg_gen_shli_i64(s, ret, arg, ofs); + tcg_gen_ext32u_i64(s, ret, ret); + return; + } + break; + case 16: + if (TCG_TARGET_HAS_ext16u_i64) { + tcg_gen_shli_i64(s, ret, arg, ofs); + tcg_gen_ext16u_i64(s, ret, ret); + return; + } + break; + case 8: + if (TCG_TARGET_HAS_ext8u_i64) { + tcg_gen_shli_i64(s, ret, arg, ofs); + tcg_gen_ext8u_i64(s, ret, ret); + return; + } + break; + } + tcg_gen_andi_i64(s, ret, arg, (1ull << len) - 1); + tcg_gen_shli_i64(s, ret, ret, ofs); + } +} + void tcg_gen_extract_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg, unsigned int ofs, unsigned int len) { diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index d1e2a7e9..264e0912 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -300,6 +300,8 @@ void tcg_gen_rotr_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) void tcg_gen_rotri_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, unsigned arg2); void tcg_gen_deposit_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2, unsigned int ofs, unsigned int len); +void tcg_gen_deposit_z_i32(TCGContext *s, TCGv_i32 ret, TCGv_i32 arg, + unsigned int ofs, unsigned int len); 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, @@ -473,6 +475,8 @@ void tcg_gen_rotr_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) void tcg_gen_rotri_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, unsigned arg2); void tcg_gen_deposit_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2, unsigned int ofs, unsigned int len); +void tcg_gen_deposit_z_i64(TCGContext *s, TCGv_i64 ret, TCGv_i64 arg, + unsigned int ofs, unsigned int len); 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, @@ -961,6 +965,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGContext *, TCGv_i64, TCGv, TCGv_i64, TCGArg #define tcg_gen_rotr_tl tcg_gen_rotr_i64 #define tcg_gen_rotri_tl tcg_gen_rotri_i64 #define tcg_gen_deposit_tl tcg_gen_deposit_i64 +#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_const_tl tcg_const_i64 @@ -1051,6 +1056,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGContext *, TCGv_i64, TCGv, TCGv_i64, TCGArg #define tcg_gen_rotr_tl tcg_gen_rotr_i32 #define tcg_gen_rotri_tl tcg_gen_rotri_i32 #define tcg_gen_deposit_tl tcg_gen_deposit_i32 +#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_const_tl tcg_const_i32 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index bf27e4e1..090865ac 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -3011,6 +3011,8 @@ #define tcg_gen_concat_i32_i64 tcg_gen_concat_i32_i64_x86_64 #define tcg_gen_deposit_i32 tcg_gen_deposit_i32_x86_64 #define tcg_gen_deposit_i64 tcg_gen_deposit_i64_x86_64 +#define tcg_gen_deposit_z_i32 tcg_gen_deposit_z_i32_x86_64 +#define tcg_gen_deposit_z_i64 tcg_gen_deposit_z_i64_x86_64 #define tcg_gen_discard_i64 tcg_gen_discard_i64_x86_64 #define tcg_gen_div_i32 tcg_gen_div_i32_x86_64 #define tcg_gen_div_i64 tcg_gen_div_i64_x86_64