qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/8] linux-user fixes
@ 2013-01-05  0:39 Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 1/8] fdt: Use bswapN instead of bswap_N Richard Henderson
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Version 1 was way back in October, 

  http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg02854.html

wherein Blue asked me to re-do the unaligned access function part of
the patch.  I've now done that, as patch 3 of this series.

But having a look at <qemu/bswap.h> was frought with ugliness, and
I've now cleaned up some of that as well.


r~


Richard Henderson (8):
  fdt: Use bswapN instead of bswap_N
  bswap: Tidy base definitions of bswapN
  bswap: Add host endian unaligned access functions
  bswap: Rewrite all ld<type>_<endian>_p functions
  bswap: Rewrite cpu_to_<endian><type>u with {ld,st}<type>_<endian>_p
  linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr
  alpha-linux-user: Fix sigaction
  user: Consider symbolic links as possible directories

 include/libfdt_env.h      |  16 +-
 include/qemu/bswap.h      | 480 ++++++++++++----------------------------------
 linux-user/qemu.h         |  63 +++---
 linux-user/signal.c       |  22 +--
 linux-user/syscall_defs.h |   2 +-
 path.c                    |   5 +-
 6 files changed, 171 insertions(+), 417 deletions(-)

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 1/8] fdt: Use bswapN instead of bswap_N
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 2/8] bswap: Tidy base definitions of bswapN Richard Henderson
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Fixes the libfdt enabled build for hosts that have <machine/bswap.h>.

The code at the beginning of qemu/bswap.h is attempting to standardize
on bswapN.  In the case of CONFIG_MACHINE_BSWAP_H, this is all we get.
In the case of CONFIG_BYTESWAP_H, we get bswap_N from the system header
and then wrap these with inline functions to get bswapN.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/libfdt_env.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/libfdt_env.h b/include/libfdt_env.h
index 7938d73..3667d4c 100644
--- a/include/libfdt_env.h
+++ b/include/libfdt_env.h
@@ -22,15 +22,15 @@
 #include "qemu/bswap.h"
 
 #ifdef HOST_WORDS_BIGENDIAN
-#define fdt32_to_cpu(x)		(x)
-#define cpu_to_fdt32(x)		(x)
-#define fdt64_to_cpu(x)		(x)
-#define cpu_to_fdt64(x)		(x)
+#define fdt32_to_cpu(x)  (x)
+#define cpu_to_fdt32(x)  (x)
+#define fdt64_to_cpu(x)  (x)
+#define cpu_to_fdt64(x)  (x)
 #else
-#define fdt32_to_cpu(x)		(bswap_32((x)))
-#define cpu_to_fdt32(x)		(bswap_32((x)))
-#define fdt64_to_cpu(x)		(bswap_64((x)))
-#define cpu_to_fdt64(x)		(bswap_64((x)))
+#define fdt32_to_cpu(x)  bswap32(x)
+#define cpu_to_fdt32(x)  bswap32(x)
+#define fdt64_to_cpu(x)  bswap64(x)
+#define cpu_to_fdt64(x)  bswap64(x)
 #endif
 
 #endif /* _LIBFDT_ENV_H */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 2/8] bswap: Tidy base definitions of bswapN
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 1/8] fdt: Use bswapN instead of bswap_N Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 3/8] bswap: Add host endian unaligned access functions Richard Henderson
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Move the bswap_N -> bswapN wrappers inside CONFIG_BYTESWAP_H.

Change the ultimate fallback defintions from macros to inline functions.
The proper types recieved by the function arguments means we can remove
unnecessary casts, making the code more readable.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/qemu/bswap.h | 72 ++++++++++++++++++++++------------------------------
 1 file changed, 30 insertions(+), 42 deletions(-)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 2006fcd..b2a8f94 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -7,48 +7,11 @@
 #include "fpu/softfloat.h"
 
 #ifdef CONFIG_MACHINE_BSWAP_H
-#include <sys/endian.h>
-#include <sys/types.h>
-#include <machine/bswap.h>
-#else
-
-#ifdef CONFIG_BYTESWAP_H
-#include <byteswap.h>
-#else
-
-#define bswap_16(x) \
-({ \
-	uint16_t __x = (x); \
-	((uint16_t)( \
-		(((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
-		(((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
-})
-
-#define bswap_32(x) \
-({ \
-	uint32_t __x = (x); \
-	((uint32_t)( \
-		(((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
-		(((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
-		(((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
-		(((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
-})
-
-#define bswap_64(x) \
-({ \
-	uint64_t __x = (x); \
-	((uint64_t)( \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) <<  8) | \
-	        (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >>  8) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
-		(uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
-})
-
-#endif /* !CONFIG_BYTESWAP_H */
+# include <sys/endian.h>
+# include <sys/types.h>
+# include <machine/bswap.h>
+#elif defined(CONFIG_BYTESWAP_H)
+# include <byteswap.h>
 
 static inline uint16_t bswap16(uint16_t x)
 {
@@ -64,7 +27,32 @@ static inline uint64_t bswap64(uint64_t x)
 {
     return bswap_64(x);
 }
+# else
+static inline uint16_t bswap16(uint16_t x)
+{
+    return (((x & 0x00ff) << 8) |
+            ((x & 0xff00) >> 8));
+}
 
+static inline uint32_t bswap32(uint32_t x)
+{
+    return (((x & 0x000000ffU) << 24) |
+            ((x & 0x0000ff00U) <<  8) |
+            ((x & 0x00ff0000U) >>  8) |
+            ((x & 0xff000000U) >> 24));
+}
+
+static inline uint64_t bswap64(uint64_t x)
+{
+    return (((x & 0x00000000000000ffULL) << 56) |
+            ((x & 0x000000000000ff00ULL) << 40) |
+            ((x & 0x0000000000ff0000ULL) << 24) |
+            ((x & 0x00000000ff000000ULL) <<  8) |
+            ((x & 0x000000ff00000000ULL) >>  8) |
+            ((x & 0x0000ff0000000000ULL) >> 24) |
+            ((x & 0x00ff000000000000ULL) >> 40) |
+            ((x & 0xff00000000000000ULL) >> 56));
+}
 #endif /* ! CONFIG_MACHINE_BSWAP_H */
 
 static inline void bswap16s(uint16_t *s)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 3/8] bswap: Add host endian unaligned access functions
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 1/8] fdt: Use bswapN instead of bswap_N Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 2/8] bswap: Tidy base definitions of bswapN Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 4/8] bswap: Rewrite all ld<type>_<endian>_p functions Richard Henderson
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/qemu/bswap.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index b2a8f94..381554b 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -226,6 +226,8 @@ static inline uint32_t qemu_bswap_len(uint32_t value, int len)
     return bswap32(value) >> (32 - 8 * len);
 }
 
+/* Unions for reinterpreting between floats and integers.  */
+
 typedef union {
     float32 f;
     uint32_t l;
@@ -309,7 +311,7 @@ typedef union {
  *   q: 64 bits
  *
  * endian is:
- * (empty): 8 bit access
+ * (empty): host endian
  *   be   : big endian
  *   le   : little endian
  */
@@ -328,6 +330,53 @@ static inline void stb_p(void *ptr, int 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.  */
+
+static inline int lduw_p(const void *ptr)
+{
+    uint16_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline int ldsw_p(const void *ptr)
+{
+    int16_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline void stw_p(void *ptr, uint16_t v)
+{
+    memcpy(ptr, &v, sizeof(v));
+}
+
+static inline int ldl_p(const void *ptr)
+{
+    int32_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline void stl_p(void *ptr, uint32_t v)
+{
+    memcpy(ptr, &v, sizeof(v));
+}
+
+static inline uint64_t ldq_p(const void *ptr)
+{
+    uint64_t r;
+    memcpy(&r, ptr, sizeof(r));
+    return r;
+}
+
+static inline void stq_p(void *ptr, uint64_t v)
+{
+    memcpy(ptr, &v, sizeof(v));
+}
+
 /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
    kernel handles unaligned load/stores may give better results, but
    it is a system wide setting : bad */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 4/8] bswap: Rewrite all ld<type>_<endian>_p functions
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
                   ` (2 preceding siblings ...)
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 3/8] bswap: Add host endian unaligned access functions Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 5/8] bswap: Rewrite cpu_to_<endian><type>u with {ld, st}<type>_<endian>_p Richard Henderson
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Use the new host endian unaligned access functions instead of
open coding byte-by-byte references.  Remove assembly special
cases for i386 and ppc -- we've now exposed the operation to
the compiler sufficiently for these to be optimized automatically.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/qemu/bswap.h | 300 ++++++---------------------------------------------
 1 file changed, 30 insertions(+), 270 deletions(-)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 381554b..68cda6a 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -215,11 +215,6 @@ static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
 #define leul_to_cpu(v) (v)
 #endif
 
-#undef le_bswap
-#undef be_bswap
-#undef le_bswaps
-#undef be_bswaps
-
 /* len must be one of 1, 2, 4 */
 static inline uint32_t qemu_bswap_len(uint32_t value, int len)
 {
@@ -377,115 +372,61 @@ static inline void stq_p(void *ptr, uint64_t v)
     memcpy(ptr, &v, sizeof(v));
 }
 
-/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
-   kernel handles unaligned load/stores may give better results, but
-   it is a system wide setting : bad */
-#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
-/* conservative code for little endian unaligned accesses */
 static inline int lduw_le_p(const void *ptr)
 {
-#ifdef _ARCH_PPC
-    int val;
-    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
-    return val;
-#else
-    const uint8_t *p = ptr;
-    return p[0] | (p[1] << 8);
-#endif
+    return (uint16_t)le_bswap(lduw_p(ptr), 16);
 }
 
 static inline int ldsw_le_p(const void *ptr)
 {
-#ifdef _ARCH_PPC
-    int val;
-    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
-    return (int16_t)val;
-#else
-    const uint8_t *p = ptr;
-    return (int16_t)(p[0] | (p[1] << 8));
-#endif
+    return (int16_t)le_bswap(lduw_p(ptr), 16);
 }
 
 static inline int ldl_le_p(const void *ptr)
 {
-#ifdef _ARCH_PPC
-    int val;
-    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
-    return val;
-#else
-    const uint8_t *p = ptr;
-    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-#endif
+    return le_bswap(ldl_p(ptr), 32);
 }
 
 static inline uint64_t ldq_le_p(const void *ptr)
 {
-    const uint8_t *p = ptr;
-    uint32_t v1, v2;
-    v1 = ldl_le_p(p);
-    v2 = ldl_le_p(p + 4);
-    return v1 | ((uint64_t)v2 << 32);
+    return le_bswap(ldq_p(ptr), 64);
 }
 
 static inline void stw_le_p(void *ptr, int v)
 {
-#ifdef _ARCH_PPC
-    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
-#else
-    uint8_t *p = ptr;
-    p[0] = v;
-    p[1] = v >> 8;
-#endif
+    stw_p(ptr, le_bswap(v, 16));
 }
 
 static inline void stl_le_p(void *ptr, int v)
 {
-#ifdef _ARCH_PPC
-    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
-#else
-    uint8_t *p = ptr;
-    p[0] = v;
-    p[1] = v >> 8;
-    p[2] = v >> 16;
-    p[3] = v >> 24;
-#endif
+    stl_p(ptr, le_bswap(v, 32));
 }
 
 static inline void stq_le_p(void *ptr, uint64_t v)
 {
-    uint8_t *p = ptr;
-    stl_le_p(p, (uint32_t)v);
-    stl_le_p(p + 4, v >> 32);
+    stq_p(ptr, le_bswap(v, 64));
 }
 
 /* float access */
 
 static inline float32 ldfl_le_p(const void *ptr)
 {
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
-    u.i = ldl_le_p(ptr);
+    CPU_FloatU u;
+    u.l = ldl_le_p(ptr);
     return u.f;
 }
 
 static inline void stfl_le_p(void *ptr, float32 v)
 {
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
+    CPU_FloatU u;
     u.f = v;
-    stl_le_p(ptr, u.i);
+    stl_le_p(ptr, u.l);
 }
 
 static inline float64 ldfq_le_p(const void *ptr)
 {
     CPU_DoubleU u;
-    u.l.lower = ldl_le_p(ptr);
-    u.l.upper = ldl_le_p(ptr + 4);
+    u.ll = ldq_le_p(ptr);
     return u.d;
 }
 
@@ -493,188 +434,64 @@ static inline void stfq_le_p(void *ptr, float64 v)
 {
     CPU_DoubleU u;
     u.d = v;
-    stl_le_p(ptr, u.l.lower);
-    stl_le_p(ptr + 4, u.l.upper);
+    stq_le_p(ptr, u.ll);
 }
 
-#else
-
-static inline int lduw_le_p(const void *ptr)
-{
-    return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_le_p(const void *ptr)
-{
-    return *(int16_t *)ptr;
-}
-
-static inline int ldl_le_p(const void *ptr)
-{
-    return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_le_p(const void *ptr)
-{
-    return *(uint64_t *)ptr;
-}
-
-static inline void stw_le_p(void *ptr, int v)
-{
-    *(uint16_t *)ptr = v;
-}
-
-static inline void stl_le_p(void *ptr, int v)
-{
-    *(uint32_t *)ptr = v;
-}
-
-static inline void stq_le_p(void *ptr, uint64_t v)
-{
-    *(uint64_t *)ptr = v;
-}
-
-/* float access */
-
-static inline float32 ldfl_le_p(const void *ptr)
-{
-    return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_le_p(const void *ptr)
-{
-    return *(float64 *)ptr;
-}
-
-static inline void stfl_le_p(void *ptr, float32 v)
-{
-    *(float32 *)ptr = v;
-}
-
-static inline void stfq_le_p(void *ptr, float64 v)
-{
-    *(float64 *)ptr = v;
-}
-#endif
-
-#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
-
 static inline int lduw_be_p(const void *ptr)
 {
-#if defined(__i386__)
-    int val;
-    asm volatile ("movzwl %1, %0\n"
-                  "xchgb %b0, %h0\n"
-                  : "=q" (val)
-                  : "m" (*(uint16_t *)ptr));
-    return val;
-#else
-    const uint8_t *b = ptr;
-    return ((b[0] << 8) | b[1]);
-#endif
+    return (uint16_t)be_bswap(lduw_p(ptr), 16);
 }
 
 static inline int ldsw_be_p(const void *ptr)
 {
-#if defined(__i386__)
-    int val;
-    asm volatile ("movzwl %1, %0\n"
-                  "xchgb %b0, %h0\n"
-                  : "=q" (val)
-                  : "m" (*(uint16_t *)ptr));
-    return (int16_t)val;
-#else
-    const uint8_t *b = ptr;
-    return (int16_t)((b[0] << 8) | b[1]);
-#endif
+    return (int16_t)be_bswap(lduw_p(ptr), 16);
 }
 
 static inline int ldl_be_p(const void *ptr)
 {
-#if defined(__i386__) || defined(__x86_64__)
-    int val;
-    asm volatile ("movl %1, %0\n"
-                  "bswap %0\n"
-                  : "=r" (val)
-                  : "m" (*(uint32_t *)ptr));
-    return val;
-#else
-    const uint8_t *b = ptr;
-    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-#endif
+    return be_bswap(ldl_p(ptr), 32);
 }
 
 static inline uint64_t ldq_be_p(const void *ptr)
 {
-    uint32_t a,b;
-    a = ldl_be_p(ptr);
-    b = ldl_be_p((uint8_t *)ptr + 4);
-    return (((uint64_t)a<<32)|b);
+    return be_bswap(ldq_p(ptr), 64);
 }
 
 static inline void stw_be_p(void *ptr, int v)
 {
-#if defined(__i386__)
-    asm volatile ("xchgb %b0, %h0\n"
-                  "movw %w0, %1\n"
-                  : "=q" (v)
-                  : "m" (*(uint16_t *)ptr), "0" (v));
-#else
-    uint8_t *d = (uint8_t *) ptr;
-    d[0] = v >> 8;
-    d[1] = v;
-#endif
+    stw_p(ptr, be_bswap(v, 16));
 }
 
 static inline void stl_be_p(void *ptr, int v)
 {
-#if defined(__i386__) || defined(__x86_64__)
-    asm volatile ("bswap %0\n"
-                  "movl %0, %1\n"
-                  : "=r" (v)
-                  : "m" (*(uint32_t *)ptr), "0" (v));
-#else
-    uint8_t *d = (uint8_t *) ptr;
-    d[0] = v >> 24;
-    d[1] = v >> 16;
-    d[2] = v >> 8;
-    d[3] = v;
-#endif
+    stl_p(ptr, be_bswap(v, 32));
 }
 
 static inline void stq_be_p(void *ptr, uint64_t v)
 {
-    stl_be_p(ptr, v >> 32);
-    stl_be_p((uint8_t *)ptr + 4, v);
+    stq_p(ptr, be_bswap(v, 64));
 }
 
 /* float access */
 
 static inline float32 ldfl_be_p(const void *ptr)
 {
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
-    u.i = ldl_be_p(ptr);
+    CPU_FloatU u;
+    u.l = ldl_be_p(ptr);
     return u.f;
 }
 
 static inline void stfl_be_p(void *ptr, float32 v)
 {
-    union {
-        float32 f;
-        uint32_t i;
-    } u;
+    CPU_FloatU u;
     u.f = v;
-    stl_be_p(ptr, u.i);
+    stl_be_p(ptr, u.l);
 }
 
 static inline float64 ldfq_be_p(const void *ptr)
 {
     CPU_DoubleU u;
-    u.l.upper = ldl_be_p(ptr);
-    u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
+    u.ll = ldq_be_p(ptr);
     return u.d;
 }
 
@@ -682,69 +499,12 @@ static inline void stfq_be_p(void *ptr, float64 v)
 {
     CPU_DoubleU u;
     u.d = v;
-    stl_be_p(ptr, u.l.upper);
-    stl_be_p((uint8_t *)ptr + 4, u.l.lower);
-}
-
-#else
-
-static inline int lduw_be_p(const void *ptr)
-{
-    return *(uint16_t *)ptr;
-}
-
-static inline int ldsw_be_p(const void *ptr)
-{
-    return *(int16_t *)ptr;
-}
-
-static inline int ldl_be_p(const void *ptr)
-{
-    return *(uint32_t *)ptr;
-}
-
-static inline uint64_t ldq_be_p(const void *ptr)
-{
-    return *(uint64_t *)ptr;
-}
-
-static inline void stw_be_p(void *ptr, int v)
-{
-    *(uint16_t *)ptr = v;
-}
-
-static inline void stl_be_p(void *ptr, int v)
-{
-    *(uint32_t *)ptr = v;
-}
-
-static inline void stq_be_p(void *ptr, uint64_t v)
-{
-    *(uint64_t *)ptr = v;
-}
-
-/* float access */
-
-static inline float32 ldfl_be_p(const void *ptr)
-{
-    return *(float32 *)ptr;
-}
-
-static inline float64 ldfq_be_p(const void *ptr)
-{
-    return *(float64 *)ptr;
-}
-
-static inline void stfl_be_p(void *ptr, float32 v)
-{
-    *(float32 *)ptr = v;
-}
-
-static inline void stfq_be_p(void *ptr, float64 v)
-{
-    *(float64 *)ptr = v;
+    stq_be_p(ptr, u.ll);
 }
 
-#endif
+#undef le_bswap
+#undef be_bswap
+#undef le_bswaps
+#undef be_bswaps
 
 #endif /* BSWAP_H */
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 5/8] bswap: Rewrite cpu_to_<endian><type>u with {ld, st}<type>_<endian>_p
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
                   ` (3 preceding siblings ...)
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 4/8] bswap: Rewrite all ld<type>_<endian>_p functions Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 6/8] linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr Richard Henderson
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

We've now optimized the ld/st versions; reuse that for the "legacy"
versions.  Always use inlines so that we get the type checking that
we expect.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/qemu/bswap.h | 147 +++++++++++++++++++--------------------------------
 1 file changed, 53 insertions(+), 94 deletions(-)

diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 68cda6a..be9b035 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -121,100 +121,6 @@ CPU_CONVERT(le, 16, uint16_t)
 CPU_CONVERT(le, 32, uint32_t)
 CPU_CONVERT(le, 64, uint64_t)
 
-/* unaligned versions (optimized for frequent unaligned accesses)*/
-
-#if defined(__i386__) || defined(_ARCH_PPC)
-
-#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
-#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
-#define le16_to_cpupu(p) le16_to_cpup(p)
-#define le32_to_cpupu(p) le32_to_cpup(p)
-#define be32_to_cpupu(p) be32_to_cpup(p)
-
-#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
-#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
-#define cpu_to_be64wu(p, v) cpu_to_be64w(p, v)
-
-#else
-
-static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v & 0xff;
-    p1[1] = v >> 8;
-}
-
-static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v & 0xff;
-    p1[1] = v >> 8;
-    p1[2] = v >> 16;
-    p1[3] = v >> 24;
-}
-
-static inline uint16_t le16_to_cpupu(const uint16_t *p)
-{
-    const uint8_t *p1 = (const uint8_t *)p;
-    return p1[0] | (p1[1] << 8);
-}
-
-static inline uint32_t le32_to_cpupu(const uint32_t *p)
-{
-    const uint8_t *p1 = (const uint8_t *)p;
-    return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
-}
-
-static inline uint32_t be32_to_cpupu(const uint32_t *p)
-{
-    const uint8_t *p1 = (const uint8_t *)p;
-    return p1[3] | (p1[2] << 8) | (p1[1] << 16) | (p1[0] << 24);
-}
-
-static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v >> 8;
-    p1[1] = v & 0xff;
-}
-
-static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v >> 24;
-    p1[1] = v >> 16;
-    p1[2] = v >> 8;
-    p1[3] = v & 0xff;
-}
-
-static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
-{
-    uint8_t *p1 = (uint8_t *)p;
-
-    p1[0] = v >> 56;
-    p1[1] = v >> 48;
-    p1[2] = v >> 40;
-    p1[3] = v >> 32;
-    p1[4] = v >> 24;
-    p1[5] = v >> 16;
-    p1[6] = v >> 8;
-    p1[7] = v & 0xff;
-}
-
-#endif
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define cpu_to_32wu cpu_to_be32wu
-#define leul_to_cpu(v) glue(glue(le,HOST_LONG_BITS),_to_cpu)(v)
-#else
-#define cpu_to_32wu cpu_to_le32wu
-#define leul_to_cpu(v) (v)
-#endif
-
 /* len must be one of 1, 2, 4 */
 static inline uint32_t qemu_bswap_len(uint32_t value, int len)
 {
@@ -310,6 +216,7 @@ typedef union {
  *   be   : big endian
  *   le   : little endian
  */
+
 static inline int ldub_p(const void *ptr)
 {
     return *(uint8_t *)ptr;
@@ -502,6 +409,58 @@ static inline void stfq_be_p(void *ptr, float64 v)
     stq_be_p(ptr, u.ll);
 }
 
+/* Legacy unaligned versions.  Note that we never had a complete set.  */
+
+static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
+{
+    stw_le_p(p, v);
+}
+
+static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
+{
+    stl_le_p(p, v);
+}
+
+static inline uint16_t le16_to_cpupu(const uint16_t *p)
+{
+    return lduw_le_p(p);
+}
+
+static inline uint32_t le32_to_cpupu(const uint32_t *p)
+{
+    return ldl_le_p(p);
+}
+
+static inline uint32_t be32_to_cpupu(const uint32_t *p)
+{
+    return ldl_be_p(p);
+}
+
+static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
+{
+    stw_be_p(p, v);
+}
+
+static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
+{
+    stl_be_p(p, v);
+}
+
+static inline void cpu_to_be64wu(uint64_t *p, uint64_t v)
+{
+    stq_be_p(p, v);
+}
+
+static inline void cpu_to_32wu(uint32_t *p, uint32_t v)
+{
+    stl_p(p, v);
+}
+
+static inline unsigned long leul_to_cpu(unsigned long v)
+{
+    return le_bswap(v, HOST_LONG_BITS);
+}
+
 #undef le_bswap
 #undef be_bswap
 #undef le_bswaps
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 6/8] linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
                   ` (4 preceding siblings ...)
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 5/8] bswap: Rewrite cpu_to_<endian><type>u with {ld, st}<type>_<endian>_p Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 7/8] alpha-linux-user: Fix sigaction Richard Henderson
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

The previous formuation with multiple assignments to __typeof(*hptr) falls
down when hptr is qualified const.  E.g. with const struct S *p, p->f is
also qualified const.

With this formulation, there's no assignment to any local variable.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/qemu.h | 63 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 8a3538c..31a220a 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -287,36 +287,39 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
                             (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
 }
 
-/* NOTE __get_user and __put_user use host pointers and don't check access. */
-/* These are usually used to access struct data members once the
- * struct has been locked - usually with lock_user_struct().
- */
-#define __put_user(x, hptr)\
-({ __typeof(*hptr) pu_ = (x);\
-    switch(sizeof(*hptr)) {\
-    case 1: break;\
-    case 2: pu_ = tswap16(pu_); break; \
-    case 4: pu_ = tswap32(pu_); break; \
-    case 8: pu_ = tswap64(pu_); break; \
-    default: abort();\
-    }\
-    memcpy(hptr, &pu_, sizeof(pu_)); \
-    0;\
-})
-
-#define __get_user(x, hptr) \
-({ __typeof(*hptr) gu_; \
-    memcpy(&gu_, hptr, sizeof(gu_)); \
-    switch(sizeof(*hptr)) {\
-    case 1: break; \
-    case 2: gu_ = tswap16(gu_); break; \
-    case 4: gu_ = tswap32(gu_); break; \
-    case 8: gu_ = tswap64(gu_); break; \
-    default: abort();\
-    }\
-    (x) = gu_; \
-    0;\
-})
+/* NOTE __get_user and __put_user use host pointers and don't check access.
+   These are usually used to access struct data members once the struct has
+   been locked - usually with lock_user_struct.  */
+
+/* Tricky points:
+   - Use __builtin_choose_expr to avoid type promotion from ?:,
+   - Invalid sizes result in a compile time error stemming from
+     the fact that abort has no parameters.
+   - It's easier to use the endian-specific unaligned load/store
+     functions than host-endian unaligned load/store plus tswapN.  */
+
+#define __put_user_e(x, hptr, e)                                        \
+  (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p,                   \
+   __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort))))   \
+     ((hptr), (x)), 0)
+
+#define __get_user_e(x, hptr, e)                                        \
+  ((x) =                                                                \
+   __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p,                  \
+   __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p,            \
+   __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort))))   \
+     (hptr), 0)
+
+#ifdef TARGET_WORDS_BIGENDIAN
+# define __put_user(x, hptr)  __put_user_e(x, hptr, be)
+# define __get_user(x, hptr)  __get_user_e(x, hptr, be)
+#else
+# define __put_user(x, hptr)  __put_user_e(x, hptr, le)
+# define __get_user(x, hptr)  __get_user_e(x, hptr, le)
+#endif
 
 /* put_user()/get_user() take a guest address and check access */
 /* These are usually used to access an atomic data type, such as an int,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 7/8] alpha-linux-user: Fix sigaction
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
                   ` (5 preceding siblings ...)
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 6/8] linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 8/8] user: Consider symbolic links as possible directories Richard Henderson
  2013-01-12 16:07 ` [Qemu-devel] [PATCH v2 0/8] linux-user fixes Blue Swirl
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Unconditional bswap replaced by __get_user/__put_user.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/signal.c       | 22 ++++++++--------------
 linux-user/syscall_defs.h |  2 +-
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 95e2ffa..407619a 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -607,28 +607,22 @@ int do_sigaction(int sig, const struct target_sigaction *act,
             sig, act, oact);
 #endif
     if (oact) {
-        oact->_sa_handler = tswapal(k->_sa_handler);
-#if defined(TARGET_MIPS) || defined (TARGET_ALPHA)
-        oact->sa_flags = bswap32(k->sa_flags);
-#else
-        oact->sa_flags = tswapal(k->sa_flags);
-#endif
+        __put_user(k->_sa_handler, &oact->_sa_handler);
+        __put_user(k->sa_flags, &oact->sa_flags);
 #if !defined(TARGET_MIPS)
-        oact->sa_restorer = tswapal(k->sa_restorer);
+        __put_user(k->sa_restorer, &oact->sa_restorer);
 #endif
+        /* Not swapped.  */
         oact->sa_mask = k->sa_mask;
     }
     if (act) {
         /* FIXME: This is not threadsafe.  */
-        k->_sa_handler = tswapal(act->_sa_handler);
-#if defined(TARGET_MIPS) || defined (TARGET_ALPHA)
-        k->sa_flags = bswap32(act->sa_flags);
-#else
-        k->sa_flags = tswapal(act->sa_flags);
-#endif
+        __get_user(k->_sa_handler, &act->_sa_handler);
+        __get_user(k->sa_flags, &act->sa_flags);
 #if !defined(TARGET_MIPS)
-        k->sa_restorer = tswapal(act->sa_restorer);
+        __get_user(k->sa_restorer, &act->sa_restorer);
 #endif
+        /* To be swapped in target_to_host_sigset.  */
         k->sa_mask = act->sa_mask;
 
         /* we update the host linux signal state */
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index d4589e7..f8f5539 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -544,7 +544,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
 struct target_old_sigaction {
     abi_ulong _sa_handler;
     abi_ulong sa_mask;
-    abi_ulong sa_flags;
+    int32_t sa_flags;
 };
 
 struct target_rt_sigaction {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH 8/8] user: Consider symbolic links as possible directories
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
                   ` (6 preceding siblings ...)
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 7/8] alpha-linux-user: Fix sigaction Richard Henderson
@ 2013-01-05  0:39 ` Richard Henderson
  2013-01-12 16:07 ` [Qemu-devel] [PATCH v2 0/8] linux-user fixes Blue Swirl
  8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2013-01-05  0:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Riku Voipio

Commit 2296f194dfde4c0a54f249d3fdb8c8ca21dc611b reduced the number
of syscalls performed during user emulation startup, but failed to
consider the use of symbolic links in creating directory structures.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 path.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/path.c b/path.c
index ef3f277..4c5b0f6 100644
--- a/path.c
+++ b/path.c
@@ -58,9 +58,10 @@ static struct pathelem *new_entry(const char *root,
 #define streq(a,b) (strcmp((a), (b)) == 0)
 
 /* Not all systems provide this feature */
-#if defined(DT_DIR) && defined(DT_UNKNOWN)
+#if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
 # define dirent_type(dirent) ((dirent)->d_type)
-# define is_dir_maybe(type)  ((type) == DT_DIR || (type) == DT_UNKNOWN)
+# define is_dir_maybe(type) \
+    ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
 #else
 # define dirent_type(dirent) (1)
 # define is_dir_maybe(type)  (type)
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/8] linux-user fixes
  2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
                   ` (7 preceding siblings ...)
  2013-01-05  0:39 ` [Qemu-devel] [PATCH 8/8] user: Consider symbolic links as possible directories Richard Henderson
@ 2013-01-12 16:07 ` Blue Swirl
  8 siblings, 0 replies; 10+ messages in thread
From: Blue Swirl @ 2013-01-12 16:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Riku Voipio, qemu-devel

Thanks, applied all.

On Sat, Jan 5, 2013 at 12:39 AM, Richard Henderson <rth@twiddle.net> wrote:
> Version 1 was way back in October,
>
>   http://lists.gnu.org/archive/html/qemu-devel/2012-10/msg02854.html
>
> wherein Blue asked me to re-do the unaligned access function part of
> the patch.  I've now done that, as patch 3 of this series.
>
> But having a look at <qemu/bswap.h> was frought with ugliness, and
> I've now cleaned up some of that as well.
>
>
> r~
>
>
> Richard Henderson (8):
>   fdt: Use bswapN instead of bswap_N
>   bswap: Tidy base definitions of bswapN
>   bswap: Add host endian unaligned access functions
>   bswap: Rewrite all ld<type>_<endian>_p functions
>   bswap: Rewrite cpu_to_<endian><type>u with {ld,st}<type>_<endian>_p
>   linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr
>   alpha-linux-user: Fix sigaction
>   user: Consider symbolic links as possible directories
>
>  include/libfdt_env.h      |  16 +-
>  include/qemu/bswap.h      | 480 ++++++++++++----------------------------------
>  linux-user/qemu.h         |  63 +++---
>  linux-user/signal.c       |  22 +--
>  linux-user/syscall_defs.h |   2 +-
>  path.c                    |   5 +-
>  6 files changed, 171 insertions(+), 417 deletions(-)
>
> --
> 1.7.11.7
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-01-12 16:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-05  0:39 [Qemu-devel] [PATCH v2 0/8] linux-user fixes Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 1/8] fdt: Use bswapN instead of bswap_N Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 2/8] bswap: Tidy base definitions of bswapN Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 3/8] bswap: Add host endian unaligned access functions Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 4/8] bswap: Rewrite all ld<type>_<endian>_p functions Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 5/8] bswap: Rewrite cpu_to_<endian><type>u with {ld, st}<type>_<endian>_p Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 6/8] linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 7/8] alpha-linux-user: Fix sigaction Richard Henderson
2013-01-05  0:39 ` [Qemu-devel] [PATCH 8/8] user: Consider symbolic links as possible directories Richard Henderson
2013-01-12 16:07 ` [Qemu-devel] [PATCH v2 0/8] linux-user fixes Blue Swirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).