tcg: Use tcg_out_dupi_vec from temp_load

Having dupi pass though movi is confusing and arguably wrong.

Backports 0a6a8bc8ebfe5ae2a3f18ef48b92a74bc2df2f96
This commit is contained in:
Richard Henderson 2021-03-03 20:22:50 -05:00 committed by Lioncash
parent 68f645dd4f
commit c5c19529c5
3 changed files with 47 additions and 28 deletions

View file

@ -1004,12 +1004,6 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
tcg_debug_assert(rd < 32);
break;
case TCG_TYPE_V64:
case TCG_TYPE_V128:
tcg_debug_assert(rd >= 32);
tcg_out_dupi_vec(s, type, rd, value);
return;
default:
g_assert_not_reached();
}

View file

@ -981,30 +981,32 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
}
}
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
static void tcg_out_movi_vec(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
if (arg == 0) {
tcg_out_vex_modrm(s, OPC_PXOR, ret, ret, ret);
return;
}
if (arg == -1) {
tcg_out_vex_modrm(s, OPC_PCMPEQB, ret, ret, ret);
return;
}
int rexw = (type == TCG_TYPE_I32 ? 0 : P_REXW);
tcg_out_vex_modrm_pool(s, OPC_MOVD_VyEy + rexw, ret);
if (TCG_TARGET_REG_BITS == 64) {
new_pool_label(s, arg, R_386_PC32, s->code_ptr - 4, -4);
} else {
new_pool_label(s, arg, R_386_32, s->code_ptr - 4, 0);
}
}
static void tcg_out_movi_int(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
tcg_target_long diff;
switch (type) {
case TCG_TYPE_I32:
#if TCG_TARGET_REG_BITS == 64
case TCG_TYPE_I64:
#endif
if (ret < 16) {
break;
}
/* fallthru */
case TCG_TYPE_V64:
case TCG_TYPE_V128:
case TCG_TYPE_V256:
tcg_debug_assert(ret >= 16);
tcg_out_dupi_vec(s, type, ret, arg);
return;
default:
g_assert_not_reached();
}
if (arg == 0) {
tgen_arithr(s, ARITH_XOR, ret, ret);
return;
@ -1033,6 +1035,25 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
tcg_out64(s, arg);
}
static void tcg_out_movi(TCGContext *s, TCGType type,
TCGReg ret, tcg_target_long arg)
{
switch (type) {
case TCG_TYPE_I32:
#if TCG_TARGET_REG_BITS == 64
case TCG_TYPE_I64:
#endif
if (ret < 16) {
tcg_out_movi_int(s, type, ret, arg);
} else {
tcg_out_movi_vec(s, type, ret, arg);
}
break;
default:
g_assert_not_reached();
}
}
static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
{
if (val == (int8_t)val) {

View file

@ -2738,7 +2738,11 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
case TEMP_VAL_CONST:
reg = tcg_reg_alloc(s, desired_regs, allocated_regs,
preferred_regs, ts->indirect_base);
tcg_out_movi(s, ts->type, reg, ts->val);
if (ts->type <= TCG_TYPE_I64) {
tcg_out_movi(s, ts->type, reg, ts->val);
} else {
tcg_out_dupi_vec(s, ts->type, reg, ts->val);
}
ts->mem_coherent = 0;
break;
case TEMP_VAL_MEM: