tcg: Remove INDEX_op_dup2_vec

This opcode was exclusively for 32-bit hosts.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2026-01-07 12:40:43 +11:00
parent 2f4bf8148f
commit 6e7b13936d
4 changed files with 2 additions and 125 deletions

View File

@@ -130,7 +130,6 @@ DEF(qemu_st2, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_INT
DEF(mov_vec, 1, 1, 0, TCG_OPF_VECTOR | TCG_OPF_NOT_PRESENT)
DEF(dup_vec, 1, 1, 0, TCG_OPF_VECTOR)
DEF(dup2_vec, 1, 2, 0, TCG_OPF_VECTOR)
DEF(ld_vec, 1, 1, 1, TCG_OPF_VECTOR)
DEF(st_vec, 0, 2, 1, TCG_OPF_VECTOR)

View File

@@ -1716,21 +1716,6 @@ static bool fold_dup(OptContext *ctx, TCGOp *op)
return finish_folding(ctx, op);
}
static bool fold_dup2(OptContext *ctx, TCGOp *op)
{
if (arg_is_const(op->args[1]) && arg_is_const(op->args[2])) {
uint64_t t = deposit64(arg_const_val(op->args[1]), 32, 32,
arg_const_val(op->args[2]));
return tcg_opt_gen_movi(ctx, op, op->args[0], t);
}
if (args_are_copies(op->args[1], op->args[2])) {
op->opc = INDEX_op_dup_vec;
TCGOP_VECE(op) = MO_32;
}
return finish_folding(ctx, op);
}
static bool fold_eqv(OptContext *ctx, TCGOp *op)
{
uint64_t z_mask, o_mask, s_mask;
@@ -2887,9 +2872,6 @@ void tcg_optimize(TCGContext *s)
case INDEX_op_dup_vec:
done = fold_dup(&ctx, op);
break;
case INDEX_op_dup2_vec:
done = fold_dup2(&ctx, op);
break;
case INDEX_op_eqv:
case INDEX_op_eqv_vec:
done = fold_eqv(&ctx, op);

View File

@@ -75,7 +75,6 @@ bool tcg_can_emit_vecop_list(const TCGOpcode *list,
case INDEX_op_xor_vec:
case INDEX_op_mov_vec:
case INDEX_op_dup_vec:
case INDEX_op_dup2_vec:
case INDEX_op_ld_vec:
case INDEX_op_st_vec:
case INDEX_op_bitsel_vec:
@@ -228,20 +227,11 @@ void tcg_gen_dupi_vec(unsigned vece, TCGv_vec r, uint64_t a)
void tcg_gen_dup_i64_vec(unsigned vece, TCGv_vec r, TCGv_i64 a)
{
TCGArg ri = tcgv_vec_arg(r);
TCGArg ai = tcgv_i64_arg(a);
TCGTemp *rt = arg_temp(ri);
TCGType type = rt->base_type;
if (TCG_TARGET_REG_BITS == 64) {
TCGArg ai = tcgv_i64_arg(a);
vec_gen_2(INDEX_op_dup_vec, type, vece, ri, ai);
} else if (vece == MO_64) {
TCGArg al = tcgv_i32_arg(TCGV_LOW(a));
TCGArg ah = tcgv_i32_arg(TCGV_HIGH(a));
vec_gen_3(INDEX_op_dup2_vec, type, MO_64, ri, al, ah);
} else {
TCGArg ai = tcgv_i32_arg(TCGV_LOW(a));
vec_gen_2(INDEX_op_dup_vec, type, vece, ri, ai);
}
vec_gen_2(INDEX_op_dup_vec, type, vece, ri, ai);
}
void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec r, TCGv_i32 a)

View File

@@ -2493,8 +2493,6 @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
case INDEX_op_xor_vec:
case INDEX_op_cmp_vec:
return has_type;
case INDEX_op_dup2_vec:
return has_type && TCG_TARGET_REG_BITS == 32;
case INDEX_op_not_vec:
return has_type && TCG_TARGET_HAS_not_vec;
case INDEX_op_neg_vec:
@@ -5888,93 +5886,6 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
}
}
static bool tcg_reg_alloc_dup2(TCGContext *s, const TCGOp *op)
{
const TCGLifeData arg_life = op->life;
TCGTemp *ots, *itsl, *itsh;
TCGType vtype = TCGOP_TYPE(op);
/* This opcode is only valid for 32-bit hosts, for 64-bit elements. */
tcg_debug_assert(TCG_TARGET_REG_BITS == 32);
tcg_debug_assert(TCGOP_VECE(op) == MO_64);
ots = arg_temp(op->args[0]);
itsl = arg_temp(op->args[1]);
itsh = arg_temp(op->args[2]);
/* ENV should not be modified. */
tcg_debug_assert(!temp_readonly(ots));
/* Allocate the output register now. */
if (ots->val_type != TEMP_VAL_REG) {
TCGRegSet allocated_regs = s->reserved_regs;
TCGRegSet dup_out_regs = opcode_args_ct(op)[0].regs;
TCGReg oreg;
/* Make sure to not spill the input registers. */
if (!IS_DEAD_ARG(1) && itsl->val_type == TEMP_VAL_REG) {
tcg_regset_set_reg(allocated_regs, itsl->reg);
}
if (!IS_DEAD_ARG(2) && itsh->val_type == TEMP_VAL_REG) {
tcg_regset_set_reg(allocated_regs, itsh->reg);
}
oreg = tcg_reg_alloc(s, dup_out_regs, allocated_regs,
output_pref(op, 0), ots->indirect_base);
set_temp_val_reg(s, ots, oreg);
}
/* Promote dup2 of immediates to dupi_vec. */
if (itsl->val_type == TEMP_VAL_CONST && itsh->val_type == TEMP_VAL_CONST) {
uint64_t val = deposit64(itsl->val, 32, 32, itsh->val);
MemOp vece = MO_64;
if (val == dup_const(MO_8, val)) {
vece = MO_8;
} else if (val == dup_const(MO_16, val)) {
vece = MO_16;
} else if (val == dup_const(MO_32, val)) {
vece = MO_32;
}
tcg_out_dupi_vec(s, vtype, vece, ots->reg, val);
goto done;
}
/* If the two inputs form one 64-bit value, try dupm_vec. */
if (itsl->temp_subindex == HOST_BIG_ENDIAN &&
itsh->temp_subindex == !HOST_BIG_ENDIAN &&
itsl == itsh + (HOST_BIG_ENDIAN ? 1 : -1)) {
TCGTemp *its = itsl - HOST_BIG_ENDIAN;
temp_sync(s, its + 0, s->reserved_regs, 0, 0);
temp_sync(s, its + 1, s->reserved_regs, 0, 0);
if (tcg_out_dupm_vec(s, vtype, MO_64, ots->reg,
its->mem_base->reg, its->mem_offset)) {
goto done;
}
}
/* Fall back to generic expansion. */
return false;
done:
ots->mem_coherent = 0;
if (IS_DEAD_ARG(1)) {
temp_dead(s, itsl);
}
if (IS_DEAD_ARG(2)) {
temp_dead(s, itsh);
}
if (NEED_SYNC_ARG(0)) {
temp_sync(s, ots, s->reserved_regs, 0, IS_DEAD_ARG(0));
} else if (IS_DEAD_ARG(0)) {
temp_dead(s, ots);
}
return true;
}
static void load_arg_reg(TCGContext *s, TCGReg reg, TCGTemp *ts,
TCGRegSet allocated_regs)
{
@@ -6939,11 +6850,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
case INDEX_op_mb:
tcg_out_mb(s, op->args[0]);
break;
case INDEX_op_dup2_vec:
if (tcg_reg_alloc_dup2(s, op)) {
break;
}
/* fall through */
default:
do_default:
/* Sanity check that we've not introduced any unhandled opcodes. */