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