diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-05-19 16:02:40 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-05-19 16:02:40 +0200 |
commit | 55b440f9c4614e6b51a250eb9cf654d23ec0f544 (patch) | |
tree | 64736d890cc5dafc5bcf701d29dd7405691ead3f | |
parent | 73b175849c1952c8bf109ad35720ccaf511cd7b9 (diff) | |
download | spice-protocol-55b440f9c4614e6b51a250eb9cf654d23ec0f544.tar.gz spice-protocol-55b440f9c4614e6b51a250eb9cf654d23ec0f544.tar.xz spice-protocol-55b440f9c4614e6b51a250eb9cf654d23ec0f544.zip |
Add byteswapping macros
-rw-r--r-- | spice/macros.h | 176 | ||||
-rw-r--r-- | spice/types.h | 1 |
2 files changed, 177 insertions, 0 deletions
diff --git a/spice/macros.h b/spice/macros.h index 72186dd..1d1934f 100644 --- a/spice/macros.h +++ b/spice/macros.h @@ -183,4 +183,180 @@ #define SPICE_UNLIKELY(expr) (expr) #endif +#ifdef _MSC_VER +#define SPICE_UINT64_CONSTANT(x) (x ## UI64) +#define SPICE_INT64_CONSTANT(x) (x ## I64) +#else +#if LONG_MAX == 2147483647L +#define SPICE_UINT64_CONSTANT(x) (x ## ULL) +#define SPICE_INT64_CONSTANT(x) (x ## LL) +#else +#define SPICE_UINT64_CONSTANT(x) (x ## UL) +#define SPICE_INT64_CONSTANT(x) (x ## L) +#endif +#endif + +/* Little/Bit endian byte swapping */ + +#define SPICE_BYTESWAP16_CONSTANT(val) ((uint16_t) ( \ + (uint16_t) ((uint16_t) (val) >> 8) | \ + (uint16_t) ((uint16_t) (val) << 8))) + +#define SPICE_BYTESWAP32_CONSTANT(val) ((uint32_t) ( \ + (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \ + (((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \ + (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \ + (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24))) + +#define SPICE_BYTESWAP64_CONSTANT(val) ((uint64_t) ( \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x00000000000000ff)) << 56) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x000000000000ff00)) << 40) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x0000000000ff0000)) << 24) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x00000000ff000000)) << 8) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x000000ff00000000)) >> 8) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x0000ff0000000000)) >> 24) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0x00ff000000000000)) >> 40) | \ + (((uint64_t) (val) & \ + (uint64_t) SPICE_UINT64_CONSTANT(0xff00000000000000)) >> 56))) + +/* Arch specific stuff for speed + */ +#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__) +# if defined (__i386__) +# define SPICE_BYTESWAP16_IA32(val) \ + (__extension__ \ + ({ register uint16_t __v, __x = ((uint16_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP16_CONSTANT (__x); \ + else \ + __asm__ ("rorw $8, %w0" \ + : "=r" (__v) \ + : "0" (__x) \ + : "cc"); \ + __v; })) +# if !defined (__i486__) && !defined (__i586__) \ + && !defined (__pentium__) && !defined (__i686__) \ + && !defined (__pentiumpro__) && !defined (__pentium4__) +# define SPICE_BYTESWAP32_IA32(val) \ + (__extension__ \ + ({ register uint32_t __v, __x = ((uint32_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP32_CONSTANT (__x); \ + else \ + __asm__ ("rorw $8, %w0\n\t" \ + "rorl $16, %0\n\t" \ + "rorw $8, %w0" \ + : "=r" (__v) \ + : "0" (__x) \ + : "cc"); \ + __v; })) +# else /* 486 and higher has bswap */ +# define SPICE_BYTESWAP32_IA32(val) \ + (__extension__ \ + ({ register uint32_t __v, __x = ((uint32_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP32_CONSTANT (__x); \ + else \ + __asm__ ("bswap %0" \ + : "=r" (__v) \ + : "0" (__x)); \ + __v; })) +# endif /* processor specific 32-bit stuff */ +# define SPICE_BYTESWAP64_IA32(val) \ + (__extension__ \ + ({ union { uint64_t __ll; \ + uint32_t __l[2]; } __w, __r; \ + __w.__ll = ((uint64_t) (val)); \ + if (__builtin_constant_p (__w.__ll)) \ + __r.__ll = SPICE_BYTESWAP64_CONSTANT (__w.__ll); \ + else \ + { \ + __r.__l[0] = SPICE_BYTESWAP32 (__w.__l[1]); \ + __r.__l[1] = SPICE_BYTESWAP32 (__w.__l[0]); \ + } \ + __r.__ll; })) + /* Possibly just use the constant version and let gcc figure it out? */ +# define SPICE_BYTESWAP16(val) (SPICE_BYTESWAP16_IA32 (val)) +# define SPICE_BYTESWAP32(val) (SPICE_BYTESWAP32_IA32 (val)) +# define SPICE_BYTESWAP64(val) (SPICE_BYTESWAP64_IA32 (val)) +# elif defined (__ia64__) +# define SPICE_BYTESWAP16_IA64(val) \ + (__extension__ \ + ({ register uint16_t __v, __x = ((uint16_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP16_CONSTANT (__x); \ + else \ + __asm__ __volatile__ ("shl %0 = %1, 48 ;;" \ + "mux1 %0 = %0, @rev ;;" \ + : "=r" (__v) \ + : "r" (__x)); \ + __v; })) +# define SPICE_BYTESWAP32_IA64(val) \ + (__extension__ \ + ({ register uint32_t __v, __x = ((uint32_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP32_CONSTANT (__x); \ + else \ + __asm__ __volatile__ ("shl %0 = %1, 32 ;;" \ + "mux1 %0 = %0, @rev ;;" \ + : "=r" (__v) \ + : "r" (__x)); \ + __v; })) +# define SPICE_BYTESWAP64_IA64(val) \ + (__extension__ \ + ({ register uint64_t __v, __x = ((uint64_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP64_CONSTANT (__x); \ + else \ + __asm__ __volatile__ ("mux1 %0 = %1, @rev ;;" \ + : "=r" (__v) \ + : "r" (__x)); \ + __v; })) +# define SPICE_BYTESWAP16(val) (SPICE_BYTESWAP16_IA64 (val)) +# define SPICE_BYTESWAP32(val) (SPICE_BYTESWAP32_IA64 (val)) +# define SPICE_BYTESWAP64(val) (SPICE_BYTESWAP64_IA64 (val)) +# elif defined (__x86_64__) +# define SPICE_BYTESWAP32_X86_64(val) \ + (__extension__ \ + ({ register uint32_t __v, __x = ((uint32_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP32_CONSTANT (__x); \ + else \ + __asm__ ("bswapl %0" \ + : "=r" (__v) \ + : "0" (__x)); \ + __v; })) +# define SPICE_BYTESWAP64_X86_64(val) \ + (__extension__ \ + ({ register uint64_t __v, __x = ((uint64_t) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = SPICE_BYTESWAP64_CONSTANT (__x); \ + else \ + __asm__ ("bswapq %0" \ + : "=r" (__v) \ + : "0" (__x)); \ + __v; })) + /* gcc seems to figure out optimal code for this on its own */ +# define SPICE_BYTESWAP16(val) (SPICE_BYTESWAP16_CONSTANT (val)) +# define SPICE_BYTESWAP32(val) (SPICE_BYTESWAP32_X86_64 (val)) +# define SPICE_BYTESWAP64(val) (SPICE_BYTESWAP64_X86_64 (val)) +# else /* generic gcc */ +# define SPICE_BYTESWAP16(val) (SPICE_BYTESWAP16_CONSTANT (val)) +# define SPICE_BYTESWAP32(val) (SPICE_BYTESWAP32_CONSTANT (val)) +# define SPICE_BYTESWAP64(val) (SPICE_BYTESWAP64_CONSTANT (val)) +# endif +#else /* generic */ +# define SPICE_BYTESWAP16(val) (SPICE_BYTESWAP16_CONSTANT (val)) +# define SPICE_BYTESWAP32(val) (SPICE_BYTESWAP32_CONSTANT (val)) +# define SPICE_BYTESWAP64(val) (SPICE_BYTESWAP64_CONSTANT (val)) +#endif /* generic */ + + #endif /* _H_SPICE_MACROS */ diff --git a/spice/types.h b/spice/types.h index c6c4d03..c8c5333 100644 --- a/spice/types.h +++ b/spice/types.h @@ -36,5 +36,6 @@ * If they are not in stdint.h on your system, * include the right one here. */ #include <stdint.h> +#include <limits.h> #endif /* _H_SPICE_TYPES */ |