@@ -70,7 +70,6 @@ typedef enum {
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 1
@@ -100,6 +99,11 @@ typedef enum {
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
__builtin___clear_cache((char *)start, (char *)stop);
@@ -102,7 +102,6 @@ extern bool have_bmi1;
#define TCG_TARGET_HAS_mulsh_i32 0
#if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
@@ -129,6 +128,12 @@ extern bool have_bmi1;
#define TCG_TARGET_HAS_muls2_i64 1
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
+
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
#endif
#define TCG_TARGET_deposit_i32_valid(ofs, len) \
@@ -160,11 +160,15 @@ typedef enum {
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_mulsh_i64 0
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
#define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) <= 16)
#define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) <= 16)
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_neg_i32 0 /* sub r1, r0, r3 */
#define TCG_TARGET_HAS_neg_i64 0 /* sub r1, r0, r3 */
@@ -77,7 +77,6 @@ typedef enum {
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 1
@@ -105,6 +104,12 @@ typedef enum {
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
+
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
#endif
void flush_icache_range(uintptr_t start, uintptr_t stop);
@@ -72,7 +72,6 @@ typedef enum TCGReg {
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
#define TCG_TARGET_HAS_div2_i64 1
#define TCG_TARGET_HAS_rot_i64 1
@@ -101,6 +100,11 @@ typedef enum TCGReg {
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
extern bool tcg_target_deposit_valid(int ofs, int len);
#define TCG_TARGET_deposit_i32_valid tcg_target_deposit_valid
#define TCG_TARGET_deposit_i64_valid tcg_target_deposit_valid
@@ -118,7 +118,6 @@ extern bool use_vis3_instructions;
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 1
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 0
@@ -147,6 +146,11 @@ extern bool use_vis3_instructions;
#define TCG_TARGET_HAS_muluh_i64 use_vis3_instructions
#define TCG_TARGET_HAS_mulsh_i64 0
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 1
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
#define TCG_AREG0 TCG_REG_I0
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
@@ -1769,6 +1769,9 @@ void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
if (TCG_TARGET_REG_BITS == 32) {
tcg_gen_mov_i32(TCGV_LOW(ret), arg);
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
+ } else if (TCG_TARGET_HAS_extu_i32_i64) {
+ tcg_gen_op2(&tcg_ctx, INDEX_op_extu_i32_i64,
+ GET_TCGV_I64(ret), GET_TCGV_I32(arg));
} else {
/* Note: we assume the target supports move between
32 and 64 bit registers. */
@@ -1781,6 +1784,9 @@ void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
if (TCG_TARGET_REG_BITS == 32) {
tcg_gen_mov_i32(TCGV_LOW(ret), arg);
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
+ } else if (TCG_TARGET_HAS_extu_i32_i64) {
+ tcg_gen_op2(&tcg_ctx, INDEX_op_ext_i32_i64,
+ GET_TCGV_I64(ret), GET_TCGV_I32(arg));
} else {
/* Note: we assume the target supports move between
32 and 64 bit registers. */
@@ -138,6 +138,9 @@ DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
+/* size changing ops */
+DEF(ext_i32_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext_i32_i64))
+DEF(extu_i32_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_extu_i32_i64))
DEF(trunc_shr_i64_i32, 1, 1, 1,
IMPL(TCG_TARGET_HAS_trunc_shr_i64_i32)
| (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
@@ -84,7 +84,6 @@
#define TCG_TARGET_HAS_mulsh_i32 0
#if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
@@ -115,6 +114,12 @@
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muluh_i64 0
#define TCG_TARGET_HAS_mulsh_i64 0
+
+/* size changing optional ops */
+#define TCG_TARGET_HAS_trunc_shr_i64_i32 0
+#define TCG_TARGET_HAS_ext_i32_i64 0
+#define TCG_TARGET_HAS_extu_i32_i64 0
+
#else
#define TCG_TARGET_HAS_mulu2_i32 1
#endif /* TCG_TARGET_REG_BITS == 64 */
Implement optional but real ext_i32_i64 and extu_i32_i64 ops. When implemented, these ensure that a 32-bit value is always converted to a 64-bit value and not propagated through the register allocator or the optimizer. Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> --- tcg/aarch64/tcg-target.h | 6 +++++- tcg/i386/tcg-target.h | 7 ++++++- tcg/ia64/tcg-target.h | 6 +++++- tcg/ppc/tcg-target.h | 7 ++++++- tcg/s390/tcg-target.h | 6 +++++- tcg/sparc/tcg-target.h | 6 +++++- tcg/tcg-op.c | 6 ++++++ tcg/tcg-opc.h | 3 +++ tcg/tci/tcg-target.h | 7 ++++++- 9 files changed, 47 insertions(+), 7 deletions(-)