From 1a057554cc2e3ece8ed166f12a9b85cd5ec4cbe1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 12:08:46 -0700 Subject: [PATCH 01/15] tcg: Replace if + tcg_abort with tcg_debug_assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/i386/tcg-target.c.inc | 8 +++----- tcg/tcg.c | 4 +--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 5a151fe64a..dfd41c7bf1 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1369,8 +1369,8 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) } } -/* Use SMALL != 0 to force a short forward branch. */ -static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int small) +/* Set SMALL to force a short forward branch. */ +static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, bool small) { int32_t val, val1; @@ -1385,9 +1385,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, TCGLabel *l, int small) } tcg_out8(s, val1); } else { - if (small) { - tcg_abort(); - } + tcg_debug_assert(!small); if (opc == -1) { tcg_out8(s, OPC_JMP_long); tcg_out32(s, val - 5); diff --git a/tcg/tcg.c b/tcg/tcg.c index bb52bc060b..100f81edb2 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1174,9 +1174,7 @@ static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type, { TCGTemp *ts; - if (TCG_TARGET_REG_BITS == 32 && type != TCG_TYPE_I32) { - tcg_abort(); - } + tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32); ts = tcg_global_alloc(s); ts->base_type = type; From 732e89f4c401c3cf175aa84c987a029b9729070b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 12:09:14 -0700 Subject: [PATCH 02/15] tcg: Replace tcg_abort with g_assert_not_reached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/tcg/tcg.h | 6 ------ target/i386/tcg/translate.c | 20 ++++++++++---------- target/s390x/tcg/translate.c | 4 ++-- tcg/aarch64/tcg-target.c.inc | 4 ++-- tcg/arm/tcg-target.c.inc | 2 +- tcg/i386/tcg-target.c.inc | 14 +++++++------- tcg/mips/tcg-target.c.inc | 14 +++++++------- tcg/optimize.c | 10 ++++------ tcg/ppc/tcg-target.c.inc | 8 ++++---- tcg/s390x/tcg-target.c.inc | 8 ++++---- tcg/sparc64/tcg-target.c.inc | 2 +- tcg/tcg.c | 8 ++++---- tcg/tci/tcg-target.c.inc | 2 +- 13 files changed, 47 insertions(+), 55 deletions(-) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 5cfaa53938..b19e167e1d 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -967,12 +967,6 @@ typedef struct TCGTargetOpDef { const char *args_ct_str[TCG_MAX_OP_ARGS]; } TCGTargetOpDef; -#define tcg_abort() \ -do {\ - fprintf(stderr, "%s:%d: tcg fatal error\n", __FILE__, __LINE__);\ - abort();\ -} while (0) - bool tcg_op_supported(TCGOpcode op); void tcg_gen_callN(void *func, TCGTemp *ret, int nargs, TCGTemp **args); diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 9dfad2f7bc..91c9c0c478 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -476,7 +476,7 @@ static TCGv gen_op_deposit_reg_v(DisasContext *s, MemOp ot, int reg, TCGv dest, break; #endif default: - tcg_abort(); + g_assert_not_reached(); } return cpu_regs[reg]; } @@ -660,7 +660,7 @@ static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0, } break; default: - tcg_abort(); + g_assert_not_reached(); } if (ovr_seg >= 0) { @@ -765,7 +765,7 @@ static void gen_helper_in_func(MemOp ot, TCGv v, TCGv_i32 n) gen_helper_inl(v, cpu_env, n); break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -782,7 +782,7 @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n) gen_helper_outl(cpu_env, v, n); break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1932,7 +1932,7 @@ static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1, break; #endif default: - tcg_abort(); + g_assert_not_reached(); } } else { switch (ot) { @@ -1951,7 +1951,7 @@ static void gen_rotc_rm_T1(DisasContext *s, MemOp ot, int op1, break; #endif default: - tcg_abort(); + g_assert_not_reached(); } } /* store */ @@ -2282,7 +2282,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s, break; default: - tcg_abort(); + g_assert_not_reached(); } done: @@ -2434,7 +2434,7 @@ static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot) ret = x86_ldl_code(env, s); break; default: - tcg_abort(); + g_assert_not_reached(); } return ret; } @@ -3723,7 +3723,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0); break; default: - tcg_abort(); + g_assert_not_reached(); } break; case 0x99: /* CDQ/CWD */ @@ -3748,7 +3748,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu) gen_op_mov_reg_v(s, MO_16, R_EDX, s->T0); break; default: - tcg_abort(); + g_assert_not_reached(); } break; case 0x1af: /* imul Gv, Ev */ diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 2d9b4bbb1f..46b874e94d 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -418,7 +418,7 @@ static int get_mem_index(DisasContext *s) case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT: return MMU_HOME_IDX; default: - tcg_abort(); + g_assert_not_reached(); break; } #endif @@ -652,7 +652,7 @@ static void gen_op_calc_cc(DisasContext *s) gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr); break; default: - tcg_abort(); + g_assert_not_reached(); } /* We now have cc in cc_op as constant */ diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index a091326f84..1315cb92ab 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1778,7 +1778,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp memop, TCGType ext, tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, otype, off_r); break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1800,7 +1800,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp memop, tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, otype, off_r); break; default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index d06ac60c15..b4daa97e7a 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -2302,7 +2302,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index dfd41c7bf1..b05193050d 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -218,7 +218,7 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type, tcg_patch8(code_ptr, value); break; default: - tcg_abort(); + g_assert_not_reached(); } return true; } @@ -1095,7 +1095,7 @@ static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val) tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0); tcg_out32(s, val); } else { - tcg_abort(); + g_assert_not_reached(); } } @@ -1359,7 +1359,7 @@ static void tgen_arithi(TCGContext *s, int c, int r0, return; } - tcg_abort(); + g_assert_not_reached(); } static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) @@ -1523,7 +1523,7 @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args, label_this, small); break; default: - tcg_abort(); + g_assert_not_reached(); } tcg_out_label(s, label_next); } @@ -1958,7 +1958,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) } break; default: - tcg_abort(); + g_assert_not_reached(); } /* Jump to the code corresponding to next IR of qemu_st */ @@ -2788,7 +2788,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, /* load bits 0..15 */ tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, a2, a0); } else { - tcg_abort(); + g_assert_not_reached(); } break; @@ -2841,7 +2841,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } #undef OP_32_64 diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 80748d892e..668bc73ee6 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -798,7 +798,7 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, break; default: - tcg_abort(); + g_assert_not_reached(); break; } } @@ -855,7 +855,7 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1, break; default: - tcg_abort(); + g_assert_not_reached(); break; } @@ -1337,7 +1337,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) } break; default: - tcg_abort(); + g_assert_not_reached(); } i = tcg_out_call_iarg_imm(s, i, oi); @@ -1527,7 +1527,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg lo, TCGReg hi, } break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1775,7 +1775,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg lo, TCGReg hi, break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1848,7 +1848,7 @@ static void tcg_out_qemu_st_unalign(TCGContext *s, TCGReg lo, TCGReg hi, break; default: - tcg_abort(); + g_assert_not_reached(); } } static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) @@ -2420,7 +2420,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/optimize.c b/tcg/optimize.c index ce05989c39..9614fa3638 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -453,9 +453,7 @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y) return (uint64_t)x % ((uint64_t)y ? : 1); default: - fprintf(stderr, - "Unrecognized operation %d in do_constant_folding.\n", op); - tcg_abort(); + g_assert_not_reached(); } } @@ -493,7 +491,7 @@ static bool do_constant_folding_cond_32(uint32_t x, uint32_t y, TCGCond c) case TCG_COND_GTU: return x > y; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -521,7 +519,7 @@ static bool do_constant_folding_cond_64(uint64_t x, uint64_t y, TCGCond c) case TCG_COND_GTU: return x > y; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -541,7 +539,7 @@ static bool do_constant_folding_cond_eq(TCGCond c) case TCG_COND_EQ: return 1; default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 066b49224a..f4fa12667f 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -1510,7 +1510,7 @@ static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, break; default: - tcg_abort(); + g_assert_not_reached(); } op |= BF(cr) | ((type == TCG_TYPE_I64) << 21); @@ -1681,7 +1681,7 @@ static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond, break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1835,7 +1835,7 @@ static void tcg_out_cmp2(TCGContext *s, const TCGArg *args, break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -3126,7 +3126,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 844532156b..d07d28bcfd 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1641,7 +1641,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data, break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1687,7 +1687,7 @@ static void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc, TCGReg data, break; default: - tcg_abort(); + g_assert_not_reached(); } } @@ -1818,7 +1818,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); break; default: - tcg_abort(); + g_assert_not_reached(); } tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi); tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr); @@ -2645,7 +2645,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 694f2b9dd4..4ee5732b66 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -1701,7 +1701,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } } diff --git a/tcg/tcg.c b/tcg/tcg.c index 100f81edb2..c3a8578951 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -3680,7 +3680,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs, case TEMP_VAL_DEAD: default: - tcg_abort(); + g_assert_not_reached(); } ts->mem_coherent = 1; } @@ -3767,7 +3767,7 @@ static TCGReg tcg_reg_alloc(TCGContext *s, TCGRegSet required_regs, } } - tcg_abort(); + g_assert_not_reached(); } static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs, @@ -3813,7 +3813,7 @@ static TCGReg tcg_reg_alloc_pair(TCGContext *s, TCGRegSet required_regs, } } } - tcg_abort(); + g_assert_not_reached(); } /* Make sure the temporary is in a register. If needed, allocate the register @@ -3860,7 +3860,7 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs, break; case TEMP_VAL_DEAD: default: - tcg_abort(); + g_assert_not_reached(); } set_temp_val_reg(s, ts, reg); } diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index c1d34d7bd1..5309c3ffe1 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -796,7 +796,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ default: - tcg_abort(); + g_assert_not_reached(); } } From 678155b2c50aa3bf37abef6bfe914bf58f49bec2 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 11:17:01 -0700 Subject: [PATCH 03/15] tcg: Split out tcg_out_ext8s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for performing 8-bit sign-extend. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 11 +++++++---- tcg/arm/tcg-target.c.inc | 10 ++++------ tcg/i386/tcg-target.c.inc | 10 +++++----- tcg/loongarch64/tcg-target.c.inc | 11 ++++------- tcg/mips/tcg-target.c.inc | 12 ++++++++---- tcg/ppc/tcg-target.c.inc | 10 ++++------ tcg/riscv/tcg-target.c.inc | 9 +++------ tcg/s390x/tcg-target.c.inc | 10 +++------- tcg/sparc64/tcg-target.c.inc | 7 +++++++ tcg/tcg.c | 21 ++++++++++++++++----- tcg/tci/tcg-target.c.inc | 21 ++++++++++++++++++++- 11 files changed, 81 insertions(+), 51 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 1315cb92ab..4f4f814293 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1419,6 +1419,11 @@ static inline void tcg_out_sxt(TCGContext *s, TCGType ext, MemOp s_bits, tcg_out_sbfm(s, ext, rd, rn, 0, bits); } +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn) +{ + tcg_out_sxt(s, type, MO_8, rd, rn); +} + static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits, TCGReg rd, TCGReg rn) { @@ -2230,10 +2235,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext8s_i64: - case INDEX_op_ext8s_i32: - tcg_out_sxt(s, ext, MO_8, a0, a1); - break; case INDEX_op_ext16s_i64: case INDEX_op_ext16s_i32: tcg_out_sxt(s, ext, MO_16, a0, a1); @@ -2310,6 +2311,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index b4daa97e7a..04a860897f 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -958,10 +958,10 @@ static void tcg_out_udiv(TCGContext *s, ARMCond cond, tcg_out32(s, 0x0730f010 | (cond << 28) | (rd << 16) | rn | (rm << 8)); } -static void tcg_out_ext8s(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) +static void tcg_out_ext8s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn) { /* sxtb */ - tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn); + tcg_out32(s, 0x06af0070 | (COND_AL << 28) | (rd << 12) | rn); } static void __attribute__((unused)) @@ -1533,7 +1533,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) datahi = lb->datahi_reg; switch (opc & MO_SSIZE) { case MO_SB: - tcg_out_ext8s(s, COND_AL, datalo, TCG_REG_R0); + tcg_out_ext8s(s, TCG_TYPE_I32, datalo, TCG_REG_R0); break; case MO_SW: tcg_out_ext16s(s, COND_AL, datalo, TCG_REG_R0); @@ -2244,9 +2244,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_bswap32(s, COND_AL, args[0], args[1]); break; - case INDEX_op_ext8s_i32: - tcg_out_ext8s(s, COND_AL, args[0], args[1]); - break; case INDEX_op_ext16s_i32: tcg_out_ext16s(s, COND_AL, args[0], args[1]); break; @@ -2301,6 +2298,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ default: g_assert_not_reached(); } diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index b05193050d..14e8bdf56b 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1266,8 +1266,9 @@ static inline void tcg_out_ext8u(TCGContext *s, int dest, int src) tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src); } -static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw) +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) { + int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW; /* movsbl */ tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64); tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src); @@ -1929,7 +1930,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) data_reg = l->datalo_reg; switch (opc & MO_SSIZE) { case MO_SB: - tcg_out_ext8s(s, data_reg, TCG_REG_EAX, rexw); + tcg_out_ext8s(s, l->type, data_reg, TCG_REG_EAX); break; case MO_SW: tcg_out_ext16s(s, data_reg, TCG_REG_EAX, rexw); @@ -2669,9 +2670,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0); break; - OP_32_64(ext8s): - tcg_out_ext8s(s, a0, a1, rexw); - break; OP_32_64(ext16s): tcg_out_ext16s(s, a0, a1, rexw); break; @@ -2840,6 +2838,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index c5f55afd68..a96f655c44 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -441,7 +441,7 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31); } -static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { tcg_out_opc_sext_b(s, ret, arg); } @@ -893,7 +893,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) switch (opc & MO_SSIZE) { case MO_SB: - tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0); + tcg_out_ext8s(s, type, l->datalo_reg, TCG_REG_A0); break; case MO_SW: tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0); @@ -1246,11 +1246,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_ext8s_i32: - case INDEX_op_ext8s_i64: - tcg_out_ext8s(s, a0, a1); - break; - case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: tcg_out_ext8u(s, a0, a1); @@ -1627,6 +1622,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 668bc73ee6..8fc9d02bd5 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -552,6 +552,12 @@ static void tcg_out_movi(TCGContext *s, TCGType type, } } +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) +{ + tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32); + tcg_out_opc_reg(s, OPC_SEB, rd, TCG_REG_ZERO, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -2245,10 +2251,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_not_i64: i1 = OPC_NOR; goto do_unary; - case INDEX_op_ext8s_i32: - case INDEX_op_ext8s_i64: - i1 = OPC_SEB; - goto do_unary; case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: i1 = OPC_SEH; @@ -2419,6 +2421,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index f4fa12667f..573067e535 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -775,7 +775,7 @@ static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs, tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me)); } -static inline void tcg_out_ext8s(TCGContext *s, TCGReg dst, TCGReg src) +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src) { tcg_out32(s, EXTSB | RA(dst) | RS(src)); } @@ -2626,7 +2626,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ld8s_i32: case INDEX_op_ld8s_i64: tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]); - tcg_out_ext8s(s, args[0], args[0]); + tcg_out_ext8s(s, TCG_TYPE_REG, args[0], args[0]); break; case INDEX_op_ld16u_i32: case INDEX_op_ld16u_i64: @@ -2974,10 +2974,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_ext8s_i32: - case INDEX_op_ext8s_i64: - tcg_out_ext8s(s, args[0], args[1]); - break; case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: tcg_out_ext16s(s, args[0], args[1]); @@ -3125,6 +3121,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 558de127ef..04b27f6887 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -585,7 +585,7 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_opc_imm(s, OPC_SRLI, ret, ret, 32); } -static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg) +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 24); tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24); @@ -1612,11 +1612,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32u(s, a0, a1); break; - case INDEX_op_ext8s_i32: - case INDEX_op_ext8s_i64: - tcg_out_ext8s(s, a0, a1); - break; - case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: tcg_out_ext16s(s, a0, a1); @@ -1651,6 +1646,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index d07d28bcfd..1232ccb122 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1092,7 +1092,7 @@ static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src, tcg_out16(s, (ofs << 8) | (RIEf_RISBG & 0xff)); } -static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) { tcg_out_insn(s, RRE, LGBR, dest, src); } @@ -2233,9 +2233,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext8s_i32: - tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]); - break; case INDEX_op_ext16s_i32: tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]); break; @@ -2537,9 +2534,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext8s_i64: - tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]); - break; case INDEX_op_ext16s_i64: tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]); break; @@ -2644,6 +2638,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 4ee5732b66..7952cfc4da 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -496,6 +496,11 @@ static void tcg_out_movi(TCGContext *s, TCGType type, tcg_out_movi_int(s, type, ret, arg, false, TCG_REG_T2); } +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) +{ + g_assert_not_reached(); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1700,6 +1705,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index c3a8578951..76ba3e28cd 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -105,6 +105,7 @@ static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1, static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, tcg_target_long arg); +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4496,11 +4497,21 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) } /* emit instruction */ - if (def->flags & TCG_OPF_VECTOR) { - tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), - new_args, const_args); - } else { - tcg_out_op(s, op->opc, new_args, const_args); + switch (op->opc) { + case INDEX_op_ext8s_i32: + tcg_out_ext8s(s, TCG_TYPE_I32, new_args[0], new_args[1]); + break; + case INDEX_op_ext8s_i64: + tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]); + break; + default: + if (def->flags & TCG_OPF_VECTOR) { + tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), + new_args, const_args); + } else { + tcg_out_op(s, op->opc, new_args, const_args); + } + break; } /* move the outputs in the correct register if needed */ diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 5309c3ffe1..029508e308 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -557,6 +557,24 @@ static void tcg_out_movi(TCGContext *s, TCGType type, } } +static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) +{ + switch (type) { + case TCG_TYPE_I32: + tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32); + tcg_out_op_rr(s, INDEX_op_ext8s_i32, rd, rs); + break; +#if TCG_TARGET_REG_BITS == 64 + case TCG_TYPE_I64: + tcg_debug_assert(TCG_TARGET_HAS_ext8s_i64); + tcg_out_op_rr(s, INDEX_op_ext8s_i64, rd, rs); + break; +#endif + default: + g_assert_not_reached(); + } +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -715,7 +733,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_32_64(ext8s) /* Optional (TCG_TARGET_HAS_ext8s_*). */ CASE_32_64(ext8u) /* Optional (TCG_TARGET_HAS_ext8u_*). */ CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */ CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */ @@ -795,6 +812,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_call: /* Always emitted via tcg_out_call. */ case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ + case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8s_i64: default: g_assert_not_reached(); } From d0e66c897f2cdfb0807b76567a17d7811487fac3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 13:26:51 -0700 Subject: [PATCH 04/15] tcg: Split out tcg_out_ext8u MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for performing 8-bit zero-extend. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 11 +++++++---- tcg/arm/tcg-target.c.inc | 12 +++++++++--- tcg/i386/tcg-target.c.inc | 7 +++---- tcg/loongarch64/tcg-target.c.inc | 7 ++----- tcg/mips/tcg-target.c.inc | 9 ++++++++- tcg/ppc/tcg-target.c.inc | 7 +++++++ tcg/riscv/tcg-target.c.inc | 7 ++----- tcg/s390x/tcg-target.c.inc | 14 +++++--------- tcg/sparc64/tcg-target.c.inc | 9 ++++++++- tcg/tcg.c | 5 +++++ tcg/tci/tcg-target.c.inc | 14 +++++++++++++- 11 files changed, 69 insertions(+), 33 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 4f4f814293..cca91363ce 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1432,6 +1432,11 @@ static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits, tcg_out_ubfm(s, 0, rd, rn, 0, bits); } +static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_uxt(s, MO_8, rd, rn); +} + static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm) { @@ -2243,10 +2248,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1); break; - case INDEX_op_ext8u_i64: - case INDEX_op_ext8u_i32: - tcg_out_uxt(s, MO_8, a0, a1); - break; case INDEX_op_ext16u_i64: case INDEX_op_ext16u_i32: tcg_out_uxt(s, MO_16, a0, a1); @@ -2313,6 +2314,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 04a860897f..b99f08a54b 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -964,8 +964,13 @@ static void tcg_out_ext8s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn) tcg_out32(s, 0x06af0070 | (COND_AL << 28) | (rd << 12) | rn); } +static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_dat_imm(s, COND_AL, ARITH_AND, rd, rn, 0xff); +} + static void __attribute__((unused)) -tcg_out_ext8u(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) +tcg_out_ext8u_cond(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) { tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff); } @@ -1365,8 +1370,8 @@ static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGTYPE arg) \ DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32, (tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) -DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u, - (tcg_out_ext8u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) +DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u_cond, + (tcg_out_ext8u_cond(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u, (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, ) @@ -2299,6 +2304,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */ case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ + case INDEX_op_ext8u_i32: default: g_assert_not_reached(); } diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 14e8bdf56b..462a2348c6 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1259,7 +1259,7 @@ static inline void tcg_out_rolw_8(TCGContext *s, int reg) tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8); } -static inline void tcg_out_ext8u(TCGContext *s, int dest, int src) +static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src) { /* movzbl */ tcg_debug_assert(src < 4 || TCG_TARGET_REG_BITS == 64); @@ -2673,9 +2673,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, OP_32_64(ext16s): tcg_out_ext16s(s, a0, a1, rexw); break; - OP_32_64(ext8u): - tcg_out_ext8u(s, a0, a1); - break; OP_32_64(ext16u): tcg_out_ext16u(s, a0, a1); break; @@ -2840,6 +2837,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index a96f655c44..a206b9cfc5 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -1246,11 +1246,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_ext8u_i32: - case INDEX_op_ext8u_i64: - tcg_out_ext8u(s, a0, a1); - break; - case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: tcg_out_ext16s(s, a0, a1); @@ -1624,6 +1619,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 8fc9d02bd5..5a712e3da5 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -558,6 +558,11 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) tcg_out_opc_reg(s, OPC_SEB, rd, TCG_REG_ZERO, rs); } +static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xff); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1099,7 +1104,7 @@ static int tcg_out_call_iarg_reg8(TCGContext *s, int i, TCGReg arg) if (i < ARRAY_SIZE(tcg_target_call_iarg_regs)) { tmp = tcg_target_call_iarg_regs[i]; } - tcg_out_opc_imm(s, OPC_ANDI, tmp, arg, 0xff); + tcg_out_ext8u(s, tmp, arg); return tcg_out_call_iarg_reg(s, i, tmp); } @@ -2423,6 +2428,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 573067e535..ec8e5a1a8a 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -780,6 +780,11 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src) tcg_out32(s, EXTSB | RA(dst) | RS(src)); } +static void tcg_out_ext8u(TCGContext *s, TCGReg dst, TCGReg src) +{ + tcg_out32(s, ANDI | SAI(src, dst, 0xff)); +} + static inline void tcg_out_ext16s(TCGContext *s, TCGReg dst, TCGReg src) { tcg_out32(s, EXTSH | RA(dst) | RS(src)); @@ -3123,6 +3128,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 04b27f6887..d9b08014ce 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -1597,11 +1597,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_ext8u_i32: - case INDEX_op_ext8u_i64: - tcg_out_ext8u(s, a0, a1); - break; - case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: tcg_out_ext16u(s, a0, a1); @@ -1648,6 +1643,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 1232ccb122..338a91c591 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1097,7 +1097,7 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) tcg_out_insn(s, RRE, LGBR, dest, src); } -static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) +static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src) { tcg_out_insn(s, RRE, LLGCR, dest, src); } @@ -1153,7 +1153,7 @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val) return; } if ((val & valid) == 0xff) { - tgen_ext8u(s, TCG_TYPE_I64, dest, dest); + tcg_out_ext8u(s, dest, dest); return; } if ((val & valid) == 0xffff) { @@ -1806,7 +1806,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) } switch (opc & MO_SIZE) { case MO_UB: - tgen_ext8u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); + tcg_out_ext8u(s, TCG_REG_R4, data_reg); break; case MO_UW: tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); @@ -2236,9 +2236,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i32: tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]); break; - case INDEX_op_ext8u_i32: - tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]); - break; case INDEX_op_ext16u_i32: tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]); break; @@ -2541,9 +2538,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: tgen_ext32s(s, args[0], args[1]); break; - case INDEX_op_ext8u_i64: - tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]); - break; case INDEX_op_ext16u_i64: tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]); break; @@ -2640,6 +2634,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 7952cfc4da..4792b04b54 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -501,6 +501,11 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) g_assert_not_reached(); } +static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_arithi(s, rd, rs, 0xff, ARITH_AND); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -883,7 +888,7 @@ static void emit_extend(TCGContext *s, TCGReg r, int op) */ switch (op & MO_SIZE) { case MO_8: - tcg_out_arithi(s, r, r, 0xff, ARITH_AND); + tcg_out_ext8u(s, r, r); break; case MO_16: tcg_out_arithi(s, r, r, 16, SHIFT_SLL); @@ -1707,6 +1712,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 76ba3e28cd..b02ffc5679 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -106,6 +106,7 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, tcg_target_long arg); static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); +static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4504,6 +4505,10 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext8s_i64: tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]); break; + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: + tcg_out_ext8u(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 029508e308..e946d9165e 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -575,6 +575,17 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) } } +static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + if (TCG_TARGET_REG_BITS == 64) { + tcg_debug_assert(TCG_TARGET_HAS_ext8u_i64); + tcg_out_op_rr(s, INDEX_op_ext8u_i64, rd, rs); + } else { + tcg_debug_assert(TCG_TARGET_HAS_ext8u_i32); + tcg_out_op_rr(s, INDEX_op_ext8u_i32, rd, rs); + } +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -733,7 +744,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_32_64(ext8u) /* Optional (TCG_TARGET_HAS_ext8u_*). */ CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */ CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */ CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */ @@ -814,6 +824,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8s_i64: + case INDEX_op_ext8u_i32: + case INDEX_op_ext8u_i64: default: g_assert_not_reached(); } From 753e42eada5c790bb3727c262f2e368e81cc788f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 14:49:59 -0700 Subject: [PATCH 05/15] tcg: Split out tcg_out_ext16s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for performing 16-bit sign-extend. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 13 ++++++++----- tcg/arm/tcg-target.c.inc | 10 ++++------ tcg/i386/tcg-target.c.inc | 16 ++++++++-------- tcg/loongarch64/tcg-target.c.inc | 13 +++++-------- tcg/mips/tcg-target.c.inc | 11 ++++++++--- tcg/ppc/tcg-target.c.inc | 12 +++++------- tcg/riscv/tcg-target.c.inc | 9 +++------ tcg/s390x/tcg-target.c.inc | 12 ++++-------- tcg/sparc64/tcg-target.c.inc | 7 +++++++ tcg/tcg.c | 7 +++++++ tcg/tci/tcg-target.c.inc | 21 ++++++++++++++++++++- 11 files changed, 79 insertions(+), 52 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index cca91363ce..3527c14d04 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1424,6 +1424,11 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn) tcg_out_sxt(s, type, MO_8, rd, rn); } +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn) +{ + tcg_out_sxt(s, type, MO_16, rd, rn); +} + static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits, TCGReg rd, TCGReg rn) { @@ -2233,17 +2238,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_rev(s, TCG_TYPE_I32, MO_16, a0, a1); if (a2 & TCG_BSWAP_OS) { /* Output must be sign-extended. */ - tcg_out_sxt(s, ext, MO_16, a0, a0); + tcg_out_ext16s(s, ext, a0, a0); } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { /* Output must be zero-extended, but input isn't. */ tcg_out_uxt(s, MO_16, a0, a0); } break; - case INDEX_op_ext16s_i64: - case INDEX_op_ext16s_i32: - tcg_out_sxt(s, ext, MO_16, a0, a1); - break; case INDEX_op_ext_i32_i64: case INDEX_op_ext32s_i64: tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1); @@ -2316,6 +2317,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i64: + case INDEX_op_ext16s_i32: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index b99f08a54b..cddf977a58 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -975,10 +975,10 @@ tcg_out_ext8u_cond(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff); } -static void tcg_out_ext16s(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) +static void tcg_out_ext16s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn) { /* sxth */ - tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn); + tcg_out32(s, 0x06bf0070 | (COND_AL << 28) | (rd << 12) | rn); } static void tcg_out_ext16u(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) @@ -1541,7 +1541,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_ext8s(s, TCG_TYPE_I32, datalo, TCG_REG_R0); break; case MO_SW: - tcg_out_ext16s(s, COND_AL, datalo, TCG_REG_R0); + tcg_out_ext16s(s, TCG_TYPE_I32, datalo, TCG_REG_R0); break; default: tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0); @@ -2249,9 +2249,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_bswap32(s, COND_AL, args[0], args[1]); break; - case INDEX_op_ext16s_i32: - tcg_out_ext16s(s, COND_AL, args[0], args[1]); - break; case INDEX_op_ext16u_i32: tcg_out_ext16u(s, COND_AL, args[0], args[1]); break; @@ -2305,6 +2302,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */ case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8u_i32: + case INDEX_op_ext16s_i32: default: g_assert_not_reached(); } diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 462a2348c6..21bd828146 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1280,8 +1280,9 @@ static inline void tcg_out_ext16u(TCGContext *s, int dest, int src) tcg_out_modrm(s, OPC_MOVZWL, dest, src); } -static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw) +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) { + int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW; /* movsw[lq] */ tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src); } @@ -1891,7 +1892,6 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) MemOp opc = get_memop(oi); TCGReg data_reg; tcg_insn_unit **label_ptr = &l->label_ptr[0]; - int rexw = (l->type == TCG_TYPE_I64 ? P_REXW : 0); /* resolve label address */ tcg_patch32(label_ptr[0], s->code_ptr - label_ptr[0] - 4); @@ -1933,7 +1933,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_ext8s(s, l->type, data_reg, TCG_REG_EAX); break; case MO_SW: - tcg_out_ext16s(s, data_reg, TCG_REG_EAX, rexw); + tcg_out_ext16s(s, l->type, data_reg, TCG_REG_EAX); break; #if TCG_TARGET_REG_BITS == 64 case MO_SL: @@ -2153,6 +2153,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, TCGReg base, int index, intptr_t ofs, int seg, bool is64, MemOp memop) { + TCGType type = is64 ? TCG_TYPE_I64 : TCG_TYPE_I32; bool use_movbe = false; int rexw = is64 * P_REXW; int movop = OPC_MOVL_GvEv; @@ -2195,7 +2196,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, if (use_movbe) { tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg, datalo, base, index, 0, ofs); - tcg_out_ext16s(s, datalo, datalo, rexw); + tcg_out_ext16s(s, type, datalo, datalo); } else { tcg_out_modrm_sib_offset(s, OPC_MOVSWL + rexw + seg, datalo, base, index, 0, ofs); @@ -2670,9 +2671,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0); break; - OP_32_64(ext16s): - tcg_out_ext16s(s, a0, a1, rexw); - break; OP_32_64(ext16u): tcg_out_ext16u(s, a0, a1); break; @@ -2816,7 +2814,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, if (a1 < 4 && a0 < 8) { tcg_out_modrm(s, OPC_MOVSBL, a0, a1 + 4); } else { - tcg_out_ext16s(s, a0, a1, 0); + tcg_out_ext16s(s, TCG_TYPE_I32, a0, a1); tcg_out_shifti(s, SHIFT_SAR, a0, 8); } break; @@ -2839,6 +2837,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index a206b9cfc5..a365fbcf8f 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -446,7 +446,7 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) tcg_out_opc_sext_b(s, ret, arg); } -static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { tcg_out_opc_sext_h(s, ret, arg); } @@ -896,7 +896,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_ext8s(s, type, l->datalo_reg, TCG_REG_A0); break; case MO_SW: - tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0); + tcg_out_ext16s(s, type, l->datalo_reg, TCG_REG_A0); break; case MO_SL: tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); @@ -1246,11 +1246,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_ext16s_i32: - case INDEX_op_ext16s_i64: - tcg_out_ext16s(s, a0, a1); - break; - case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: tcg_out_ext16u(s, a0, a1); @@ -1351,7 +1346,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_bswap16_i64: tcg_out_opc_revb_2h(s, a0, a1); if (a2 & TCG_BSWAP_OS) { - tcg_out_ext16s(s, a0, a0); + tcg_out_ext16s(s, TCG_TYPE_REG, a0, a0); } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { tcg_out_ext16u(s, a0, a0); } @@ -1621,6 +1616,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 5a712e3da5..9d305b9cf4 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -563,6 +563,12 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xff); } +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) +{ + tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32); + tcg_out_opc_reg(s, OPC_SEH, rd, TCG_REG_ZERO, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -2256,9 +2262,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_not_i64: i1 = OPC_NOR; goto do_unary; - case INDEX_op_ext16s_i32: - case INDEX_op_ext16s_i64: - i1 = OPC_SEH; do_unary: tcg_out_opc_reg(s, i1, a0, TCG_REG_ZERO, a1); break; @@ -2430,6 +2433,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index ec8e5a1a8a..e4b997fca8 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -785,7 +785,7 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg dst, TCGReg src) tcg_out32(s, ANDI | SAI(src, dst, 0xff)); } -static inline void tcg_out_ext16s(TCGContext *s, TCGReg dst, TCGReg src) +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src) { tcg_out32(s, EXTSH | RA(dst) | RS(src)); } @@ -843,7 +843,7 @@ static void tcg_out_bswap16(TCGContext *s, TCGReg dst, TCGReg src, int flags) if (have_isa_3_10) { tcg_out32(s, BRH | RA(dst) | RS(src)); if (flags & TCG_BSWAP_OS) { - tcg_out_ext16s(s, dst, dst); + tcg_out_ext16s(s, TCG_TYPE_REG, dst, dst); } else if ((flags & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { tcg_out_ext16u(s, dst, dst); } @@ -862,7 +862,7 @@ static void tcg_out_bswap16(TCGContext *s, TCGReg dst, TCGReg src, int flags) tcg_out_rlw(s, RLWIMI, tmp, src, 8, 16, 23); if (flags & TCG_BSWAP_OS) { - tcg_out_ext16s(s, dst, tmp); + tcg_out_ext16s(s, TCG_TYPE_REG, dst, tmp); } else { tcg_out_mov(s, TCG_TYPE_REG, dst, tmp); } @@ -2979,10 +2979,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_ext16s_i32: - case INDEX_op_ext16s_i64: - tcg_out_ext16s(s, args[0], args[1]); - break; case INDEX_op_ext_i32_i64: case INDEX_op_ext32s_i64: tcg_out_ext32s(s, args[0], args[1]); @@ -3130,6 +3126,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index d9b08014ce..12ee7b29af 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -591,7 +591,7 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 24); } -static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg) +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) { tcg_out_opc_imm(s, OPC_SLLIW, ret, arg, 16); tcg_out_opc_imm(s, OPC_SRAIW, ret, ret, 16); @@ -1607,11 +1607,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32u(s, a0, a1); break; - case INDEX_op_ext16s_i32: - case INDEX_op_ext16s_i64: - tcg_out_ext16s(s, a0, a1); - break; - case INDEX_op_ext32s_i64: case INDEX_op_extrl_i64_i32: case INDEX_op_ext_i32_i64: @@ -1645,6 +1640,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 338a91c591..024867336a 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1102,7 +1102,7 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_insn(s, RRE, LLGCR, dest, src); } -static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) { tcg_out_insn(s, RRE, LGHR, dest, src); } @@ -1609,7 +1609,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data, case MO_SW | MO_BSWAP: /* swapped sign-extended halfword load */ tcg_out_insn(s, RXY, LRVH, data, base, index, disp); - tgen_ext16s(s, TCG_TYPE_I64, data, data); + tcg_out_ext16s(s, TCG_TYPE_REG, data, data); break; case MO_SW: tcg_out_insn(s, RXY, LGH, data, base, index, disp); @@ -2233,9 +2233,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext16s_i32: - tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]); - break; case INDEX_op_ext16u_i32: tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]); break; @@ -2531,9 +2528,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext16s_i64: - tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]); - break; case INDEX_op_ext_i32_i64: case INDEX_op_ext32s_i64: tgen_ext32s(s, args[0], args[1]); @@ -2636,6 +2630,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 4792b04b54..e4a8bd6e27 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -501,6 +501,11 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) g_assert_not_reached(); } +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) +{ + g_assert_not_reached(); +} + static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) { tcg_out_arithi(s, rd, rs, 0xff, ARITH_AND); @@ -1714,6 +1719,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index b02ffc5679..739f92c2ee 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -106,6 +106,7 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, tcg_target_long arg); static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); @@ -4509,6 +4510,12 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext8u_i64: tcg_out_ext8u(s, new_args[0], new_args[1]); break; + case INDEX_op_ext16s_i32: + tcg_out_ext16s(s, TCG_TYPE_I32, new_args[0], new_args[1]); + break; + case INDEX_op_ext16s_i64: + tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index e946d9165e..167f8123b1 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -586,6 +586,24 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) } } +static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) +{ + switch (type) { + case TCG_TYPE_I32: + tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32); + tcg_out_op_rr(s, INDEX_op_ext16s_i32, rd, rs); + break; +#if TCG_TARGET_REG_BITS == 64 + case TCG_TYPE_I64: + tcg_debug_assert(TCG_TARGET_HAS_ext16s_i64); + tcg_out_op_rr(s, INDEX_op_ext16s_i64, rd, rs); + break; +#endif + default: + g_assert_not_reached(); + } +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -744,7 +762,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_32_64(ext16s) /* Optional (TCG_TARGET_HAS_ext16s_*). */ CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */ CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */ CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */ @@ -826,6 +843,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i64: case INDEX_op_ext8u_i32: case INDEX_op_ext8u_i64: + case INDEX_op_ext16s_i32: + case INDEX_op_ext16s_i64: default: g_assert_not_reached(); } From 379afdff47556f01e75ce2caffd7ae9efa4f1214 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 16:25:22 -0700 Subject: [PATCH 06/15] tcg: Split out tcg_out_ext16u MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for performing 16-bit zero-extend. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 13 ++++++++----- tcg/arm/tcg-target.c.inc | 17 ++++++++++------- tcg/i386/tcg-target.c.inc | 8 +++----- tcg/loongarch64/tcg-target.c.inc | 7 ++----- tcg/mips/tcg-target.c.inc | 5 +++++ tcg/ppc/tcg-target.c.inc | 4 +++- tcg/riscv/tcg-target.c.inc | 7 ++----- tcg/s390x/tcg-target.c.inc | 17 ++++++----------- tcg/sparc64/tcg-target.c.inc | 11 +++++++++-- tcg/tcg.c | 5 +++++ tcg/tci/tcg-target.c.inc | 14 +++++++++++++- 11 files changed, 66 insertions(+), 42 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 3527c14d04..f55829e9ce 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1442,6 +1442,11 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rn) tcg_out_uxt(s, MO_8, rd, rn); } +static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_uxt(s, MO_16, rd, rn); +} + static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm) { @@ -2241,7 +2246,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext16s(s, ext, a0, a0); } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { /* Output must be zero-extended, but input isn't. */ - tcg_out_uxt(s, MO_16, a0, a0); + tcg_out_ext16u(s, a0, a0); } break; @@ -2249,10 +2254,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1); break; - case INDEX_op_ext16u_i64: - case INDEX_op_ext16u_i32: - tcg_out_uxt(s, MO_16, a0, a1); - break; case INDEX_op_extu_i32_i64: case INDEX_op_ext32u_i64: tcg_out_movr(s, TCG_TYPE_I32, a0, a1); @@ -2319,6 +2320,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i64: case INDEX_op_ext16s_i32: + case INDEX_op_ext16u_i64: + case INDEX_op_ext16u_i32: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index cddf977a58..8fa0c6cbc0 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -981,12 +981,18 @@ static void tcg_out_ext16s(TCGContext *s, TCGType t, TCGReg rd, TCGReg rn) tcg_out32(s, 0x06bf0070 | (COND_AL << 28) | (rd << 12) | rn); } -static void tcg_out_ext16u(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn) +static void tcg_out_ext16u_cond(TCGContext *s, ARMCond cond, + TCGReg rd, TCGReg rn) { /* uxth */ tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn); } +static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_ext16u_cond(s, COND_AL, rd, rn); +} + static void tcg_out_bswap16(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn, int flags) { @@ -1372,8 +1378,8 @@ DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32, (tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u_cond, (tcg_out_ext8u_cond(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) -DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u, - (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) +DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u_cond, + (tcg_out_ext16u_cond(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP)) DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, ) static TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg, @@ -2249,10 +2255,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_bswap32(s, COND_AL, args[0], args[1]); break; - case INDEX_op_ext16u_i32: - tcg_out_ext16u(s, COND_AL, args[0], args[1]); - break; - case INDEX_op_deposit_i32: tcg_out_deposit(s, COND_AL, args[0], args[2], args[3], args[4], const_args[2]); @@ -2303,6 +2305,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */ case INDEX_op_ext8u_i32: case INDEX_op_ext16s_i32: + case INDEX_op_ext16u_i32: default: g_assert_not_reached(); } diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 21bd828146..74a0c1885e 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1274,7 +1274,7 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src); } -static inline void tcg_out_ext16u(TCGContext *s, int dest, int src) +static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src) { /* movzwl */ tcg_out_modrm(s, OPC_MOVZWL, dest, src); @@ -2671,10 +2671,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, a0); break; - OP_32_64(ext16u): - tcg_out_ext16u(s, a0, a1); - break; - case INDEX_op_qemu_ld_i32: tcg_out_qemu_ld(s, args, 0); break; @@ -2839,6 +2835,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index a365fbcf8f..08c2b65b19 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -1246,11 +1246,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_ext16u_i32: - case INDEX_op_ext16u_i64: - tcg_out_ext16u(s, a0, a1); - break; - case INDEX_op_ext32u_i64: case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); @@ -1618,6 +1613,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 9d305b9cf4..220060c821 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -569,6 +569,11 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) tcg_out_opc_reg(s, OPC_SEH, rd, TCG_REG_ZERO, rs); } +static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xffff); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index e4b997fca8..28929ed5db 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -790,7 +790,7 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dst, TCGReg src) tcg_out32(s, EXTSH | RA(dst) | RS(src)); } -static inline void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src) +static void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src) { tcg_out32(s, ANDI | SAI(src, dst, 0xffff)); } @@ -3128,6 +3128,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 12ee7b29af..c49decaae9 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -1597,11 +1597,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_ext16u_i32: - case INDEX_op_ext16u_i64: - tcg_out_ext16u(s, a0, a1); - break; - case INDEX_op_ext32u_i64: case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); @@ -1642,6 +1637,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 024867336a..0c489c2341 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1107,7 +1107,7 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) tcg_out_insn(s, RRE, LGHR, dest, src); } -static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) +static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src) { tcg_out_insn(s, RRE, LLGHR, dest, src); } @@ -1157,7 +1157,7 @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val) return; } if ((val & valid) == 0xffff) { - tgen_ext16u(s, TCG_TYPE_I64, dest, dest); + tcg_out_ext16u(s, dest, dest); return; } @@ -1600,7 +1600,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data, case MO_UW | MO_BSWAP: /* swapped unsigned halfword load with upper bits zeroed */ tcg_out_insn(s, RXY, LRVH, data, base, index, disp); - tgen_ext16u(s, TCG_TYPE_I64, data, data); + tcg_out_ext16u(s, data, data); break; case MO_UW: tcg_out_insn(s, RXY, LLGH, data, base, index, disp); @@ -1809,7 +1809,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_ext8u(s, TCG_REG_R4, data_reg); break; case MO_UW: - tgen_ext16u(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); + tcg_out_ext16u(s, TCG_REG_R4, data_reg); break; case MO_UL: tgen_ext32u(s, TCG_REG_R4, data_reg); @@ -2233,10 +2233,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext16u_i32: - tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]); - break; - case INDEX_op_bswap16_i32: a0 = args[0], a1 = args[1], a2 = args[2]; tcg_out_insn(s, RRE, LRVR, a0, a1); @@ -2532,9 +2528,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: tgen_ext32s(s, args[0], args[1]); break; - case INDEX_op_ext16u_i64: - tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]); - break; case INDEX_op_extu_i32_i64: case INDEX_op_ext32u_i64: tgen_ext32u(s, args[0], args[1]); @@ -2632,6 +2625,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index e4a8bd6e27..98784f6545 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -511,6 +511,12 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_arithi(s, rd, rs, 0xff, ARITH_AND); } +static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_arithi(s, rd, rs, 16, SHIFT_SLL); + tcg_out_arithi(s, rd, rd, 16, SHIFT_SRL); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -896,8 +902,7 @@ static void emit_extend(TCGContext *s, TCGReg r, int op) tcg_out_ext8u(s, r, r); break; case MO_16: - tcg_out_arithi(s, r, r, 16, SHIFT_SLL); - tcg_out_arithi(s, r, r, 16, SHIFT_SRL); + tcg_out_ext16u(s, r, r); break; case MO_32: tcg_out_arith(s, r, r, 0, SHIFT_SRL); @@ -1721,6 +1726,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 739f92c2ee..5b0db747e8 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -108,6 +108,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); +static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4516,6 +4517,10 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext16s_i64: tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]); break; + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: + tcg_out_ext16u(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 167f8123b1..49a83942fa 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -604,6 +604,17 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs) } } +static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + if (TCG_TARGET_REG_BITS == 64) { + tcg_debug_assert(TCG_TARGET_HAS_ext16u_i64); + tcg_out_op_rr(s, INDEX_op_ext16u_i64, rd, rs); + } else { + tcg_debug_assert(TCG_TARGET_HAS_ext16u_i32); + tcg_out_op_rr(s, INDEX_op_ext16u_i32, rd, rs); + } +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -762,7 +773,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_32_64(ext16u) /* Optional (TCG_TARGET_HAS_ext16u_*). */ CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */ CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */ CASE_64(ext_i32) @@ -845,6 +855,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext16u_i32: + case INDEX_op_ext16u_i64: default: g_assert_not_reached(); } From 52bf3398c3a2f51d3eaf8fd30dafcdc0cc7fc571 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 17:50:09 -0700 Subject: [PATCH 07/15] tcg: Split out tcg_out_ext32s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for performing 32-bit sign-extend. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 9 +++++++-- tcg/arm/tcg-target.c.inc | 5 +++++ tcg/i386/tcg-target.c.inc | 5 +++-- tcg/loongarch64/tcg-target.c.inc | 2 +- tcg/mips/tcg-target.c.inc | 12 +++++++++--- tcg/ppc/tcg-target.c.inc | 5 +++-- tcg/riscv/tcg-target.c.inc | 2 +- tcg/s390x/tcg-target.c.inc | 10 +++++----- tcg/sparc64/tcg-target.c.inc | 11 ++++++++--- tcg/tcg.c | 4 ++++ tcg/tci/tcg-target.c.inc | 9 ++++++++- 11 files changed, 54 insertions(+), 20 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index f55829e9ce..d7964734c3 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1429,6 +1429,11 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rn) tcg_out_sxt(s, type, MO_16, rd, rn); } +static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_sxt(s, TCG_TYPE_I64, MO_32, rd, rn); +} + static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits, TCGReg rd, TCGReg rn) { @@ -2232,7 +2237,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_bswap32_i64: tcg_out_rev(s, TCG_TYPE_I32, MO_32, a0, a1); if (a2 & TCG_BSWAP_OS) { - tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a0); + tcg_out_ext32s(s, a0, a0); } break; case INDEX_op_bswap32_i32: @@ -2251,7 +2256,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_ext_i32_i64: - case INDEX_op_ext32s_i64: tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1); break; case INDEX_op_extu_i32_i64: @@ -2322,6 +2326,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext16u_i32: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 8fa0c6cbc0..401769bdd6 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -993,6 +993,11 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn) tcg_out_ext16u_cond(s, COND_AL, rd, rn); } +static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn) +{ + g_assert_not_reached(); +} + static void tcg_out_bswap16(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn, int flags) { diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 74a0c1885e..f4ac877aba 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1293,8 +1293,9 @@ static inline void tcg_out_ext32u(TCGContext *s, int dest, int src) tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src); } -static inline void tcg_out_ext32s(TCGContext *s, int dest, int src) +static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src) { + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); tcg_out_modrm(s, OPC_MOVSLQ, dest, src); } @@ -2758,7 +2759,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32u(s, a0, a1); break; case INDEX_op_ext_i32_i64: - case INDEX_op_ext32s_i64: tcg_out_ext32s(s, a0, a1); break; case INDEX_op_extrh_i64_i32: @@ -2837,6 +2837,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index 08c2b65b19..037474510c 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -1251,7 +1251,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32u(s, a0, a1); break; - case INDEX_op_ext32s_i64: case INDEX_op_extrl_i64_i32: case INDEX_op_ext_i32_i64: tcg_out_ext32s(s, a0, a1); @@ -1615,6 +1614,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 220060c821..c57ccb6b3d 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -574,6 +574,12 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_opc_imm(s, OPC_ANDI, rd, rs, 0xffff); } +static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); + tcg_out_opc_sa(s, OPC_SLL, rd, rs, 0); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1313,7 +1319,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) /* delay slot */ if (TCG_TARGET_REG_BITS == 64 && l->type == TCG_TYPE_I32) { /* we always sign-extend 32-bit loads */ - tcg_out_opc_sa(s, OPC_SLL, v0, TCG_REG_V0, 0); + tcg_out_ext32s(s, v0, TCG_REG_V0); } else { tcg_out_opc_reg(s, OPC_OR, v0, TCG_REG_V0, TCG_REG_ZERO); } @@ -2287,10 +2293,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extrh_i64_i32: tcg_out_dsra(s, a0, a1, 32); break; - case INDEX_op_ext32s_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extrl_i64_i32: - tcg_out_opc_sa(s, OPC_SLL, a0, a1, 0); + tcg_out_ext32s(s, a0, a1); break; case INDEX_op_ext32u_i64: case INDEX_op_extu_i32_i64: @@ -2440,6 +2445,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext8u_i64: case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 28929ed5db..0814894099 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -795,8 +795,9 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg dst, TCGReg src) tcg_out32(s, ANDI | SAI(src, dst, 0xffff)); } -static inline void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src) +static void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src) { + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); tcg_out32(s, EXTSW | RA(dst) | RS(src)); } @@ -2980,7 +2981,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_ext_i32_i64: - case INDEX_op_ext32s_i64: tcg_out_ext32s(s, args[0], args[1]); break; case INDEX_op_extu_i32_i64: @@ -3130,6 +3130,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index c49decaae9..9381e113aa 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -1602,7 +1602,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32u(s, a0, a1); break; - case INDEX_op_ext32s_i64: case INDEX_op_extrl_i64_i32: case INDEX_op_ext_i32_i64: tcg_out_ext32s(s, a0, a1); @@ -1639,6 +1638,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 0c489c2341..9aff45cbfd 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1112,7 +1112,7 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_insn(s, RRE, LLGHR, dest, src); } -static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src) +static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src) { tcg_out_insn(s, RRE, LGFR, dest, src); } @@ -1627,7 +1627,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data, case MO_SL | MO_BSWAP: /* swapped sign-extended int load */ tcg_out_insn(s, RXY, LRV, data, base, index, disp); - tgen_ext32s(s, data, data); + tcg_out_ext32s(s, data, data); break; case MO_SL: tcg_out_insn(s, RXY, LGF, data, base, index, disp); @@ -2259,7 +2259,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, a0 = args[0], a1 = args[1], a2 = args[2]; tcg_out_insn(s, RRE, LRVR, a0, a1); if (a2 & TCG_BSWAP_OS) { - tgen_ext32s(s, a0, a0); + tcg_out_ext32s(s, a0, a0); } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { tgen_ext32u(s, a0, a0); } @@ -2525,8 +2525,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_ext_i32_i64: - case INDEX_op_ext32s_i64: - tgen_ext32s(s, args[0], args[1]); + tcg_out_ext32s(s, args[0], args[1]); break; case INDEX_op_extu_i32_i64: case INDEX_op_ext32u_i64: @@ -2627,6 +2626,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 98784f6545..fef19493d0 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -517,6 +517,11 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_arithi(s, rd, rd, 16, SHIFT_SRL); } +static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_arithi(s, rd, rs, 0, SHIFT_SRA); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1213,7 +1218,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, /* We let the helper sign-extend SB and SW, but leave SL for here. */ if (is_64 && (memop & MO_SSIZE) == MO_SL) { - tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA); + tcg_out_ext32s(s, data, TCG_REG_O0); } else { tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0); } @@ -1668,8 +1673,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, c = ARITH_UDIVX; goto gen_arith; case INDEX_op_ext_i32_i64: - case INDEX_op_ext32s_i64: - tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA); + tcg_out_ext32s(s, a0, a1); break; case INDEX_op_extu_i32_i64: case INDEX_op_ext32u_i64: @@ -1728,6 +1732,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 5b0db747e8..84aa8d639e 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -109,6 +109,7 @@ static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg); +static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4521,6 +4522,9 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext16u_i64: tcg_out_ext16u(s, new_args[0], new_args[1]); break; + case INDEX_op_ext32s_i64: + tcg_out_ext32s(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 49a83942fa..04e162a623 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -615,6 +615,13 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs) } } +static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); + tcg_debug_assert(TCG_TARGET_HAS_ext32s_i64); + tcg_out_op_rr(s, INDEX_op_ext32s_i64, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -773,7 +780,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_64(ext32s) /* Optional (TCG_TARGET_HAS_ext32s_i64). */ CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */ CASE_64(ext_i32) CASE_64(extu_i32) @@ -857,6 +863,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: + case INDEX_op_ext32s_i64: default: g_assert_not_reached(); } From 9ecf5f61b8f468f17483f325f565802c645983a5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 18:07:05 -0700 Subject: [PATCH 08/15] tcg: Split out tcg_out_ext32u MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for performing 32-bit zero-extend. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 9 +++++++-- tcg/arm/tcg-target.c.inc | 5 +++++ tcg/i386/tcg-target.c.inc | 4 ++-- tcg/loongarch64/tcg-target.c.inc | 2 +- tcg/mips/tcg-target.c.inc | 3 ++- tcg/ppc/tcg-target.c.inc | 4 +++- tcg/riscv/tcg-target.c.inc | 2 +- tcg/s390x/tcg-target.c.inc | 20 ++++++++++---------- tcg/sparc64/tcg-target.c.inc | 17 +++++++++++------ tcg/tcg.c | 4 ++++ tcg/tci/tcg-target.c.inc | 9 ++++++++- 11 files changed, 54 insertions(+), 25 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index d7964734c3..bca5f03dfb 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1452,6 +1452,11 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rn) tcg_out_uxt(s, MO_16, rd, rn); } +static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_movr(s, TCG_TYPE_I32, rd, rn); +} + static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm) { @@ -2259,8 +2264,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1); break; case INDEX_op_extu_i32_i64: - case INDEX_op_ext32u_i64: - tcg_out_movr(s, TCG_TYPE_I32, a0, a1); + tcg_out_ext32u(s, a0, a1); break; case INDEX_op_deposit_i64: @@ -2327,6 +2331,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext16u_i32: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 401769bdd6..5c48b92f83 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -998,6 +998,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn) g_assert_not_reached(); } +static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn) +{ + g_assert_not_reached(); +} + static void tcg_out_bswap16(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn, int flags) { diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index f4ac877aba..7d63403693 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1287,7 +1287,7 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src); } -static inline void tcg_out_ext32u(TCGContext *s, int dest, int src) +static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src) { /* 32-bit mov zero extends. */ tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src); @@ -2754,7 +2754,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_bswap64(s, a0); break; case INDEX_op_extu_i32_i64: - case INDEX_op_ext32u_i64: case INDEX_op_extrl_i64_i32: tcg_out_ext32u(s, a0, a1); break; @@ -2838,6 +2837,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index 037474510c..d2511eda7a 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -1246,7 +1246,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_ext32u_i64: case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); break; @@ -1615,6 +1614,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index c57ccb6b3d..fe90547c43 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -663,6 +663,7 @@ static void tcg_out_bswap64(TCGContext *s, TCGReg ret, TCGReg arg) static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg) { + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); if (use_mips32r2_instructions) { tcg_out_opc_bf(s, OPC_DEXT, ret, arg, 31, 0); } else { @@ -2297,7 +2298,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extrl_i64_i32: tcg_out_ext32s(s, a0, a1); break; - case INDEX_op_ext32u_i64: case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); break; @@ -2446,6 +2446,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i32: case INDEX_op_ext16s_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 0814894099..55d4524947 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -801,8 +801,9 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg dst, TCGReg src) tcg_out32(s, EXTSW | RA(dst) | RS(src)); } -static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src) +static void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src) { + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); tcg_out_rld(s, RLDICL, dst, src, 0, 32); } @@ -3131,6 +3132,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 9381e113aa..1d91fd19c6 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -1597,7 +1597,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_ext32u_i64: case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); break; @@ -1639,6 +1638,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 9aff45cbfd..825dbfc523 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1117,7 +1117,7 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_insn(s, RRE, LGFR, dest, src); } -static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src) +static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src) { tcg_out_insn(s, RRE, LLGFR, dest, src); } @@ -1149,7 +1149,7 @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val) /* Look for the zero-extensions. */ if ((val & valid) == 0xffffffff) { - tgen_ext32u(s, dest, dest); + tcg_out_ext32u(s, dest, dest); return; } if ((val & valid) == 0xff) { @@ -1440,7 +1440,7 @@ static void tgen_ctpop(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) /* With MIE3, and bit 0 of m4 set, we get the complete result. */ if (HAVE_FACILITY(MISC_INSN_EXT3)) { if (type == TCG_TYPE_I32) { - tgen_ext32u(s, dest, src); + tcg_out_ext32u(s, dest, src); src = dest; } tcg_out_insn(s, RRFc, POPCNT, dest, src, 8); @@ -1618,7 +1618,7 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc, TCGReg data, case MO_UL | MO_BSWAP: /* swapped unsigned int load with upper bits zeroed */ tcg_out_insn(s, RXY, LRV, data, base, index, disp); - tgen_ext32u(s, data, data); + tcg_out_ext32u(s, data, data); break; case MO_UL: tcg_out_insn(s, RXY, LLGF, data, base, index, disp); @@ -1743,7 +1743,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc, offsetof(CPUTLBEntry, addend)); if (TARGET_LONG_BITS == 32) { - tgen_ext32u(s, TCG_REG_R3, addr_reg); + tcg_out_ext32u(s, TCG_REG_R3, addr_reg); return TCG_REG_R3; } return addr_reg; @@ -1812,7 +1812,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_ext16u(s, TCG_REG_R4, data_reg); break; case MO_UL: - tgen_ext32u(s, TCG_REG_R4, data_reg); + tcg_out_ext32u(s, TCG_REG_R4, data_reg); break; case MO_UQ: tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); @@ -1879,7 +1879,7 @@ static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg, TCGReg *index_reg, tcg_target_long *disp) { if (TARGET_LONG_BITS == 32) { - tgen_ext32u(s, TCG_TMP0, *addr_reg); + tcg_out_ext32u(s, TCG_TMP0, *addr_reg); *addr_reg = TCG_TMP0; } if (guest_base < 0x80000) { @@ -2261,7 +2261,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, if (a2 & TCG_BSWAP_OS) { tcg_out_ext32s(s, a0, a0); } else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) { - tgen_ext32u(s, a0, a0); + tcg_out_ext32u(s, a0, a0); } break; @@ -2528,8 +2528,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32s(s, args[0], args[1]); break; case INDEX_op_extu_i32_i64: - case INDEX_op_ext32u_i64: - tgen_ext32u(s, args[0], args[1]); + tcg_out_ext32u(s, args[0], args[1]); break; case INDEX_op_add2_i64: @@ -2627,6 +2626,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index fef19493d0..6464d1fb5e 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -522,6 +522,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_arithi(s, rd, rs, 0, SHIFT_SRA); } +static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_arithi(s, rd, rs, 0, SHIFT_SRL); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -910,7 +915,7 @@ static void emit_extend(TCGContext *s, TCGReg r, int op) tcg_out_ext16u(s, r, r); break; case MO_32: - tcg_out_arith(s, r, r, 0, SHIFT_SRL); + tcg_out_ext32u(s, r, r); break; case MO_64: break; @@ -1134,7 +1139,7 @@ static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index, /* If the guest address must be zero-extended, do so now. */ if (TARGET_LONG_BITS == 32) { - tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL); + tcg_out_ext32u(s, r0, addr); return r0; } return addr; @@ -1231,7 +1236,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, unsigned t_bits; if (TARGET_LONG_BITS == 32) { - tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL); + tcg_out_ext32u(s, TCG_REG_T1, addr); addr = TCG_REG_T1; } @@ -1363,7 +1368,7 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, unsigned t_bits; if (TARGET_LONG_BITS == 32) { - tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL); + tcg_out_ext32u(s, TCG_REG_T1, addr); addr = TCG_REG_T1; } @@ -1676,8 +1681,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_ext32s(s, a0, a1); break; case INDEX_op_extu_i32_i64: - case INDEX_op_ext32u_i64: - tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL); + tcg_out_ext32u(s, a0, a1); break; case INDEX_op_extrl_i64_i32: tcg_out_mov(s, TCG_TYPE_I32, a0, a1); @@ -1733,6 +1737,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 84aa8d639e..a182771c01 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -110,6 +110,7 @@ static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg); static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg); +static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4525,6 +4526,9 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext32s_i64: tcg_out_ext32s(s, new_args[0], new_args[1]); break; + case INDEX_op_ext32u_i64: + tcg_out_ext32u(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 04e162a623..bc7b5a410c 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -622,6 +622,13 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_op_rr(s, INDEX_op_ext32s_i64, rd, rs); } +static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); + tcg_debug_assert(TCG_TARGET_HAS_ext32u_i64); + tcg_out_op_rr(s, INDEX_op_ext32u_i64, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -780,7 +787,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_64(ext32u) /* Optional (TCG_TARGET_HAS_ext32u_i64). */ CASE_64(ext_i32) CASE_64(extu_i32) CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */ @@ -864,6 +870,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: + case INDEX_op_ext32u_i64: default: g_assert_not_reached(); } From 9c6aa274a494ce807e998a3652fa16a3d2da4387 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 18:30:56 -0700 Subject: [PATCH 09/15] tcg: Split out tcg_out_exts_i32_i64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for type extension with sign. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 9 ++++++--- tcg/arm/tcg-target.c.inc | 5 +++++ tcg/i386/tcg-target.c.inc | 9 ++++++--- tcg/loongarch64/tcg-target.c.inc | 7 ++++++- tcg/mips/tcg-target.c.inc | 7 ++++++- tcg/ppc/tcg-target.c.inc | 9 ++++++--- tcg/riscv/tcg-target.c.inc | 7 ++++++- tcg/s390x/tcg-target.c.inc | 9 ++++++--- tcg/sparc64/tcg-target.c.inc | 9 ++++++--- tcg/tcg.c | 4 ++++ tcg/tci/tcg-target.c.inc | 7 ++++++- 11 files changed, 63 insertions(+), 19 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index bca5f03dfb..58596eaa4b 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1434,6 +1434,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rn) tcg_out_sxt(s, TCG_TYPE_I64, MO_32, rd, rn); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_ext32s(s, rd, rn); +} + static inline void tcg_out_uxt(TCGContext *s, MemOp s_bits, TCGReg rd, TCGReg rn) { @@ -2260,9 +2265,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext_i32_i64: - tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1); - break; case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); break; @@ -2332,6 +2334,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i32: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 5c48b92f83..2ca25a3d81 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -1003,6 +1003,11 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn) g_assert_not_reached(); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) +{ + g_assert_not_reached(); +} + static void tcg_out_bswap16(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn, int flags) { diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 7d63403693..fd4c4e20c8 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1299,6 +1299,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_modrm(s, OPC_MOVSLQ, dest, src); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) +{ + tcg_out_ext32s(s, dest, src); +} + static inline void tcg_out_bswap64(TCGContext *s, int reg) { tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0); @@ -2757,9 +2762,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extrl_i64_i32: tcg_out_ext32u(s, a0, a1); break; - case INDEX_op_ext_i32_i64: - tcg_out_ext32s(s, a0, a1); - break; case INDEX_op_extrh_i64_i32: tcg_out_shifti(s, SHIFT_SHR + P_REXW, a0, 32); break; @@ -2838,6 +2840,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index d2511eda7a..989632e08a 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -456,6 +456,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_opc_addi_w(s, ret, arg, 0); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) +{ + tcg_out_ext32s(s, ret, arg); +} + static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, TCGReg a0, TCGReg a1, TCGReg a2, bool c2, bool is_32bit) @@ -1251,7 +1256,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_extrl_i64_i32: - case INDEX_op_ext_i32_i64: tcg_out_ext32s(s, a0, a1); break; @@ -1615,6 +1619,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index fe90547c43..df36bec5c0 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -580,6 +580,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_opc_sa(s, OPC_SLL, rd, rs, 0); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32s(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -2294,7 +2299,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extrh_i64_i32: tcg_out_dsra(s, a0, a1, 32); break; - case INDEX_op_ext_i32_i64: case INDEX_op_extrl_i64_i32: tcg_out_ext32s(s, a0, a1); break; @@ -2447,6 +2451,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16s_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 55d4524947..e24f897765 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -807,6 +807,11 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src) tcg_out_rld(s, RLDICL, dst, src, 0, 32); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dst, TCGReg src) +{ + tcg_out_ext32s(s, dst, src); +} + static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c) { tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c); @@ -2981,9 +2986,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_ext_i32_i64: - tcg_out_ext32s(s, args[0], args[1]); - break; case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, args[0], args[1]); break; @@ -3133,6 +3135,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 1d91fd19c6..7bd3b421ad 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -602,6 +602,11 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_opc_imm(s, OPC_ADDIW, ret, arg, 0); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) +{ + tcg_out_ext32s(s, ret, arg); +} + static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data, TCGReg addr, intptr_t offset) { @@ -1602,7 +1607,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, break; case INDEX_op_extrl_i64_i32: - case INDEX_op_ext_i32_i64: tcg_out_ext32s(s, a0, a1); break; @@ -1639,6 +1643,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 825dbfc523..60deaa9a95 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1122,6 +1122,11 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_insn(s, RRE, LLGFR, dest, src); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) +{ + tcg_out_ext32s(s, dest, src); +} + static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val) { int msb, lsb; @@ -2524,9 +2529,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_ext_i32_i64: - tcg_out_ext32s(s, args[0], args[1]); - break; case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, args[0], args[1]); break; @@ -2627,6 +2629,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 6464d1fb5e..56ffc6ed91 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -527,6 +527,11 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_arithi(s, rd, rs, 0, SHIFT_SRL); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32s(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1677,9 +1682,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_divu_i64: c = ARITH_UDIVX; goto gen_arith; - case INDEX_op_ext_i32_i64: - tcg_out_ext32s(s, a0, a1); - break; case INDEX_op_extu_i32_i64: tcg_out_ext32u(s, a0, a1); break; @@ -1738,6 +1740,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index a182771c01..b0498170ea 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -111,6 +111,7 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg); +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4529,6 +4530,9 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext32u_i64: tcg_out_ext32u(s, new_args[0], new_args[1]); break; + case INDEX_op_ext_i32_i64: + tcg_out_exts_i32_i64(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index bc7b5a410c..7886f21bf5 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -629,6 +629,11 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_op_rr(s, INDEX_op_ext32u_i64, rd, rs); } +static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32s(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -787,7 +792,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_64(ext_i32) CASE_64(extu_i32) CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */ case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */ @@ -871,6 +875,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext16u_i64: case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: + case INDEX_op_ext_i32_i64: default: g_assert_not_reached(); } From b9bfe000f954e1defefb4c917f98bf82c337144b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 18:56:28 -0700 Subject: [PATCH 10/15] tcg: Split out tcg_out_extu_i32_i64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for type extension with zero. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 10 ++++++---- tcg/arm/tcg-target.c.inc | 5 +++++ tcg/i386/tcg-target.c.inc | 7 ++++++- tcg/loongarch64/tcg-target.c.inc | 10 ++++++---- tcg/mips/tcg-target.c.inc | 9 ++++++--- tcg/ppc/tcg-target.c.inc | 10 ++++++---- tcg/riscv/tcg-target.c.inc | 10 ++++++---- tcg/s390x/tcg-target.c.inc | 10 ++++++---- tcg/sparc64/tcg-target.c.inc | 9 ++++++--- tcg/tcg.c | 4 ++++ tcg/tci/tcg-target.c.inc | 7 ++++++- 11 files changed, 63 insertions(+), 28 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 58596eaa4b..ca8b25865b 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1462,6 +1462,11 @@ static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rn) tcg_out_movr(s, TCG_TYPE_I32, rd, rn); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_ext32u(s, rd, rn); +} + static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm) { @@ -2265,10 +2270,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, a0, a1); - break; - case INDEX_op_deposit_i64: case INDEX_op_deposit_i32: tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]); @@ -2335,6 +2336,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 2ca25a3d81..2135616e12 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -1008,6 +1008,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) g_assert_not_reached(); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) +{ + g_assert_not_reached(); +} + static void tcg_out_bswap16(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn, int flags) { diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index fd4c4e20c8..40d661072b 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1304,6 +1304,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_ext32s(s, dest, src); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) +{ + tcg_out_ext32u(s, dest, src); +} + static inline void tcg_out_bswap64(TCGContext *s, int reg) { tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0); @@ -2758,7 +2763,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_bswap64_i64: tcg_out_bswap64(s, a0); break; - case INDEX_op_extu_i32_i64: case INDEX_op_extrl_i64_i32: tcg_out_ext32u(s, a0, a1); break; @@ -2841,6 +2845,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index 989632e08a..6ecde0804f 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -461,6 +461,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_ext32s(s, ret, arg); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) +{ + tcg_out_ext32u(s, ret, arg); +} + static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, TCGReg a0, TCGReg a1, TCGReg a2, bool c2, bool is_32bit) @@ -1251,10 +1256,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, a0, a1); - break; - case INDEX_op_extrl_i64_i32: tcg_out_ext32s(s, a0, a1); break; @@ -1620,6 +1621,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index df36bec5c0..3e455fdb1f 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -585,6 +585,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32s(s, rd, rs); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32u(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -2302,9 +2307,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extrl_i64_i32: tcg_out_ext32s(s, a0, a1); break; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, a0, a1); - break; case INDEX_op_sar_i32: i1 = OPC_SRAV, i2 = OPC_SRA; @@ -2452,6 +2454,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index e24f897765..bd298c55fd 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -812,6 +812,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dst, TCGReg src) tcg_out_ext32s(s, dst, src); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dst, TCGReg src) +{ + tcg_out_ext32u(s, dst, src); +} + static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c) { tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c); @@ -2986,10 +2991,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, args[0], args[1]); - break; - case INDEX_op_setcond_i32: tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2], const_args[2]); @@ -3136,6 +3137,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 7bd3b421ad..064a334d82 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -607,6 +607,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_ext32s(s, ret, arg); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) +{ + tcg_out_ext32u(s, ret, arg); +} + static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data, TCGReg addr, intptr_t offset) { @@ -1602,10 +1607,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, a0, a1); - break; - case INDEX_op_extrl_i64_i32: tcg_out_ext32s(s, a0, a1); break; @@ -1644,6 +1645,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 60deaa9a95..e17d000991 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1127,6 +1127,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_ext32s(s, dest, src); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) +{ + tcg_out_ext32u(s, dest, src); +} + static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val) { int msb, lsb; @@ -2529,10 +2534,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, } break; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, args[0], args[1]); - break; - case INDEX_op_add2_i64: if (const_args[4]) { if ((int64_t)args[4] >= 0) { @@ -2630,6 +2631,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 56ffc6ed91..c57a8c8304 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -532,6 +532,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32s(s, rd, rs); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32u(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1682,9 +1687,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_divu_i64: c = ARITH_UDIVX; goto gen_arith; - case INDEX_op_extu_i32_i64: - tcg_out_ext32u(s, a0, a1); - break; case INDEX_op_extrl_i64_i32: tcg_out_mov(s, TCG_TYPE_I32, a0, a1); break; @@ -1741,6 +1743,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index b0498170ea..17bd6d4581 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -112,6 +112,7 @@ static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4533,6 +4534,9 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_ext_i32_i64: tcg_out_exts_i32_i64(s, new_args[0], new_args[1]); break; + case INDEX_op_extu_i32_i64: + tcg_out_extu_i32_i64(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 7886f21bf5..48c9dbd0b4 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -634,6 +634,11 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32s(s, rd, rs); } +static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32u(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -792,7 +797,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, CASE_32_64(neg) /* Optional (TCG_TARGET_HAS_neg_*). */ CASE_32_64(not) /* Optional (TCG_TARGET_HAS_not_*). */ - CASE_64(extu_i32) CASE_32_64(ctpop) /* Optional (TCG_TARGET_HAS_ctpop_*). */ case INDEX_op_bswap32_i32: /* Optional (TCG_TARGET_HAS_bswap32_i32). */ case INDEX_op_bswap64_i64: /* Optional (TCG_TARGET_HAS_bswap64_i64). */ @@ -876,6 +880,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32s_i64: case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: + case INDEX_op_extu_i32_i64: default: g_assert_not_reached(); } From b8b94ac6753effcfda7880d3b9ac49b530e3d2ab Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 19:58:35 -0700 Subject: [PATCH 11/15] tcg: Split out tcg_out_extrl_i64_i32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need a backend interface for type truncation. For those backends that did not enable TCG_TARGET_HAS_extrl_i64_i32, use tcg_out_mov. Use it in tcg_reg_alloc_op in the meantime. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 6 ++++++ tcg/arm/tcg-target.c.inc | 5 +++++ tcg/i386/tcg-target.c.inc | 9 ++++++--- tcg/loongarch64/tcg-target.c.inc | 10 ++++++---- tcg/mips/tcg-target.c.inc | 9 ++++++--- tcg/ppc/tcg-target.c.inc | 7 +++++++ tcg/riscv/tcg-target.c.inc | 10 ++++++---- tcg/s390x/tcg-target.c.inc | 6 ++++++ tcg/sparc64/tcg-target.c.inc | 9 ++++++--- tcg/tcg.c | 4 ++++ tcg/tci/tcg-target.c.inc | 7 +++++++ 11 files changed, 65 insertions(+), 17 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index ca8b25865b..bd1fab193e 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1467,6 +1467,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) tcg_out_ext32u(s, rd, rn); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_out_mov(s, TCG_TYPE_I32, rd, rn); +} + static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, int64_t aimm) { @@ -2337,6 +2342,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 2135616e12..1820655ee3 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -1013,6 +1013,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rn) g_assert_not_reached(); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rn) +{ + g_assert_not_reached(); +} + static void tcg_out_bswap16(TCGContext *s, ARMCond cond, TCGReg rd, TCGReg rn, int flags) { diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index 40d661072b..f39ef9dd01 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1309,6 +1309,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_ext32u(s, dest, src); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg dest, TCGReg src) +{ + tcg_out_ext32u(s, dest, src); +} + static inline void tcg_out_bswap64(TCGContext *s, int reg) { tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0); @@ -2763,9 +2768,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_bswap64_i64: tcg_out_bswap64(s, a0); break; - case INDEX_op_extrl_i64_i32: - tcg_out_ext32u(s, a0, a1); - break; case INDEX_op_extrh_i64_i32: tcg_out_shifti(s, SHIFT_SHR + P_REXW, a0, 32); break; @@ -2846,6 +2848,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index 6ecde0804f..c8b87a2fd2 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -466,6 +466,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_ext32u(s, ret, arg); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg) +{ + tcg_out_ext32s(s, ret, arg); +} + static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc, TCGReg a0, TCGReg a1, TCGReg a2, bool c2, bool is_32bit) @@ -1256,10 +1261,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_brcond(s, a2, a0, a1, arg_label(args[3])); break; - case INDEX_op_extrl_i64_i32: - tcg_out_ext32s(s, a0, a1); - break; - case INDEX_op_extrh_i64_i32: tcg_out_opc_srai_d(s, a0, a1, 32); break; @@ -1622,6 +1623,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index 3e455fdb1f..b0f9fbc44c 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -590,6 +590,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32u(s, rd, rs); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_ext32s(s, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -2304,9 +2309,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_extrh_i64_i32: tcg_out_dsra(s, a0, a1, 32); break; - case INDEX_op_extrl_i64_i32: - tcg_out_ext32s(s, a0, a1); - break; case INDEX_op_sar_i32: i1 = OPC_SRAV, i2 = OPC_SRA; @@ -2455,6 +2457,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index bd298c55fd..4c4178b700 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -817,6 +817,12 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dst, TCGReg src) tcg_out_ext32u(s, dst, src); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rn) +{ + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); + tcg_out_mov(s, TCG_TYPE_I32, rd, rn); +} + static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c) { tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c); @@ -3138,6 +3144,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 064a334d82..860bf90881 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -612,6 +612,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) tcg_out_ext32u(s, ret, arg); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg) +{ + tcg_out_ext32s(s, ret, arg); +} + static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data, TCGReg addr, intptr_t offset) { @@ -1607,10 +1612,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; - case INDEX_op_extrl_i64_i32: - tcg_out_ext32s(s, a0, a1); - break; - case INDEX_op_extrh_i64_i32: tcg_out_opc_imm(s, OPC_SRAI, a0, a1, 32); break; @@ -1646,6 +1647,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index e17d000991..360229cdd3 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1132,6 +1132,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg dest, TCGReg src) tcg_out_ext32u(s, dest, src); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg dest, TCGReg src) +{ + tcg_out_mov(s, TCG_TYPE_I32, dest, src); +} + static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val) { int msb, lsb; @@ -2632,6 +2637,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index c57a8c8304..18ddd6bb9f 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -537,6 +537,11 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32u(s, rd, rs); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_out_mov(s, TCG_TYPE_I32, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -1687,9 +1692,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_divu_i64: c = ARITH_UDIVX; goto gen_arith; - case INDEX_op_extrl_i64_i32: - tcg_out_mov(s, TCG_TYPE_I32, a0, a1); - break; case INDEX_op_extrh_i64_i32: tcg_out_arithi(s, a0, a1, 32, SHIFT_SRLX); break; @@ -1744,6 +1746,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } diff --git a/tcg/tcg.c b/tcg/tcg.c index 17bd6d4581..0188152c37 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -113,6 +113,7 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); @@ -4537,6 +4538,9 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) case INDEX_op_extu_i32_i64: tcg_out_extu_i32_i64(s, new_args[0], new_args[1]); break; + case INDEX_op_extrl_i64_i32: + tcg_out_extrl_i64_i32(s, new_args[0], new_args[1]); + break; default: if (def->flags & TCG_OPF_VECTOR) { tcg_out_vec_op(s, op->opc, TCGOP_VECL(op), TCGOP_VECE(op), diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 48c9dbd0b4..68531e35ec 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -639,6 +639,12 @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32u(s, rd, rs); } +static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs) +{ + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); + tcg_out_mov(s, TCG_TYPE_I32, rd, rs); +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { @@ -881,6 +887,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_ext32u_i64: case INDEX_op_ext_i32_i64: case INDEX_op_extu_i32_i64: + case INDEX_op_extrl_i64_i32: default: g_assert_not_reached(); } From b3dfd5fc181433bd43e2163b1a94b11a548edfba Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 21:16:28 -0700 Subject: [PATCH 12/15] tcg: Introduce tcg_out_movext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is common code in most qemu_{ld,st} slow paths, extending the input value for the store helper data argument or extending the return value from the load helper. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 8 +--- tcg/arm/tcg-target.c.inc | 16 ++------ tcg/i386/tcg-target.c.inc | 30 +++------------ tcg/loongarch64/tcg-target.c.inc | 53 ++++----------------------- tcg/ppc/tcg-target.c.inc | 38 +++++-------------- tcg/riscv/tcg-target.c.inc | 13 +------ tcg/s390x/tcg-target.c.inc | 19 ++-------- tcg/sparc64/tcg-target.c.inc | 31 +++------------- tcg/tcg.c | 63 ++++++++++++++++++++++++++++++++ 9 files changed, 103 insertions(+), 168 deletions(-) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index bd1fab193e..29bc97ed1c 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1620,7 +1620,6 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { MemOpIdx oi = lb->oi; MemOp opc = get_memop(oi); - MemOp size = opc & MO_SIZE; if (!reloc_pc19(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { return false; @@ -1631,12 +1630,9 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, oi); tcg_out_adr(s, TCG_REG_X3, lb->raddr); tcg_out_call_int(s, qemu_ld_helpers[opc & MO_SIZE]); - if (opc & MO_SIGN) { - tcg_out_sxt(s, lb->type, size, lb->datalo_reg, TCG_REG_X0); - } else { - tcg_out_mov(s, size == MO_64, lb->datalo_reg, TCG_REG_X0); - } + tcg_out_movext(s, lb->type, lb->datalo_reg, + TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_X0); tcg_out_goto(s, lb->raddr); return true; } diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 1820655ee3..ec65cb5720 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -1567,17 +1567,7 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) datalo = lb->datalo_reg; datahi = lb->datahi_reg; - switch (opc & MO_SSIZE) { - case MO_SB: - tcg_out_ext8s(s, TCG_TYPE_I32, datalo, TCG_REG_R0); - break; - case MO_SW: - tcg_out_ext16s(s, TCG_TYPE_I32, datalo, TCG_REG_R0); - break; - default: - tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0); - break; - case MO_UQ: + if ((opc & MO_SIZE) == MO_64) { if (datalo != TCG_REG_R1) { tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0); tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1); @@ -1589,7 +1579,9 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1); tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_TMP); } - break; + } else { + tcg_out_movext(s, TCG_TYPE_I32, datalo, + TCG_TYPE_I32, opc & MO_SSIZE, TCG_REG_R0); } tcg_out_goto(s, COND_AL, lb->raddr); diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index f39ef9dd01..f8c0eed01d 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -1944,28 +1944,8 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_branch(s, 1, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]); data_reg = l->datalo_reg; - switch (opc & MO_SSIZE) { - case MO_SB: - tcg_out_ext8s(s, l->type, data_reg, TCG_REG_EAX); - break; - case MO_SW: - tcg_out_ext16s(s, l->type, data_reg, TCG_REG_EAX); - break; -#if TCG_TARGET_REG_BITS == 64 - case MO_SL: - tcg_out_ext32s(s, data_reg, TCG_REG_EAX); - break; -#endif - case MO_UB: - case MO_UW: - /* Note that the helpers have zero-extended to tcg_target_long. */ - case MO_UL: - tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); - break; - case MO_UQ: - if (TCG_TARGET_REG_BITS == 64) { - tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX); - } else if (data_reg == TCG_REG_EDX) { + if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) { + if (data_reg == TCG_REG_EDX) { /* xchg %edx, %eax */ tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0); tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EAX); @@ -1973,9 +1953,9 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX); tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EDX); } - break; - default: - g_assert_not_reached(); + } else { + tcg_out_movext(s, l->type, data_reg, + TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_EAX); } /* Jump to the code corresponding to next IR of qemu_st */ diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index c8b87a2fd2..f51c4ce81b 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -891,7 +891,6 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) MemOpIdx oi = l->oi; MemOp opc = get_memop(oi); MemOp size = opc & MO_SIZE; - TCGType type = l->type; /* resolve label address */ if (!reloc_br_sk16(l->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) { @@ -906,28 +905,8 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l) tcg_out_call_int(s, qemu_ld_helpers[size], false); - switch (opc & MO_SSIZE) { - case MO_SB: - tcg_out_ext8s(s, type, l->datalo_reg, TCG_REG_A0); - break; - case MO_SW: - tcg_out_ext16s(s, type, l->datalo_reg, TCG_REG_A0); - break; - case MO_SL: - tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); - break; - case MO_UL: - if (type == TCG_TYPE_I32) { - /* MO_UL loads of i32 should be sign-extended too */ - tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0); - break; - } - /* fallthrough */ - default: - tcg_out_mov(s, type, l->datalo_reg, TCG_REG_A0); - break; - } - + tcg_out_movext(s, l->type, l->datalo_reg, + TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_A0); return tcg_out_goto(s, l->raddr); } @@ -945,23 +924,8 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) /* call store helper */ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A0, TCG_AREG0); tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_A1, l->addrlo_reg); - switch (size) { - case MO_8: - tcg_out_ext8u(s, TCG_REG_A2, l->datalo_reg); - break; - case MO_16: - tcg_out_ext16u(s, TCG_REG_A2, l->datalo_reg); - break; - case MO_32: - tcg_out_ext32u(s, TCG_REG_A2, l->datalo_reg); - break; - case MO_64: - tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_A2, l->datalo_reg); - break; - default: - g_assert_not_reached(); - break; - } + tcg_out_movext(s, size == MO_64 ? TCG_TYPE_I32 : TCG_TYPE_I32, TCG_REG_A2, + l->type, size, l->datalo_reg); tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A3, oi); tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A4, (tcg_target_long)l->raddr); @@ -1138,7 +1102,7 @@ static void tcg_out_qemu_st_indexed(TCGContext *s, TCGReg data, } } -static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) +static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGType type) { TCGReg addr_regl; TCGReg data_regl; @@ -1160,8 +1124,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args) tcg_out_tlb_load(s, addr_regl, oi, label_ptr, 0); base = tcg_out_zext_addr_if_32_bit(s, addr_regl, TCG_REG_TMP0); tcg_out_qemu_st_indexed(s, data_regl, base, TCG_REG_TMP2, opc); - add_qemu_ldst_label(s, 0, oi, - 0, /* type param is unused for stores */ + add_qemu_ldst_label(s, 0, oi, type, data_regl, addr_regl, s->code_ptr, label_ptr); #else @@ -1600,10 +1563,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_ld(s, args, TCG_TYPE_I64); break; case INDEX_op_qemu_st_i32: - tcg_out_qemu_st(s, args); + tcg_out_qemu_st(s, args, TCG_TYPE_I32); break; case INDEX_op_qemu_st_i64: - tcg_out_qemu_st(s, args); + tcg_out_qemu_st(s, args, TCG_TYPE_I64); break; case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index 4c4178b700..b1d9c0bbe4 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -1971,10 +1971,6 @@ static const uint32_t qemu_stx_opc[(MO_SIZE + MO_BSWAP) + 1] = { [MO_BSWAP | MO_UQ] = STDBRX, }; -static const uint32_t qemu_exts_opc[4] = { - EXTSB, EXTSH, EXTSW, 0 -}; - #if defined (CONFIG_SOFTMMU) /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr, * int mmu_idx, uintptr_t ra) @@ -2168,11 +2164,9 @@ static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) { tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4); tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3); - } else if (opc & MO_SIGN) { - uint32_t insn = qemu_exts_opc[opc & MO_SIZE]; - tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3)); } else { - tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3); + tcg_out_movext(s, lb->type, lo, + TCG_TYPE_REG, opc & MO_SSIZE, TCG_REG_R3); } tcg_out_b(s, 0, lb->raddr); @@ -2206,25 +2200,13 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) lo = lb->datalo_reg; hi = lb->datahi_reg; - if (TCG_TARGET_REG_BITS == 32) { - switch (s_bits) { - case MO_64: - arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN); - tcg_out_mov(s, TCG_TYPE_I32, arg++, hi); - /* FALLTHRU */ - case MO_32: - tcg_out_mov(s, TCG_TYPE_I32, arg++, lo); - break; - default: - tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31); - break; - } + if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) { + arg |= (TCG_TARGET_CALL_ARG_I64 == TCG_CALL_ARG_EVEN); + tcg_out_mov(s, TCG_TYPE_I32, arg++, hi); + tcg_out_mov(s, TCG_TYPE_I32, arg++, lo); } else { - if (s_bits == MO_64) { - tcg_out_mov(s, TCG_TYPE_I64, arg++, lo); - } else { - tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits)); - } + tcg_out_movext(s, s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32, + arg++, lb->type, s_bits, lo); } tcg_out_movi(s, TCG_TYPE_I32, arg++, oi); @@ -2371,8 +2353,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64) } else { insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)]; tcg_out32(s, insn | TAB(datalo, rbase, addrlo)); - insn = qemu_exts_opc[s_bits]; - tcg_out32(s, insn | RA(datalo) | RS(datalo)); + tcg_out_movext(s, TCG_TYPE_REG, datalo, + TCG_TYPE_REG, opc & MO_SSIZE, datalo); } } diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 860bf90881..0d92135bf6 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -1079,17 +1079,8 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l) /* call store helper */ tcg_out_mov(s, TCG_TYPE_PTR, a0, TCG_AREG0); tcg_out_mov(s, TCG_TYPE_PTR, a1, l->addrlo_reg); - tcg_out_mov(s, TCG_TYPE_PTR, a2, l->datalo_reg); - switch (s_bits) { - case MO_8: - tcg_out_ext8u(s, a2, a2); - break; - case MO_16: - tcg_out_ext16u(s, a2, a2); - break; - default: - break; - } + tcg_out_movext(s, s_bits == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32, a2, + l->type, s_bits, l->datalo_reg); tcg_out_movi(s, TCG_TYPE_PTR, a3, oi); tcg_out_movi(s, TCG_TYPE_PTR, a4, (tcg_target_long)l->raddr); diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 360229cdd3..0578fce4d7 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1809,6 +1809,7 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) TCGReg data_reg = lb->datalo_reg; MemOpIdx oi = lb->oi; MemOp opc = get_memop(oi); + MemOp size = opc & MO_SIZE; if (!patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)tcg_splitwx_to_rx(s->code_ptr), 2)) { @@ -1819,22 +1820,8 @@ static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) if (TARGET_LONG_BITS == 64) { tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg); } - switch (opc & MO_SIZE) { - case MO_UB: - tcg_out_ext8u(s, TCG_REG_R4, data_reg); - break; - case MO_UW: - tcg_out_ext16u(s, TCG_REG_R4, data_reg); - break; - case MO_UL: - tcg_out_ext32u(s, TCG_REG_R4, data_reg); - break; - case MO_UQ: - tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, data_reg); - break; - default: - g_assert_not_reached(); - } + tcg_out_movext(s, size == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32, + TCG_REG_R4, lb->type, size, data_reg); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, oi); tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R6, (uintptr_t)lb->raddr); tcg_out_call_int(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]); diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 18ddd6bb9f..869d9a0521 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -917,26 +917,6 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0) static const tcg_insn_unit *qemu_ld_trampoline[(MO_SSIZE | MO_BSWAP) + 1]; static const tcg_insn_unit *qemu_st_trampoline[(MO_SIZE | MO_BSWAP) + 1]; -static void emit_extend(TCGContext *s, TCGReg r, int op) -{ - /* Emit zero extend of 8, 16 or 32 bit data as - * required by the MO_* value op; do nothing for 64 bit. - */ - switch (op & MO_SIZE) { - case MO_8: - tcg_out_ext8u(s, r, r); - break; - case MO_16: - tcg_out_ext16u(s, r, r); - break; - case MO_32: - tcg_out_ext32u(s, r, r); - break; - case MO_64: - break; - } -} - static void build_trampolines(TCGContext *s) { static void * const qemu_ld_helpers[] = { @@ -993,8 +973,6 @@ static void build_trampolines(TCGContext *s) } qemu_st_trampoline[i] = tcg_splitwx_to_rx(s->code_ptr); - emit_extend(s, TCG_REG_O2, i); - /* Set the retaddr operand. */ tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O4, TCG_REG_O7); @@ -1341,7 +1319,7 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr, } static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, - MemOpIdx oi) + MemOpIdx oi, TCGType data_type) { MemOp memop = get_memop(oi); tcg_insn_unit *label_ptr; @@ -1367,7 +1345,8 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr, /* TLB Miss. */ tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O1, addrz); - tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_O2, data); + tcg_out_movext(s, (memop & MO_SIZE) == MO_64 ? TCG_TYPE_I64 : TCG_TYPE_I32, + TCG_REG_O2, data_type, memop & MO_SIZE, data); func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)]; tcg_debug_assert(func != NULL); @@ -1658,8 +1637,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_ld(s, a0, a1, a2, true); break; case INDEX_op_qemu_st_i32: + tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I32); + break; case INDEX_op_qemu_st_i64: - tcg_out_qemu_st(s, a0, a1, a2); + tcg_out_qemu_st(s, a0, a1, a2, TCG_TYPE_I64); break; case INDEX_op_ld32s_i64: diff --git a/tcg/tcg.c b/tcg/tcg.c index 0188152c37..328e018a80 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -352,6 +352,69 @@ void tcg_raise_tb_overflow(TCGContext *s) siglongjmp(s->jmp_trans, -2); } +/** + * tcg_out_movext -- move and extend + * @s: tcg context + * @dst_type: integral type for destination + * @dst: destination register + * @src_type: integral type for source + * @src_ext: extension to apply to source + * @src: source register + * + * Move or extend @src into @dst, depending on @src_ext and the types. + */ +static void __attribute__((unused)) +tcg_out_movext(TCGContext *s, TCGType dst_type, TCGReg dst, + TCGType src_type, MemOp src_ext, TCGReg src) +{ + switch (src_ext) { + case MO_UB: + tcg_out_ext8u(s, dst, src); + break; + case MO_SB: + tcg_out_ext8s(s, dst_type, dst, src); + break; + case MO_UW: + tcg_out_ext16u(s, dst, src); + break; + case MO_SW: + tcg_out_ext16s(s, dst_type, dst, src); + break; + case MO_UL: + case MO_SL: + if (dst_type == TCG_TYPE_I32) { + if (src_type == TCG_TYPE_I32) { + tcg_out_mov(s, TCG_TYPE_I32, dst, src); + } else { + tcg_out_extrl_i64_i32(s, dst, src); + } + } else if (src_type == TCG_TYPE_I32) { + if (src_ext & MO_SIGN) { + tcg_out_exts_i32_i64(s, dst, src); + } else { + tcg_out_extu_i32_i64(s, dst, src); + } + } else { + if (src_ext & MO_SIGN) { + tcg_out_ext32s(s, dst, src); + } else { + tcg_out_ext32u(s, dst, src); + } + } + break; + case MO_UQ: + tcg_debug_assert(TCG_TARGET_REG_BITS == 64); + if (dst_type == TCG_TYPE_I32) { + tcg_out_extrl_i64_i32(s, dst, src); + } else { + tcg_out_mov(s, TCG_TYPE_I64, dst, src); + } + break; + default: + g_assert_not_reached(); + } +} + #define C_PFX1(P, A) P##A #define C_PFX2(P, A, B) P##A##_##B #define C_PFX3(P, A, B, C) P##A##_##B##_##C From 767c250310ee0494d37bf7514d24973dd50e38ea Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 21:39:54 -0700 Subject: [PATCH 13/15] tcg: Introduce tcg_out_xchg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will want a backend interface for register swapping. This is only properly defined for x86; all others get a stub version that always indicates failure. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c.inc | 5 +++++ tcg/arm/tcg-target.c.inc | 5 +++++ tcg/i386/tcg-target.c.inc | 8 ++++++++ tcg/loongarch64/tcg-target.c.inc | 5 +++++ tcg/mips/tcg-target.c.inc | 5 +++++ tcg/ppc/tcg-target.c.inc | 5 +++++ tcg/riscv/tcg-target.c.inc | 5 +++++ tcg/s390x/tcg-target.c.inc | 5 +++++ tcg/sparc64/tcg-target.c.inc | 5 +++++ tcg/tcg.c | 2 ++ tcg/tci/tcg-target.c.inc | 5 +++++ 11 files changed, 55 insertions(+) diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc index 29bc97ed1c..4ec3cf3172 100644 --- a/tcg/aarch64/tcg-target.c.inc +++ b/tcg/aarch64/tcg-target.c.inc @@ -1106,6 +1106,11 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, tcg_out_insn(s, 3305, LDR, 0, rd); } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index ec65cb5720..8d769ca0a2 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -2607,6 +2607,11 @@ static void tcg_out_movi(TCGContext *s, TCGType type, tcg_out_movi32(s, COND_AL, ret, arg); } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc index f8c0eed01d..c8e2bf537f 100644 --- a/tcg/i386/tcg-target.c.inc +++ b/tcg/i386/tcg-target.c.inc @@ -460,6 +460,7 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct) #define OPC_VPTERNLOGQ (0x25 | P_EXT3A | P_DATA16 | P_VEXW | P_EVEX) #define OPC_VZEROUPPER (0x77 | P_EXT) #define OPC_XCHG_ax_r32 (0x90) +#define OPC_XCHG_EvGv (0x87) #define OPC_GRP3_Eb (0xf6) #define OPC_GRP3_Ev (0xf7) @@ -1078,6 +1079,13 @@ static void tcg_out_movi(TCGContext *s, TCGType type, } } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + int rexw = type == TCG_TYPE_I32 ? 0 : P_REXW; + tcg_out_modrm(s, OPC_XCHG_EvGv + rexw, r1, r2); + return true; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index f51c4ce81b..21c2fc9e98 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -419,6 +419,11 @@ static void tcg_out_addi(TCGContext *s, TCGType type, TCGReg rd, } } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/mips/tcg-target.c.inc b/tcg/mips/tcg-target.c.inc index b0f9fbc44c..346c614354 100644 --- a/tcg/mips/tcg-target.c.inc +++ b/tcg/mips/tcg-target.c.inc @@ -595,6 +595,11 @@ static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_ext32s(s, rd, rs); } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc index b1d9c0bbe4..77abb7d20c 100644 --- a/tcg/ppc/tcg-target.c.inc +++ b/tcg/ppc/tcg-target.c.inc @@ -1154,6 +1154,11 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, } } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 0d92135bf6..328cbc0ad6 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -561,6 +561,11 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, tcg_out_opc_imm(s, OPC_LD, rd, rd, 0); } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/s390x/tcg-target.c.inc b/tcg/s390x/tcg-target.c.inc index 0578fce4d7..b399798664 100644 --- a/tcg/s390x/tcg-target.c.inc +++ b/tcg/s390x/tcg-target.c.inc @@ -1076,6 +1076,11 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val, return false; } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc index 869d9a0521..4f477d539c 100644 --- a/tcg/sparc64/tcg-target.c.inc +++ b/tcg/sparc64/tcg-target.c.inc @@ -542,6 +542,11 @@ static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_mov(s, TCG_TYPE_I32, rd, rs); } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { diff --git a/tcg/tcg.c b/tcg/tcg.c index 328e018a80..fde5ccc57c 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -115,6 +115,8 @@ static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg ret, TCGReg arg); static void tcg_out_addi_ptr(TCGContext *s, TCGReg, TCGReg, tcg_target_long); +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) + __attribute__((unused)); static void tcg_out_exit_tb(TCGContext *s, uintptr_t arg); static void tcg_out_goto_tb(TCGContext *s, int which); static void tcg_out_op(TCGContext *s, TCGOpcode opc, diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 68531e35ec..4cf03a579c 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -645,6 +645,11 @@ static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs) tcg_out_mov(s, TCG_TYPE_I32, rd, rs); } +static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2) +{ + return false; +} + static void tcg_out_addi_ptr(TCGContext *s, TCGReg rd, TCGReg rs, tcg_target_long imm) { From 4745b156b8412ef12af32bd474fee70c25940950 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 6 Apr 2023 11:38:56 -0700 Subject: [PATCH 14/15] tcg: Clear TCGLabelQemuLdst on allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/tcg-ldst.c.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/tcg/tcg-ldst.c.inc b/tcg/tcg-ldst.c.inc index 6c6848d034..403cbb0f06 100644 --- a/tcg/tcg-ldst.c.inc +++ b/tcg/tcg-ldst.c.inc @@ -72,6 +72,7 @@ static inline TCGLabelQemuLdst *new_ldst_label(TCGContext *s) { TCGLabelQemuLdst *l = tcg_malloc(sizeof(*l)); + memset(l, 0, sizeof(*l)); QSIMPLEQ_INSERT_TAIL(&s->ldst_labels, l, next); return l; From 3ea9be33400f14305565a9a094cb6031c07183d5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 5 Apr 2023 18:43:47 -0700 Subject: [PATCH 15/15] tcg/riscv: Conditionalize tcg_out_exts_i32_i64 Since TCG_TYPE_I32 values are kept sign-extended in registers, via "w" instructions, we don't need to extend if the register matches. This is already relied upon by comparisons. Reviewed-by: Daniel Henrique Barboza Signed-off-by: Richard Henderson --- tcg/riscv/tcg-target.c.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index 328cbc0ad6..266fe1433d 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -609,7 +609,9 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg) static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg) { - tcg_out_ext32s(s, ret, arg); + if (ret != arg) { + tcg_out_ext32s(s, ret, arg); + } } static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg ret, TCGReg arg)