aboutsummaryrefslogtreecommitdiff
path: root/target/sparc/translate.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-11-03 10:38:21 -0700
committerRichard Henderson <richard.henderson@linaro.org>2024-02-03 16:46:10 +1000
commit54c3e9534f81a733806ac823185918dfe88687a5 (patch)
treea3bfa998a688cdeae7f66e5aec13061e261ebcf8 /target/sparc/translate.c
parent98271007379bae8ca4300ae5d8cdc37ec662ee73 (diff)
target/sparc: Use tcg_gen_qemu_{ld, st}_i128 for ASI_M_BFILL
Align the operation to the 32-byte cacheline. Use 2 i128 instead of 4 i64. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20231103173841.33651-3-richard.henderson@linaro.org>
Diffstat (limited to 'target/sparc/translate.c')
-rw-r--r--target/sparc/translate.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index 1082aabc14..3a59262c9a 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -2172,23 +2172,22 @@ static void gen_stda_asi(DisasContext *dc, DisasASI *da, TCGv addr, int rd)
case GET_ASI_BFILL:
assert(TARGET_LONG_BITS == 32);
- /* Store 32 bytes of T64 to ADDR. */
- /* ??? The original qemu code suggests 8-byte alignment, dropping
- the low bits, but the only place I can see this used is in the
- Linux kernel with 32 byte alignment, which would make more sense
- as a cacheline-style operation. */
+ /*
+ * Store 32 bytes of [rd:rd+1] to ADDR.
+ * See comments for GET_ASI_COPY above.
+ */
{
- TCGv_i64 t64 = tcg_temp_new_i64();
- TCGv d_addr = tcg_temp_new();
- TCGv eight = tcg_constant_tl(8);
- int i;
-
- tcg_gen_concat_tl_i64(t64, lo, hi);
- tcg_gen_andi_tl(d_addr, addr, -8);
- for (i = 0; i < 32; i += 8) {
- tcg_gen_qemu_st_i64(t64, d_addr, da->mem_idx, da->memop);
- tcg_gen_add_tl(d_addr, d_addr, eight);
- }
+ MemOp mop = MO_TE | MO_128 | MO_ATOM_IFALIGN_PAIR;
+ TCGv_i64 t8 = tcg_temp_new_i64();
+ TCGv_i128 t16 = tcg_temp_new_i128();
+ TCGv daddr = tcg_temp_new();
+
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_concat_i64_i128(t16, t8, t8);
+ tcg_gen_andi_tl(daddr, addr, -32);
+ tcg_gen_qemu_st_i128(t16, daddr, da->mem_idx, mop);
+ tcg_gen_addi_tl(daddr, daddr, 16);
+ tcg_gen_qemu_st_i128(t16, daddr, da->mem_idx, mop);
}
break;