tcg/riscv: Fix TCG_REG_TMP0 clobber in tcg_gen_dup{m,i}
TCG_REG_TMP0 may be used by set_vtype* to load the vtype
parameter, so delay any other use of TCG_REG_TMP0 until
the correct vtype has been installed.
Cc: qemu-stable@nongnu.org
Fixes: d4be6ee111 ("tcg/riscv: Implement vector mov/dup{m/i}")
Reported-by: Zhijin Zeng <zengzhijin@linux.spacemit.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit af6db3b71310ea63a018d517ba7d79e4e014db62)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
parent
a53ba65fff
commit
f34c0eb054
1 changed files with 19 additions and 14 deletions
|
|
@ -1074,7 +1074,7 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
|
static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
|
||||||
TCGReg dst, TCGReg src)
|
TCGReg dst, TCGReg src)
|
||||||
{
|
{
|
||||||
set_vtype_len_sew(s, type, vece);
|
set_vtype_len_sew(s, type, vece);
|
||||||
tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, src);
|
tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, src);
|
||||||
|
|
@ -1082,29 +1082,34 @@ static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
|
static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
|
||||||
TCGReg dst, TCGReg base, intptr_t offset)
|
TCGReg dst, TCGReg base, intptr_t offset)
|
||||||
{
|
{
|
||||||
|
/* Note set_vtype* may clobber TMP0, so do that first. */
|
||||||
|
set_vtype_len_sew(s, type, vece);
|
||||||
tcg_out_ld(s, TCG_TYPE_REG, TCG_REG_TMP0, base, offset);
|
tcg_out_ld(s, TCG_TYPE_REG, TCG_REG_TMP0, base, offset);
|
||||||
return tcg_out_dup_vec(s, type, vece, dst, TCG_REG_TMP0);
|
tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, TCG_REG_TMP0);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
|
static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
|
||||||
TCGReg dst, int64_t arg)
|
TCGReg dst, int64_t arg)
|
||||||
{
|
{
|
||||||
/* Arg is replicated by VECE; extract the highest element. */
|
/* Arg is replicated by VECE; extract the highest element. */
|
||||||
arg >>= (-8 << vece) & 63;
|
arg >>= (-8 << vece) & 63;
|
||||||
|
|
||||||
if (arg >= -16 && arg < 16) {
|
/* Note set_vtype* may clobber TMP0, so do that first. */
|
||||||
if (arg == 0 || arg == -1) {
|
if (arg == 0 || arg == -1) {
|
||||||
set_vtype_len(s, type);
|
set_vtype_len(s, type);
|
||||||
} else {
|
} else {
|
||||||
set_vtype_len_sew(s, type, vece);
|
set_vtype_len_sew(s, type, vece);
|
||||||
}
|
}
|
||||||
tcg_out_opc_vi(s, OPC_VMV_V_I, dst, 0, arg);
|
|
||||||
return;
|
if (arg >= -16 && arg < 16) {
|
||||||
|
tcg_out_opc_vi(s, OPC_VMV_V_I, dst, 0, arg);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, arg);
|
||||||
|
tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, TCG_REG_TMP0);
|
||||||
}
|
}
|
||||||
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, arg);
|
|
||||||
tcg_out_dup_vec(s, type, vece, dst, TCG_REG_TMP0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_br(TCGContext *s, TCGLabel *l)
|
static void tcg_out_br(TCGContext *s, TCGLabel *l)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue