tcg: Use tcg_out_dupi_vec from temp_load

Having dupi pass though movi is confusing and arguably wrong.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2020-03-31 05:43:23 -07:00
parent 45240eed4f
commit 0a6a8bc8eb
4 changed files with 47 additions and 35 deletions

View File

@ -1011,13 +1011,6 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
case TCG_TYPE_I64:
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

@ -975,30 +975,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;
@ -1027,6 +1029,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

@ -987,12 +987,6 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
tcg_out_movi_int(s, type, ret, arg, false);
break;
case TCG_TYPE_V64:
case TCG_TYPE_V128:
tcg_debug_assert(ret >= TCG_REG_V0);
tcg_out_dupi_vec(s, type, ret, arg);
break;
default:
g_assert_not_reached();
}

View File

@ -3387,7 +3387,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: