Use the MemOp argument to hold both the access size and
its endianness.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
system/memory_ldst.c.inc | 86 ++++++++++++---------------------
system/memory_ldst_endian.c.inc | 26 +++++-----
2 files changed, 44 insertions(+), 68 deletions(-)
diff --git a/system/memory_ldst.c.inc b/system/memory_ldst.c.inc
index 39b3930bf50..5c8299e0cdc 100644
--- a/system/memory_ldst.c.inc
+++ b/system/memory_ldst.c.inc
@@ -24,8 +24,7 @@ static inline
uint64_t glue(address_space_ldm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
hwaddr addr,
MemTxAttrs attrs,
- MemTxResult *result,
- enum device_endian endian)
+ MemTxResult *result)
{
const unsigned size = memop_size(mop);
uint8_t *ptr;
@@ -42,22 +41,15 @@ uint64_t glue(address_space_ldm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
release_lock |= prepare_mmio_access(mr);
/* I/O case */
- r = memory_region_dispatch_read(mr, addr1, &val,
- mop | devend_memop(endian), attrs);
+ r = memory_region_dispatch_read(mr, addr1, &val, mop, attrs);
} else {
/* RAM case */
fuzz_dma_read_cb(addr, size, mr);
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
- switch (endian) {
- case DEVICE_LITTLE_ENDIAN:
+ if ((mop & MO_BSWAP) == MO_LE) {
val = ldn_le_p(ptr, size);
- break;
- case DEVICE_BIG_ENDIAN:
+ } else {
val = ldn_be_p(ptr, size);
- break;
- default:
- val = ldn_p(ptr, size);
- break;
}
r = MEMTX_OK;
}
@@ -73,37 +65,33 @@ uint64_t glue(address_space_ldm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
/* warning: addr must be aligned */
static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
- hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
- enum device_endian endian)
+ MemOp mop, hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
- return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_32, addr,
- attrs, result, endian);
+ return glue(address_space_ldm_internal, SUFFIX)(ARG1, mop | MO_32, addr,
+ attrs, result);
}
/* warning: addr must be aligned */
static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
- hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
- enum device_endian endian)
+ MemOp mop, hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
- return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_64, addr,
- attrs, result, endian);
+ return glue(address_space_ldm_internal, SUFFIX)(ARG1, mop | MO_64, addr,
+ attrs, result);
}
uint8_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_8, addr,
- attrs, result,
- DEVICE_NATIVE_ENDIAN);
+ attrs, result);
}
/* warning: addr must be aligned */
static inline uint16_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
- hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
- enum device_endian endian)
+ MemOp mop, hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
- return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_16, addr,
- attrs, result, endian);
+ return glue(address_space_ldm_internal, SUFFIX)(ARG1, mop | MO_16, addr,
+ attrs, result);
}
/* warning: addr must be aligned */
@@ -111,8 +99,7 @@ static inline
void glue(address_space_stm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
hwaddr addr, uint64_t val,
MemTxAttrs attrs,
- MemTxResult *result,
- enum device_endian endian)
+ MemTxResult *result)
{
const unsigned size = memop_size(mop);
uint8_t *ptr;
@@ -126,21 +113,14 @@ void glue(address_space_stm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
mr = TRANSLATE(addr, &addr1, &l, true, attrs);
if (l < size || !memory_access_is_direct(mr, true, attrs)) {
release_lock |= prepare_mmio_access(mr);
- r = memory_region_dispatch_write(mr, addr1, val,
- mop | devend_memop(endian), attrs);
+ r = memory_region_dispatch_write(mr, addr1, val, mop, attrs);
} else {
/* RAM case */
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
- switch (endian) {
- case DEVICE_LITTLE_ENDIAN:
+ if ((mop & MO_BSWAP) == MO_LE) {
stn_le_p(ptr, size, val);
- break;
- case DEVICE_BIG_ENDIAN:
+ } else {
stn_be_p(ptr, size, val);
- break;
- default:
- stn_p(ptr, size, val);
- break;
}
invalidate_and_set_dirty(mr, addr1, size);
r = MEMTX_OK;
@@ -156,48 +136,44 @@ void glue(address_space_stm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
/* warning: addr must be aligned */
static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
- hwaddr addr, uint32_t val, MemTxAttrs attrs,
- MemTxResult *result, enum device_endian endian)
+ MemOp mop, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
{
- glue(address_space_stm_internal, SUFFIX)(ARG1, MO_32, addr, val,
- attrs, result, endian);
+ glue(address_space_stm_internal, SUFFIX)(ARG1, mop | MO_32, addr, val,
+ attrs, result);
}
void glue(address_space_stb, SUFFIX)(ARG1_DECL, hwaddr addr, uint8_t val,
MemTxAttrs attrs, MemTxResult *result)
{
glue(address_space_stm_internal, SUFFIX)(ARG1, MO_8, addr, val,
- attrs, result,
- DEVICE_NATIVE_ENDIAN);
+ attrs, result);
}
/* warning: addr must be aligned */
static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
- hwaddr addr, uint16_t val, MemTxAttrs attrs,
- MemTxResult *result, enum device_endian endian)
+ MemOp mop, hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result)
{
- glue(address_space_stm_internal, SUFFIX)(ARG1, MO_16, addr, val,
- attrs, result, endian);
+ glue(address_space_stm_internal, SUFFIX)(ARG1, mop | MO_16, addr, val,
+ attrs, result);
}
static inline void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
- hwaddr addr, uint64_t val, MemTxAttrs attrs,
- MemTxResult *result, enum device_endian endian)
+ MemOp mop, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
{
- glue(address_space_stm_internal, SUFFIX)(ARG1, MO_64, addr, val,
- attrs, result, endian);
+ glue(address_space_stm_internal, SUFFIX)(ARG1, mop | MO_64, addr, val,
+ attrs, result);
}
#define ENDIANNESS
-#define DEVICE_ENDIANNESS DEVICE_NATIVE_ENDIAN
+#define MO_ENDIAN (target_big_endian() ? MO_BE : MO_LE)
#include "memory_ldst_endian.c.inc"
#define ENDIANNESS _le
-#define DEVICE_ENDIANNESS DEVICE_LITTLE_ENDIAN
+#define MO_ENDIAN MO_LE
#include "memory_ldst_endian.c.inc"
#define ENDIANNESS _be
-#define DEVICE_ENDIANNESS DEVICE_BIG_ENDIAN
+#define MO_ENDIAN MO_BE
#include "memory_ldst_endian.c.inc"
#undef ARG1_DECL
diff --git a/system/memory_ldst_endian.c.inc b/system/memory_ldst_endian.c.inc
index 791d041b15d..9cf36017135 100644
--- a/system/memory_ldst_endian.c.inc
+++ b/system/memory_ldst_endian.c.inc
@@ -22,43 +22,43 @@
uint16_t ADDRESS_SPACE_LD(uw)(ARG1_DECL, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
- return ADDRESS_SPACE_LD_INTERNAL(uw)(ARG1, addr, attrs, result,
- DEVICE_ENDIANNESS);
+ return ADDRESS_SPACE_LD_INTERNAL(uw)(ARG1, MO_ENDIAN,
+ addr, attrs, result);
}
uint32_t ADDRESS_SPACE_LD(l)(ARG1_DECL, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
- return ADDRESS_SPACE_LD_INTERNAL(l)(ARG1, addr, attrs, result,
- DEVICE_ENDIANNESS);
+ return ADDRESS_SPACE_LD_INTERNAL(l)(ARG1, MO_ENDIAN,
+ addr, attrs, result);
}
uint64_t ADDRESS_SPACE_LD(q)(ARG1_DECL, hwaddr addr,
MemTxAttrs attrs, MemTxResult *result)
{
- return ADDRESS_SPACE_LD_INTERNAL(q)(ARG1, addr, attrs, result,
- DEVICE_ENDIANNESS);
+ return ADDRESS_SPACE_LD_INTERNAL(q)(ARG1, MO_ENDIAN,
+ addr, attrs, result);
}
void ADDRESS_SPACE_ST(w)(ARG1_DECL, hwaddr addr, uint16_t val,
MemTxAttrs attrs, MemTxResult *result)
{
- ADDRESS_SPACE_ST_INTERNAL(w)(ARG1, addr, val, attrs, result,
- DEVICE_ENDIANNESS);
+ ADDRESS_SPACE_ST_INTERNAL(w)(ARG1, MO_ENDIAN,
+ addr, val, attrs, result);
}
void ADDRESS_SPACE_ST(l)(ARG1_DECL, hwaddr addr, uint32_t val,
MemTxAttrs attrs, MemTxResult *result)
{
- ADDRESS_SPACE_ST_INTERNAL(l)(ARG1, addr, val, attrs, result,
- DEVICE_ENDIANNESS);
+ ADDRESS_SPACE_ST_INTERNAL(l)(ARG1, MO_ENDIAN,
+ addr, val, attrs, result);
}
void ADDRESS_SPACE_ST(q)(ARG1_DECL, hwaddr addr, uint64_t val,
MemTxAttrs attrs, MemTxResult *result)
{
- ADDRESS_SPACE_ST_INTERNAL(q)(ARG1, addr, val, attrs, result,
- DEVICE_ENDIANNESS);
+ ADDRESS_SPACE_ST_INTERNAL(q)(ARG1, MO_ENDIAN,
+ addr, val, attrs, result);
}
#undef ADDRESS_SPACE_LD
@@ -67,4 +67,4 @@ void ADDRESS_SPACE_ST(q)(ARG1_DECL, hwaddr addr, uint64_t val,
#undef ADDRESS_SPACE_ST_INTERNAL
#undef ENDIANNESS
-#undef DEVICE_ENDIANNESS
+#undef MO_ENDIAN
--
2.52.0
Il mer 24 dic 2025, 16:24 Philippe Mathieu-Daudé <philmd@linaro.org> ha
scritto:
> - switch (endian) {
> - case DEVICE_LITTLE_ENDIAN:
> + if ((mop & MO_BSWAP) == MO_LE) {
> val = ldn_le_p(ptr, size);
> - break;
> - case DEVICE_BIG_ENDIAN:
> + } else {
> val = ldn_be_p(ptr, size);
> - break;
> - default:
> - val = ldn_p(ptr, size);
> - break;
> }
>
This is an example in which you could use ldn_he_p as a memcpy, followed by
the bswap if mop & MO_BSWAP. It would be closer to how MemOp bits are
defined.
Paolo
r = MEMTX_OK;
> }
> @@ -73,37 +65,33 @@ uint64_t glue(address_space_ldm_internal,
> SUFFIX)(ARG1_DECL, MemOp mop,
>
> /* warning: addr must be aligned */
> static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
> - hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
> - enum device_endian endian)
> + MemOp mop, hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
> {
> - return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_32, addr,
> - attrs, result,
> endian);
> + return glue(address_space_ldm_internal, SUFFIX)(ARG1, mop | MO_32,
> addr,
> + attrs, result);
> }
>
> /* warning: addr must be aligned */
> static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
> - hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
> - enum device_endian endian)
> + MemOp mop, hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
> {
> - return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_64, addr,
> - attrs, result,
> endian);
> + return glue(address_space_ldm_internal, SUFFIX)(ARG1, mop | MO_64,
> addr,
> + attrs, result);
> }
>
> uint8_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, hwaddr addr,
> MemTxAttrs attrs, MemTxResult
> *result)
> {
> return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_8, addr,
> - attrs, result,
> - DEVICE_NATIVE_ENDIAN);
> + attrs, result);
> }
>
> /* warning: addr must be aligned */
> static inline uint16_t glue(address_space_lduw_internal,
> SUFFIX)(ARG1_DECL,
> - hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
> - enum device_endian endian)
> + MemOp mop, hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
> {
> - return glue(address_space_ldm_internal, SUFFIX)(ARG1, MO_16, addr,
> - attrs, result,
> endian);
> + return glue(address_space_ldm_internal, SUFFIX)(ARG1, mop | MO_16,
> addr,
> + attrs, result);
> }
>
> /* warning: addr must be aligned */
> @@ -111,8 +99,7 @@ static inline
> void glue(address_space_stm_internal, SUFFIX)(ARG1_DECL, MemOp mop,
> hwaddr addr, uint64_t val,
> MemTxAttrs attrs,
> - MemTxResult *result,
> - enum device_endian endian)
> + MemTxResult *result)
> {
> const unsigned size = memop_size(mop);
> uint8_t *ptr;
> @@ -126,21 +113,14 @@ void glue(address_space_stm_internal,
> SUFFIX)(ARG1_DECL, MemOp mop,
> mr = TRANSLATE(addr, &addr1, &l, true, attrs);
> if (l < size || !memory_access_is_direct(mr, true, attrs)) {
> release_lock |= prepare_mmio_access(mr);
> - r = memory_region_dispatch_write(mr, addr1, val,
> - mop | devend_memop(endian),
> attrs);
> + r = memory_region_dispatch_write(mr, addr1, val, mop, attrs);
> } else {
> /* RAM case */
> ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
> - switch (endian) {
> - case DEVICE_LITTLE_ENDIAN:
> + if ((mop & MO_BSWAP) == MO_LE) {
> stn_le_p(ptr, size, val);
> - break;
> - case DEVICE_BIG_ENDIAN:
> + } else {
> stn_be_p(ptr, size, val);
> - break;
> - default:
> - stn_p(ptr, size, val);
> - break;
> }
> invalidate_and_set_dirty(mr, addr1, size);
> r = MEMTX_OK;
> @@ -156,48 +136,44 @@ void glue(address_space_stm_internal,
> SUFFIX)(ARG1_DECL, MemOp mop,
>
> /* warning: addr must be aligned */
> static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
> - hwaddr addr, uint32_t val, MemTxAttrs attrs,
> - MemTxResult *result, enum device_endian endian)
> + MemOp mop, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult
> *result)
> {
> - glue(address_space_stm_internal, SUFFIX)(ARG1, MO_32, addr, val,
> - attrs, result, endian);
> + glue(address_space_stm_internal, SUFFIX)(ARG1, mop | MO_32, addr, val,
> + attrs, result);
> }
>
> void glue(address_space_stb, SUFFIX)(ARG1_DECL, hwaddr addr, uint8_t val,
> MemTxAttrs attrs, MemTxResult
> *result)
> {
> glue(address_space_stm_internal, SUFFIX)(ARG1, MO_8, addr, val,
> - attrs, result,
> - DEVICE_NATIVE_ENDIAN);
> + attrs, result);
> }
>
> /* warning: addr must be aligned */
> static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
> - hwaddr addr, uint16_t val, MemTxAttrs attrs,
> - MemTxResult *result, enum device_endian endian)
> + MemOp mop, hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult
> *result)
> {
> - glue(address_space_stm_internal, SUFFIX)(ARG1, MO_16, addr, val,
> - attrs, result, endian);
> + glue(address_space_stm_internal, SUFFIX)(ARG1, mop | MO_16, addr, val,
> + attrs, result);
> }
>
> static inline void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
> - hwaddr addr, uint64_t val, MemTxAttrs attrs,
> - MemTxResult *result, enum device_endian endian)
> + MemOp mop, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult
> *result)
> {
> - glue(address_space_stm_internal, SUFFIX)(ARG1, MO_64, addr, val,
> - attrs, result, endian);
> + glue(address_space_stm_internal, SUFFIX)(ARG1, mop | MO_64, addr, val,
> + attrs, result);
> }
>
> #define ENDIANNESS
> -#define DEVICE_ENDIANNESS DEVICE_NATIVE_ENDIAN
> +#define MO_ENDIAN (target_big_endian() ? MO_BE : MO_LE)
> #include "memory_ldst_endian.c.inc"
>
> #define ENDIANNESS _le
> -#define DEVICE_ENDIANNESS DEVICE_LITTLE_ENDIAN
> +#define MO_ENDIAN MO_LE
> #include "memory_ldst_endian.c.inc"
>
> #define ENDIANNESS _be
> -#define DEVICE_ENDIANNESS DEVICE_BIG_ENDIAN
> +#define MO_ENDIAN MO_BE
> #include "memory_ldst_endian.c.inc"
>
> #undef ARG1_DECL
> diff --git a/system/memory_ldst_endian.c.inc
> b/system/memory_ldst_endian.c.inc
> index 791d041b15d..9cf36017135 100644
> --- a/system/memory_ldst_endian.c.inc
> +++ b/system/memory_ldst_endian.c.inc
> @@ -22,43 +22,43 @@
> uint16_t ADDRESS_SPACE_LD(uw)(ARG1_DECL, hwaddr addr,
> MemTxAttrs attrs, MemTxResult *result)
> {
> - return ADDRESS_SPACE_LD_INTERNAL(uw)(ARG1, addr, attrs, result,
> - DEVICE_ENDIANNESS);
> + return ADDRESS_SPACE_LD_INTERNAL(uw)(ARG1, MO_ENDIAN,
> + addr, attrs, result);
> }
>
> uint32_t ADDRESS_SPACE_LD(l)(ARG1_DECL, hwaddr addr,
> MemTxAttrs attrs, MemTxResult *result)
> {
> - return ADDRESS_SPACE_LD_INTERNAL(l)(ARG1, addr, attrs, result,
> - DEVICE_ENDIANNESS);
> + return ADDRESS_SPACE_LD_INTERNAL(l)(ARG1, MO_ENDIAN,
> + addr, attrs, result);
> }
>
> uint64_t ADDRESS_SPACE_LD(q)(ARG1_DECL, hwaddr addr,
> MemTxAttrs attrs, MemTxResult *result)
> {
> - return ADDRESS_SPACE_LD_INTERNAL(q)(ARG1, addr, attrs, result,
> - DEVICE_ENDIANNESS);
> + return ADDRESS_SPACE_LD_INTERNAL(q)(ARG1, MO_ENDIAN,
> + addr, attrs, result);
> }
>
> void ADDRESS_SPACE_ST(w)(ARG1_DECL, hwaddr addr, uint16_t val,
> MemTxAttrs attrs, MemTxResult *result)
> {
> - ADDRESS_SPACE_ST_INTERNAL(w)(ARG1, addr, val, attrs, result,
> - DEVICE_ENDIANNESS);
> + ADDRESS_SPACE_ST_INTERNAL(w)(ARG1, MO_ENDIAN,
> + addr, val, attrs, result);
> }
>
> void ADDRESS_SPACE_ST(l)(ARG1_DECL, hwaddr addr, uint32_t val,
> MemTxAttrs attrs, MemTxResult *result)
> {
> - ADDRESS_SPACE_ST_INTERNAL(l)(ARG1, addr, val, attrs, result,
> - DEVICE_ENDIANNESS);
> + ADDRESS_SPACE_ST_INTERNAL(l)(ARG1, MO_ENDIAN,
> + addr, val, attrs, result);
> }
>
> void ADDRESS_SPACE_ST(q)(ARG1_DECL, hwaddr addr, uint64_t val,
> MemTxAttrs attrs, MemTxResult *result)
> {
> - ADDRESS_SPACE_ST_INTERNAL(q)(ARG1, addr, val, attrs, result,
> - DEVICE_ENDIANNESS);
> + ADDRESS_SPACE_ST_INTERNAL(q)(ARG1, MO_ENDIAN,
> + addr, val, attrs, result);
> }
>
> #undef ADDRESS_SPACE_LD
> @@ -67,4 +67,4 @@ void ADDRESS_SPACE_ST(q)(ARG1_DECL, hwaddr addr,
> uint64_t val,
> #undef ADDRESS_SPACE_ST_INTERNAL
>
> #undef ENDIANNESS
> -#undef DEVICE_ENDIANNESS
> +#undef MO_ENDIAN
> --
> 2.52.0
>
>
© 2016 - 2026 Red Hat, Inc.