summaryrefslogtreecommitdiff
path: root/tcg/tcg.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-03-31 01:02:08 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-01-13 08:39:08 -1000
commit4e18617555955503628a004ed97e1fc2fa7818b9 (patch)
tree7999a6e36f174ff0337729c15158fe2edda83c0c /tcg/tcg.c
parent0a6a8bc8ebfe5ae2a3f18ef48b92a74bc2df2f96 (diff)
downloadqemu-4e18617555955503628a004ed97e1fc2fa7818b9.zip
tcg: Increase tcg_out_dupi_vec immediate to int64_t
While we don't store more than tcg_target_long in TCGTemp, we shouldn't be limited to that for code generation. We will be able to use this for INDEX_op_dup2_vec with 2 constants. Also pass along the minimal vece that may be said to apply to the constant. This allows some simplification in the various backends. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r--tcg/tcg.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index ded3c928e3..c73128208c 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -117,8 +117,8 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
TCGReg dst, TCGReg src);
static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
TCGReg dst, TCGReg base, intptr_t offset);
-static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
- TCGReg dst, tcg_target_long arg);
+static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
+ TCGReg dst, int64_t arg);
static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc, unsigned vecl,
unsigned vece, const TCGArg *args,
const int *const_args);
@@ -133,8 +133,8 @@ static inline bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
{
g_assert_not_reached();
}
-static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type,
- TCGReg dst, tcg_target_long arg)
+static inline void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
+ TCGReg dst, int64_t arg)
{
g_assert_not_reached();
}
@@ -3390,7 +3390,28 @@ static void temp_load(TCGContext *s, TCGTemp *ts, TCGRegSet desired_regs,
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);
+ uint64_t val = ts->val;
+ MemOp vece = MO_64;
+
+ /*
+ * Find the minimal vector element that matches the constant.
+ * The targets will, in general, have to do this search anyway,
+ * do this generically.
+ */
+ if (TCG_TARGET_REG_BITS == 32) {
+ val = dup_const(MO_32, val);
+ vece = MO_32;
+ }
+ if (val == dup_const(MO_8, val)) {
+ vece = MO_8;
+ } else if (val == dup_const(MO_16, val)) {
+ vece = MO_16;
+ } else if (TCG_TARGET_REG_BITS == 64 &&
+ val == dup_const(MO_32, val)) {
+ vece = MO_32;
+ }
+
+ tcg_out_dupi_vec(s, ts->type, vece, reg, ts->val);
}
ts->mem_coherent = 0;
break;