On Mon, Aug 24, 2026 at 12:19:15PM +0800, BillXiang wrote:
> Hi Richard, I've read your code in accel/tcg/ldst_atomicity.c.inc. Do 
> you think it would be better to make the load/store_atomic* public?

They do not fit by default, as we need to still process unaligned cases?

I wished we can use qemu_mem_move() directly that just got introduced.. but
it does slightly more than wanted.  Maybe something like this?  Below diff
dropped ldsw_he_p() alone the way as it's never used.

Thanks,

===8<===

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 387d65c0b0..04a0f63612 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -1,6 +1,7 @@
 #ifndef BSWAP_H
 #define BSWAP_H
 
+#include "qemu/atomic.h"
 #include "qemu/target-info.h"
 #include "exec/memop.h"
 
@@ -238,62 +239,52 @@ static inline void stb_p(void *ptr, uint8_t v)
     *(uint8_t *)ptr = v;
 }
 
-/*
- * Any compiler worth its salt will turn these memcpy into native unaligned
- * operations.  Thus we don't need to play games with packed attributes, or
- * inline byte-by-byte stores.
- * Some compilation environments (eg some fortify-source implementations)
- * may intercept memcpy() in a way that defeats the compiler optimization,
- * though, so we use __builtin_memcpy() to give ourselves the best chance
- * of good performance.
- */
-
-static inline int lduw_he_p(const void *ptr)
-{
-    uint16_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
-
-static inline int ldsw_he_p(const void *ptr)
-{
-    int16_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
+#define  LD_HE_P(type, size)                                \
+    static inline type                                      \
+    glue(glue(ld, size), _he_p)(const void *ptr)            \
+    {                                                       \
+        type v;                                             \
+        if (unlikely((uintptr_t)ptr & (sizeof(v) - 1))) {   \
+            __builtin_memcpy(&v, ptr, sizeof(v));           \
+        } else {                                            \
+            v = qatomic_read((type *)ptr);                  \
+        }                                                   \
+        return v;                                           \
+    }
 
-static inline void stw_he_p(void *ptr, uint16_t v)
-{
-    __builtin_memcpy(ptr, &v, sizeof(v));
-}
+#define  ST_HE_P(type, size)                                \
+    static inline void                                      \
+    glue(glue(st, size), _he_p)(void *ptr, type v)          \
+    {                                                       \
+        if (unlikely((uintptr_t)ptr & (sizeof(v) - 1))) {   \
+            __builtin_memcpy(ptr, &v, sizeof(v));           \
+        } else {                                            \
+            qatomic_set((type *)ptr, v);                    \
+        }                                                   \
+    }
 
-static inline void st24_he_p(void *ptr, uint32_t v)
-{
-    __builtin_memcpy(ptr, &v, 3);
-}
+LD_HE_P(uint16_t, 16)
+LD_HE_P(uint32_t, 32)
+LD_HE_P(uint64_t, 64)
+ST_HE_P(uint16_t, 16)
+ST_HE_P(uint32_t, 32)
+ST_HE_P(uint64_t, 64)
 
-static inline int ldl_he_p(const void *ptr)
-{
-    int32_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
+#undef LD_HE_P
+#undef ST_HE_P
+#undef ADDR_ALIGNED
 
-static inline void stl_he_p(void *ptr, uint32_t v)
-{
-    __builtin_memcpy(ptr, &v, sizeof(v));
-}
+#define  lduw_he_p  ld16_he_p
+#define  ldl_he_p  ld32_he_p
+#define  ldq_he_p  ld64_he_p
 
-static inline uint64_t ldq_he_p(const void *ptr)
-{
-    uint64_t r;
-    __builtin_memcpy(&r, ptr, sizeof(r));
-    return r;
-}
+#define  stw_he_p  st16_he_p
+#define  stl_he_p  st32_he_p
+#define  stq_he_p  st64_he_p
 
-static inline void stq_he_p(void *ptr, uint64_t v)
+static inline void st24_he_p(void *ptr, uint32_t v)
 {
-    __builtin_memcpy(ptr, &v, sizeof(v));
+    __builtin_memcpy(ptr, &v, 3);
 }
 
 static inline int lduw_le_p(const void *ptr)
-- 
2.54.0

-- 
Peter Xu


Reply via email to