target/arm: Avoid writing to constant TCGv in trans_CSEL()
In commit0b188ea05a
we changed the implementation of trans_CSEL() to use tcg_constant_i32(). However, this change was incorrect, because the implementation of the function sets up the TCGv_i32 rn and rm to be either zero or else a TCG temp created in load_reg(), and these TCG temps are then in both cases written to by the emitted TCG ops. The result is that we hit a TCG assertion: qemu-system-arm: ../../tcg/tcg.c:4455: tcg_reg_alloc_mov: Assertion `!temp_readonly(ots)' failed. (or on a non-debug build, just produce a garbage result) Adjust the code so that rn and rm are always writeable temporaries whether the instruction is using the special case "0" or a normal register as input. Cc: qemu-stable@nongnu.org Fixes:0b188ea05a
("target/arm: Use tcg_constant in trans_CSEL") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230727103906.2641264-1-peter.maydell@linaro.org
This commit is contained in:
parent
548b8edc6d
commit
2b0d656ab6
|
@ -8799,7 +8799,7 @@ static bool trans_IT(DisasContext *s, arg_IT *a)
|
||||||
/* v8.1M CSEL/CSINC/CSNEG/CSINV */
|
/* v8.1M CSEL/CSINC/CSNEG/CSINV */
|
||||||
static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
|
static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
|
||||||
{
|
{
|
||||||
TCGv_i32 rn, rm, zero;
|
TCGv_i32 rn, rm;
|
||||||
DisasCompare c;
|
DisasCompare c;
|
||||||
|
|
||||||
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
|
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
|
||||||
|
@ -8817,16 +8817,17 @@ static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
|
/* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
|
||||||
zero = tcg_constant_i32(0);
|
rn = tcg_temp_new_i32();
|
||||||
|
rm = tcg_temp_new_i32();
|
||||||
if (a->rn == 15) {
|
if (a->rn == 15) {
|
||||||
rn = zero;
|
tcg_gen_movi_i32(rn, 0);
|
||||||
} else {
|
} else {
|
||||||
rn = load_reg(s, a->rn);
|
load_reg_var(s, rn, a->rn);
|
||||||
}
|
}
|
||||||
if (a->rm == 15) {
|
if (a->rm == 15) {
|
||||||
rm = zero;
|
tcg_gen_movi_i32(rm, 0);
|
||||||
} else {
|
} else {
|
||||||
rm = load_reg(s, a->rm);
|
load_reg_var(s, rm, a->rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (a->op) {
|
switch (a->op) {
|
||||||
|
@ -8846,7 +8847,7 @@ static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
|
||||||
}
|
}
|
||||||
|
|
||||||
arm_test_cc(&c, a->fcond);
|
arm_test_cc(&c, a->fcond);
|
||||||
tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
|
tcg_gen_movcond_i32(c.cond, rn, c.value, tcg_constant_i32(0), rn, rm);
|
||||||
|
|
||||||
store_reg(s, a->rd, rn);
|
store_reg(s, a->rd, rn);
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue