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 127 128 129 130 131 132 133 134 135 136
|
/* BYTESWAP.H Little <> Big Endian conversion - Jan Jaeger */
/* 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 */
// $Id: hbyteswp.h 5039 2009-01-08 01:59:20Z jmaynard $
//
// $Log$
// Revision 1.11 2009/01/07 18:00:13 jmaynard
// Added x86_64 assembler swap assists for those systems that don't have
// byteswap.h in the library.
//
// Revision 1.10 2006/12/08 09:43:21 jj
// Add CVS message log
//
#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
|