1 /* HBYTESWP.H (c) Copyright Jan Jaeger, 2001-2009 */ 2 /* Hercules Little <> Big Endian conversion */ 3 4 /* These definitions are only nessesary when running on older */ 5 /* versions of linux that do not have /usr/include/byteswap.h */ 6 /* compile option -DNO_ASM_BYTESWAP will expand 'C' code */ 7 /* otherwise Intel (486+) assember will be generated */ 8 9 #ifndef _BYTESWAP_H 10 #define _BYTESWAP_H 11 12 #if !defined(NO_ASM_BYTESWAP) 13 14 #include "htypes.h" // (need Hercules fixed-size data types) 15 16 #if defined( _MSVC_ ) 17 bswap_16(uint16_t x)18 static __inline uint16_t __fastcall bswap_16 ( uint16_t x ) 19 { 20 return _byteswap_ushort((x)); 21 } 22 bswap_32(uint32_t x)23 static __inline uint32_t __fastcall bswap_32 ( uint32_t x ) 24 { 25 return _byteswap_ulong((x)); 26 } 27 28 #else // !defined( _MSVC_ ) 29 30 static __inline__ uint16_t (ATTR_REGPARM(1) bswap_16)(uint16_t x) 31 { 32 #if defined(__x86_64__) 33 __asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x)); 34 #else 35 __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); 36 #endif 37 return x; 38 } 39 40 static __inline__ uint32_t (ATTR_REGPARM(1) bswap_32)(uint32_t x) 41 { 42 #if defined(__x86_64__) 43 __asm__("bswapl %0" : "=r" (x) : "0" (x)); 44 #else 45 __asm__("bswap %0" : "=r" (x) : "0" (x)); 46 #endif 47 return x; 48 } 49 50 #endif // defined( _MSVC_ ) 51 52 #else // defined(NO_ASM_BYTESWAP) 53 54 #define bswap_16(_x) \ 55 ( (((_x) & 0xFF00) >> 8) \ 56 | (((_x) & 0x00FF) << 8) ) 57 58 #define bswap_32(_x) \ 59 ( (((_x) & 0xFF000000) >> 24) \ 60 | (((_x) & 0x00FF0000) >> 8) \ 61 | (((_x) & 0x0000FF00) << 8) \ 62 | (((_x) & 0x000000FF) << 24) ) 63 64 #endif // !defined(NO_ASM_BYTESWAP) 65 66 #if defined( _MSVC_ ) 67 68 // Microsoft's Toolkit 2003 compiler (version 1300) has a known bug 69 // that causes the _byteswap_uint64 intrinsic to screw up if global 70 // otimizations are enabled. The new VStudio 8.0 compiler (version 71 // 14.00) doesn't have this problem that I am aware of. NOTE that 72 // the #pragma must be outside the function (at global scope) to 73 // prevent compiler error C2156 "pragma must be outside function". 74 75 #if ( _MSC_VER < 1400 ) 76 #pragma optimize("g",off) // (disable global optimizations) 77 #endif bswap_64(uint64_t x)78 static __inline uint64_t __fastcall bswap_64(uint64_t x) 79 { 80 return _byteswap_uint64((x)); 81 } 82 #if ( _MSC_VER < 1400 ) 83 #pragma optimize ( "", on ) 84 #endif 85 86 #else // !defined( _MSVC_ ) 87 88 #if defined(NO_ASM_BYTESWAP) 89 #define bswap_64(_x) \ 90 ( ((U64)((_x) & 0xFF00000000000000ULL) >> 56) \ 91 | ((U64)((_x) & 0x00FF000000000000ULL) >> 40) \ 92 | ((U64)((_x) & 0x0000FF0000000000ULL) >> 24) \ 93 | ((U64)((_x) & 0x000000FF00000000ULL) >> 8) \ 94 | ((U64)((_x) & 0x00000000FF000000ULL) << 8) \ 95 | ((U64)((_x) & 0x0000000000FF0000ULL) << 24) \ 96 | ((U64)((_x) & 0x000000000000FF00ULL) << 40) \ 97 | ((U64)((_x) & 0x00000000000000FFULL) << 56) ) 98 #else 99 static __inline__ uint64_t (ATTR_REGPARM(1) bswap_64)(uint64_t x) 100 { 101 #if defined(__x86_64__) 102 __asm__("bswapq %0" : "=r" (x) : "0" (x)); 103 return x; 104 #else // swap the two words after byteswapping them 105 union 106 { 107 struct 108 { 109 uint32_t high,low; 110 } words; 111 uint64_t quad; 112 } value; 113 114 value.quad=x; 115 __asm__("bswap %0" : "=r" (value.words.high) : "0" (value.words.high)); 116 __asm__("bswap %0" : "=r" (value.words.low) : "0" (value.words.low)); 117 __asm__("xchgl %0,%1" : "=r" (value.words.high), "=r" (value.words.low) : 118 "0" (value.words.high), "1" (value.words.low)); 119 return value.quad; 120 #endif // defined(__x86_64__) 121 } 122 #endif // defined(NO_ASM_BYTESWAP) 123 124 #endif // defined( _MSVC_ ) 125 126 #endif // _BYTESWAP_H 127