[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 06/11] target/ppc: introduce gen_addr_swizzle_le() function
From: |
Mark Cave-Ayland |
Subject: |
[RFC PATCH 06/11] target/ppc: introduce gen_addr_swizzle_le() function |
Date: |
Thu, 12 Dec 2024 15:14:07 +0000 |
This function is used to swizzle the address lines to implement little endian
accesses as used by older CPUs. Add the address line swizzle to the gen_ld_tl()
and gen_st_tl() functions.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
target/ppc/translate.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 1211435039..ddc0f85fb7 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -2561,6 +2561,24 @@ static TCGv do_ea_calc(DisasContext *ctx, int ra, TCGv
displ)
return ea;
}
+/*
+ * Swizzle the address lines for little endian accesses as used by older
+ * CPUs. The bottom 3 address lines are exlusive-ORed by a constant to
+ * generate the correct address for a little endian access. For more
+ * information see https://wiki.preterhuman.net/images/f/fc/Endian.pdf
+ */
+static inline void gen_addr_swizzle_le(TCGv ret, TCGv addr, MemOp op)
+{
+ MemOp size = op & MO_SIZE;
+ TCGv aoff = tcg_temp_new();
+ static int c_swizzle[MO_SIZE] = { 0x7, 0x6, 0x4, 0x0 };
+
+ tcg_gen_andi_tl(aoff, addr, (1 << size) - 1);
+ tcg_gen_andi_tl(ret, addr, ~((1 << size) - 1));
+ tcg_gen_xori_tl(ret, ret, c_swizzle[size]);
+ tcg_gen_sub_tl(ret, ret, aoff);
+}
+
#if defined(TARGET_PPC64)
/* EA <- (ra == 0) ? 0 : GPR[ra] */
static TCGv do_ea_calc_ra(DisasContext *ctx, int ra)
@@ -2586,6 +2604,10 @@ static void gen_ld_tl(DisasContext *ctx, TCGv val, TCGv
addr, TCGArg idx,
{
if (!need_addrswizzle_le(ctx)) {
tcg_gen_qemu_ld_tl(val, addr, idx, memop);
+ } else {
+ TCGv taddr = tcg_temp_new();
+ gen_addr_swizzle_le(taddr, addr, memop);
+ tcg_gen_qemu_ld_tl(val, taddr, idx, memop);
}
}
@@ -2629,6 +2651,10 @@ static void gen_st_tl(DisasContext *ctx, TCGv val, TCGv
addr, TCGArg idx,
{
if (!need_addrswizzle_le(ctx)) {
tcg_gen_qemu_st_tl(val, addr, idx, memop);
+ } else {
+ TCGv taddr = tcg_temp_new();
+ gen_addr_swizzle_le(taddr, addr, memop);
+ tcg_gen_qemu_st_tl(val, taddr, idx, memop);
}
}
--
2.39.5
- [RFC PATCH 00/11] target/ppc: implement legacy address-swizzling MSR_LE support, Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 01/11] target/ppc: introduce gen_ld_tl() function, Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 03/11] target/ppc: introduce gen_st_tl() function, Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 04/11] target/ppc: replace tcg_gen_qemu_st_tl() with gen_st_tl(), Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 06/11] target/ppc: introduce gen_addr_swizzle_le() function,
Mark Cave-Ayland <=
- [RFC PATCH 07/11] target/ppc: implement address swizzle for instruction translation, Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 05/11] target/ppc: introduce need_addrswizzle_le() function, Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 08/11] target/ppc: implement address swizzle for gen_ld_atomic(), Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 11/11] target/ppc: update DisasContext default_tcg_memop_mask value, Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 09/11] target/ppc: implement address swizzle for gen_st_atomic(), Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 10/11] target/ppc: implement address swizzle for gen_conditional_store(), Mark Cave-Ayland, 2024/12/12
- [RFC PATCH 02/11] target/ppc: replace tcg_gen_qemu_ld_tl() with gen_ld_tl(), Mark Cave-Ayland, 2024/12/12