diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2020-03-31 01:02:08 -0700 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-01-13 08:39:08 -1000 |
commit | 4e18617555955503628a004ed97e1fc2fa7818b9 (patch) | |
tree | 7999a6e36f174ff0337729c15158fe2edda83c0c /tcg/tcg.c | |
parent | 0a6a8bc8ebfe5ae2a3f18ef48b92a74bc2df2f96 (diff) | |
download | qemu-4e18617555955503628a004ed97e1fc2fa7818b9.zip qemu-4e18617555955503628a004ed97e1fc2fa7818b9.tar.gz qemu-4e18617555955503628a004ed97e1fc2fa7818b9.tar.bz2 |
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.c | 31 |
1 files changed, 26 insertions, 5 deletions
@@ -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; |