[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 16/43] bswap: Add new stn_*_p() and ldn_*_p() memory
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 16/43] bswap: Add new stn_*_p() and ldn_*_p() memory access functions |
Date: |
Fri, 15 Jun 2018 15:24:54 +0100 |
There's a common pattern in QEMU where a function needs to perform
a data load or store of an N byte integer in a particular endianness.
At the moment this is handled by doing a switch() on the size and
calling the appropriate ld*_p or st*_p function for each size.
Provide a new family of functions ldn_*_p() and stn_*_p() which
take the size as an argument and do the switch() themselves.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Philippe Mathieu-Daudé <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
Message-id: address@hidden
---
include/exec/cpu-all.h | 4 +++
include/qemu/bswap.h | 52 +++++++++++++++++++++++++++++++++++++
docs/devel/loads-stores.rst | 15 +++++++++++
3 files changed, 71 insertions(+)
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index a635f532f97..7fa726b8e36 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -133,6 +133,8 @@ static inline void tswap64s(uint64_t *s)
#define stq_p(p, v) stq_be_p(p, v)
#define stfl_p(p, v) stfl_be_p(p, v)
#define stfq_p(p, v) stfq_be_p(p, v)
+#define ldn_p(p, sz) ldn_be_p(p, sz)
+#define stn_p(p, sz, v) stn_be_p(p, sz, v)
#else
#define lduw_p(p) lduw_le_p(p)
#define ldsw_p(p) ldsw_le_p(p)
@@ -145,6 +147,8 @@ static inline void tswap64s(uint64_t *s)
#define stq_p(p, v) stq_le_p(p, v)
#define stfl_p(p, v) stfl_le_p(p, v)
#define stfq_p(p, v) stfq_le_p(p, v)
+#define ldn_p(p, sz) ldn_le_p(p, sz)
+#define stn_p(p, sz, v) stn_le_p(p, sz, v)
#endif
/* MMU memory access macros */
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 3f28f661b15..a684c1a7a29 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -290,6 +290,15 @@ typedef union {
* For accessors that take a guest address rather than a
* host address, see the cpu_{ld,st}_* accessors defined in
* cpu_ldst.h.
+ *
+ * For cases where the size to be used is not fixed at compile time,
+ * there are
+ * stn{endian}_p(ptr, sz, val)
+ * which stores @val to @ptr as an @endian-order number @sz bytes in size
+ * and
+ * ldn{endian}_p(ptr, sz)
+ * which loads @sz bytes from @ptr as an unsigned @endian-order number
+ * and returns it in a uint64_t.
*/
static inline int ldub_p(const void *ptr)
@@ -495,6 +504,49 @@ static inline unsigned long leul_to_cpu(unsigned long v)
#endif
}
+/* Store v to p as a sz byte value in host order */
+#define DO_STN_LDN_P(END) \
+ static inline void stn_## END ## _p(void *ptr, int sz, uint64_t v) \
+ { \
+ switch (sz) { \
+ case 1: \
+ stb_p(ptr, v); \
+ break; \
+ case 2: \
+ stw_ ## END ## _p(ptr, v); \
+ break; \
+ case 4: \
+ stl_ ## END ## _p(ptr, v); \
+ break; \
+ case 8: \
+ stq_ ## END ## _p(ptr, v); \
+ break; \
+ default: \
+ g_assert_not_reached(); \
+ } \
+ } \
+ static inline uint64_t ldn_## END ## _p(const void *ptr, int sz) \
+ { \
+ switch (sz) { \
+ case 1: \
+ return ldub_p(ptr); \
+ case 2: \
+ return lduw_ ## END ## _p(ptr); \
+ case 4: \
+ return (uint32_t)ldl_ ## END ## _p(ptr); \
+ case 8: \
+ return ldq_ ## END ## _p(ptr); \
+ default: \
+ g_assert_not_reached(); \
+ } \
+ }
+
+DO_STN_LDN_P(he)
+DO_STN_LDN_P(le)
+DO_STN_LDN_P(be)
+
+#undef DO_STN_LDN_P
+
#undef le_bswap
#undef be_bswap
#undef le_bswaps
diff --git a/docs/devel/loads-stores.rst b/docs/devel/loads-stores.rst
index 6a990cc2438..57d8c524bfe 100644
--- a/docs/devel/loads-stores.rst
+++ b/docs/devel/loads-stores.rst
@@ -53,9 +53,24 @@ The ``_{endian}`` infix is omitted for target-endian
accesses.
The target endian accessors are only available to source
files which are built per-target.
+There are also functions which take the size as an argument:
+
+load: ``ldn{endian}_p(ptr, sz)``
+
+which performs an unsigned load of ``sz`` bytes from ``ptr``
+as an ``{endian}`` order value and returns it in a uint64_t.
+
+store: ``stn{endian}_p(ptr, sz, val)``
+
+which stores ``val`` to ``ptr`` as an ``{endian}`` order value
+of size ``sz`` bytes.
+
+
Regexes for git grep
- ``\<ldf\?[us]\?[bwlq]\(_[hbl]e\)\?_p\>``
- ``\<stf\?[bwlq]\(_[hbl]e\)\?_p\>``
+ - ``\<ldn_\([hbl]e\)?_p\>``
+ - ``\<stn_\([hbl]e\)?_p\>``
``cpu_{ld,st}_*``
~~~~~~~~~~~~~~~~~
--
2.17.1
- [Qemu-devel] [PULL 00/43] target-arm queue, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 10/43] hw/arm/armv7m: Remove unused armv7m_init() function, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 11/43] arm: Don't crash if user tries to use a Cortex-M CPU without an NVIC, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 13/43] cpu-defs.h: Document CPUIOTLBEntry 'addr' field, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 08/43] hw/char/parallel: Convert away from old_mmio, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 07/43] hw/input/pckbd: Convert away from old_mmio, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 05/43] hw/block/pflash_cfi02: Convert away from old_mmio, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 17/43] exec.c: Don't accidentally sign-extend 4-byte loads in subpage_read(), Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 16/43] bswap: Add new stn_*_p() and ldn_*_p() memory access functions,
Peter Maydell <=
- [Qemu-devel] [PULL 04/43] hw/m68k/mcf5206: Convert away from old_mmio, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 15/43] CODING_STYLE: Define our preferred form for multiline comments, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 09/43] stellaris: Stop using armv7m_init(), Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 23/43] target/arm: Implement SVE compress active elements, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 06/43] hw/watchdog/wdt_i6300esb: Convert away from old_mmio, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 12/43] hw/core/or-irq: Support more than 16 inputs to an OR gate, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 01/43] arm_gicv3_kvm: kvm_dist_get/put_priority: skip the registers banked by GICR_IPRIORITYR, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 14/43] cputlb: Pass cpu_transaction_failed() the correct physaddr, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 21/43] target/arm: Implement SVE Permute - Predicates Group, Peter Maydell, 2018/06/15
- [Qemu-devel] [PULL 18/43] exec.c: Use stn_p() and ldn_p() instead of explicit switches, Peter Maydell, 2018/06/15