[PATCH xserver 3/2] Rewrite the byte swapping macros.
Eric Anholt
eric at anholt.net
Mon Mar 27 22:11:03 UTC 2017
The clever pointer tricks were actually not working, and we were doing
the byte-by-byte moves in general. By just doing the memcpy and
obvious byte swap code, we end up generating actual byte swap
instructions, thanks to optimizing compilers.
text data bss dec hex filename
before: 2241932 51584 132016 2425532 2502bc hw/xfree86/Xorg
after: 2216276 51584 132016 2399876 249e84 hw/xfree86/Xorg
---
doc/Xserver-spec.xml | 2 +-
glx/glxbyteorder.h | 21 ------------
include/misc.h | 97 ++++++++++++++++++----------------------------------
os/io.c | 4 +--
4 files changed, 37 insertions(+), 87 deletions(-)
diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml
index 7867544e48a9..3dde65178b7f 100644
--- a/doc/Xserver-spec.xml
+++ b/doc/Xserver-spec.xml
@@ -600,7 +600,7 @@ are: REQUEST, REQUEST_SIZE_MATCH, REQUEST_AT_LEAST_SIZE,
REQUEST_FIXED_SIZE, LEGAL_NEW_RESOURCE, and
VALIDATE_DRAWABLE_AND_GC. Useful byte swapping macros can be found
in Xserver/include/dix.h: WriteReplyToClient and WriteSwappedDataToClient; and
-in Xserver/include/misc.h: lswapl, lswaps, LengthRestB, LengthRestS,
+in Xserver/include/misc.h: bswap_64, bswap_32, bswap_16, LengthRestB, LengthRestS,
LengthRestL, SwapRestS, SwapRestL, swapl, swaps, cpswapl, and cpswaps.</para>
</section>
</section>
diff --git a/glx/glxbyteorder.h b/glx/glxbyteorder.h
index 5e94e8626e66..8f0cd8a4b0d7 100644
--- a/glx/glxbyteorder.h
+++ b/glx/glxbyteorder.h
@@ -37,25 +37,4 @@
#include "misc.h"
-static inline uint16_t
-bswap_16(uint16_t val)
-{
- swap_uint16(&val);
- return val;
-}
-
-static inline uint32_t
-bswap_32(uint32_t val)
-{
- swap_uint32(&val);
- return val;
-}
-
-static inline uint64_t
-bswap_64(uint64_t val)
-{
- swap_uint64(&val);
- return val;
-}
-
#endif /* !defined(__GLXBYTEORDER_H__) */
diff --git a/include/misc.h b/include/misc.h
index 01747fd38339..a75eb617c642 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -128,21 +128,6 @@ typedef struct _xReq *xReqPtr;
#define USE_BACKGROUND_PIXEL 3
#define USE_BORDER_PIXEL 3
-/* byte swap a 32-bit literal */
-static inline uint32_t
-lswapl(uint32_t x)
-{
- return ((x & 0xff) << 24) |
- ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x >> 24) & 0xff);
-}
-
-/* byte swap a 16-bit literal */
-static inline uint16_t
-lswaps(uint16_t x)
-{
- return (uint16_t)((x & 0xff) << 8) | ((x >> 8) & 0xff);
-}
-
#undef min
#undef max
@@ -311,88 +296,74 @@ __builtin_constant_p(int x)
}
#endif
-/* byte swap a 64-bit value */
-static inline void
-swap_uint64(uint64_t *x)
+static inline uint64_t
+bswap_64(uint64_t x)
{
- char n;
-
- n = ((char *) x)[0];
- ((char *) x)[0] = ((char *) x)[7];
- ((char *) x)[7] = n;
-
- n = ((char *) x)[1];
- ((char *) x)[1] = ((char *) x)[6];
- ((char *) x)[6] = n;
-
- n = ((char *) x)[2];
- ((char *) x)[2] = ((char *) x)[5];
- ((char *) x)[5] = n;
-
- n = ((char *) x)[3];
- ((char *) x)[3] = ((char *) x)[4];
- ((char *) x)[4] = n;
+ return (((x & 0xFF00000000000000ull) >> 56) |
+ ((x & 0x00FF000000000000ull) >> 40) |
+ ((x & 0x0000FF0000000000ull) >> 24) |
+ ((x & 0x000000FF00000000ull) >> 8) |
+ ((x & 0x00000000FF000000ull) << 8) |
+ ((x & 0x0000000000FF0000ull) << 24) |
+ ((x & 0x000000000000FF00ull) << 40) |
+ ((x & 0x00000000000000FFull) << 56));
}
#define swapll(x) do { \
+ uint64_t temp; \
if (sizeof(*(x)) != 8) \
wrong_size(); \
- swap_uint64((uint64_t *)(x)); \
+ memcpy(&temp, x, 8); \
+ temp = bswap_64(temp); \
+ memcpy(x, &temp, 8); \
} while (0)
-/* byte swap a 32-bit value */
-static inline void
-swap_uint32(uint32_t * x)
+static inline uint32_t
+bswap_32(uint32_t x)
{
- char n = ((char *) x)[0];
-
- ((char *) x)[0] = ((char *) x)[3];
- ((char *) x)[3] = n;
- n = ((char *) x)[1];
- ((char *) x)[1] = ((char *) x)[2];
- ((char *) x)[2] = n;
+ return (((x & 0xFF000000) >> 24) |
+ ((x & 0x00FF0000) >> 8) |
+ ((x & 0x0000FF00) << 8) |
+ ((x & 0x000000FF) << 24));
}
#define swapl(x) do { \
+ uint32_t temp; \
if (sizeof(*(x)) != 4) \
wrong_size(); \
- if (__builtin_constant_p((uintptr_t)(x) & 3) && ((uintptr_t)(x) & 3) == 0) \
- *(x) = lswapl(*(x)); \
- else \
- swap_uint32((uint32_t *)(x)); \
+ memcpy(&temp, x, 4); \
+ temp = bswap_32(temp); \
+ memcpy(x, &temp, 4); \
} while (0)
-/* byte swap a 16-bit value */
-static inline void
-swap_uint16(uint16_t * x)
+static inline uint16_t
+bswap_16(uint16_t x)
{
- char n = ((char *) x)[0];
-
- ((char *) x)[0] = ((char *) x)[1];
- ((char *) x)[1] = n;
+ return (((x & 0xFF00) >> 8) |
+ ((x & 0x00FF) << 8));
}
#define swaps(x) do { \
+ uint16_t temp; \
if (sizeof(*(x)) != 2) \
wrong_size(); \
- if (__builtin_constant_p((uintptr_t)(x) & 1) && ((uintptr_t)(x) & 1) == 0) \
- *(x) = lswaps(*(x)); \
- else \
- swap_uint16((uint16_t *)(x)); \
+ memcpy(&temp, x, 2); \
+ temp = bswap_16(temp); \
+ memcpy(x, &temp, 2); \
} while (0)
/* copy 32-bit value from src to dst byteswapping on the way */
#define cpswapl(src, dst) do { \
if (sizeof((src)) != 4 || sizeof((dst)) != 4) \
wrong_size(); \
- (dst) = lswapl((src)); \
+ (dst) = bswap_32((src)); \
} while (0)
/* copy short from src to dst byteswapping on the way */
#define cpswaps(src, dst) do { \
if (sizeof((src)) != 2 || sizeof((dst)) != 2) \
wrong_size(); \
- (dst) = lswaps((src)); \
+ (dst) = bswap_16((src)); \
} while (0)
extern _X_EXPORT void SwapLongs(CARD32 *list, unsigned long count);
diff --git a/os/io.c b/os/io.c
index 8aa51a1070f1..46c7e23715ff 100644
--- a/os/io.c
+++ b/os/io.c
@@ -108,12 +108,12 @@ static ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr) NULL;
static OsCommPtr AvailableInput = (OsCommPtr) NULL;
#define get_req_len(req,cli) ((cli)->swapped ? \
- lswaps((req)->length) : (req)->length)
+ bswap_16((req)->length) : (req)->length)
#include <X11/extensions/bigreqsproto.h>
#define get_big_req_len(req,cli) ((cli)->swapped ? \
- lswapl(((xBigReq *)(req))->length) : \
+ bswap_32(((xBigReq *)(req))->length) : \
((xBigReq *)(req))->length)
#define BUFSIZE 16384
--
2.11.0
More information about the xorg-devel
mailing list