aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorBastian Koppelmann <kbastian@mail.uni-paderborn.de>2023-02-02 13:04:29 +0100
committerBastian Koppelmann <kbastian@mail.uni-paderborn.de>2023-02-08 09:59:15 +0100
commita4d5d153c4c53076cea70c1609f3d7427322586b (patch)
tree03e81b708881b7da2ffc46d24f3e358532dc59c2 /target
parent70447df9365c9401643e4260436c64b35aab003e (diff)
downloadqemu-a4d5d153c4c53076cea70c1609f3d7427322586b.zip
qemu-a4d5d153c4c53076cea70c1609f3d7427322586b.tar.gz
qemu-a4d5d153c4c53076cea70c1609f3d7427322586b.tar.bz2
target/tricore: Fix OPC2_32_RRRR_DEXTR
if cpu_gpr_d[r3] == 0 then we were shifting the lower register to the right by 32 which is undefined behaviour. In this case the TriCore would do nothing an just return the higher register cpu_reg_d[r1]. We fixed that by detecting whether cpu_gpr_d[r3] was zero and cleared the lower register. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> Message-Id: <20230202120432.1268-8-kbastian@mail.uni-paderborn.de> Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Diffstat (limited to 'target')
-rw-r--r--target/tricore/translate.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/target/tricore/translate.c b/target/tricore/translate.c
index 3b4ec53..8bf78b4 100644
--- a/target/tricore/translate.c
+++ b/target/tricore/translate.c
@@ -8245,10 +8245,19 @@ static void decode_rrrr_extract_insert(DisasContext *ctx)
if (r1 == r2) {
tcg_gen_rotl_tl(cpu_gpr_d[r4], cpu_gpr_d[r1], tmp_pos);
} else {
+ TCGv msw = tcg_temp_new();
+ TCGv zero = tcg_constant_tl(0);
tcg_gen_shl_tl(tmp_width, cpu_gpr_d[r1], tmp_pos);
- tcg_gen_subfi_tl(tmp_pos, 32, tmp_pos);
- tcg_gen_shr_tl(tmp_pos, cpu_gpr_d[r2], tmp_pos);
- tcg_gen_or_tl(cpu_gpr_d[r4], tmp_width, tmp_pos);
+ tcg_gen_subfi_tl(msw, 32, tmp_pos);
+ tcg_gen_shr_tl(msw, cpu_gpr_d[r2], msw);
+ /*
+ * if pos == 0, then we do cpu_gpr_d[r2] << 32, which is undefined
+ * behaviour. So check that case here and set the low bits to zero
+ * which effectivly returns cpu_gpr_d[r1]
+ */
+ tcg_gen_movcond_tl(TCG_COND_EQ, msw, tmp_pos, zero, zero, msw);
+ tcg_gen_or_tl(cpu_gpr_d[r4], tmp_width, msw);
+ tcg_temp_free(msw);
}
break;
case OPC2_32_RRRR_EXTR: