aboutsummaryrefslogtreecommitdiff
path: root/target/arm
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-02-25 12:29:41 -1000
committerRichard Henderson <richard.henderson@linaro.org>2023-03-13 07:03:39 -0700
commit56649fd949a85973c23ae17285de7ce5ffe18656 (patch)
treef819e5535d459027025014216552022d592c8146 /target/arm
parent1b7bc9b5c8bf374dd37e49cc258e4ab3447b7148 (diff)
downloadqemu-56649fd949a85973c23ae17285de7ce5ffe18656.zip
qemu-56649fd949a85973c23ae17285de7ce5ffe18656.tar.gz
qemu-56649fd949a85973c23ae17285de7ce5ffe18656.tar.bz2
target/arm: Avoid tcg_const_ptr in handle_rev
Here it is not trivial to notice first initialization, so explicitly zero the temps. Use an array for the output, rather than separate tcg_rd/tcg_rd_hi variables. Fixes a bug by adding a missing clear_vec_high. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/arm')
-rw-r--r--target/arm/tcg/translate-a64.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 082a8b8..dff391b 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -12003,22 +12003,26 @@ static void handle_rev(DisasContext *s, int opcode, bool u,
int esize = 8 << size;
int elements = dsize / esize;
TCGv_i64 tcg_rn = tcg_temp_new_i64();
- TCGv_i64 tcg_rd = tcg_const_i64(0);
- TCGv_i64 tcg_rd_hi = tcg_const_i64(0);
+ TCGv_i64 tcg_rd[2];
+
+ for (i = 0; i < 2; i++) {
+ tcg_rd[i] = tcg_temp_new_i64();
+ tcg_gen_movi_i64(tcg_rd[i], 0);
+ }
for (i = 0; i < elements; i++) {
int e_rev = (i & 0xf) ^ revmask;
- int off = e_rev * esize;
+ int w = (e_rev * esize) / 64;
+ int o = (e_rev * esize) % 64;
+
read_vec_element(s, tcg_rn, rn, i, size);
- if (off >= 64) {
- tcg_gen_deposit_i64(tcg_rd_hi, tcg_rd_hi,
- tcg_rn, off - 64, esize);
- } else {
- tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, off, esize);
- }
+ tcg_gen_deposit_i64(tcg_rd[w], tcg_rd[w], tcg_rn, o, esize);
+ }
+
+ for (i = 0; i < 2; i++) {
+ write_vec_element(s, tcg_rd[i], rd, i, MO_64);
}
- write_vec_element(s, tcg_rd, rd, 0, MO_64);
- write_vec_element(s, tcg_rd_hi, rd, 1, MO_64);
+ clear_vec_high(s, true, rd);
}
}