1 //------------------------------------------------------------------------ 2 // EDGE Endian handling 3 //------------------------------------------------------------------------ 4 // 5 // Copyright (c) 2003-2008 The EDGE Team. 6 // 7 // This program is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU Lesser General Public License 9 // (LGPL) as published by the Free Software Foundation. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 //------------------------------------------------------------------------ 17 // 18 // Based on SDL_byteorder.h and SDL_endian.h. 19 // 20 //------------------------------------------------------------------------ 21 22 #ifndef __EPI_ENDIAN_H__ 23 #define __EPI_ENDIAN_H__ 24 25 // the two types of endianness 26 #define EPI_LIL_ENDIAN 1234 27 #define EPI_BIG_ENDIAN 4321 28 29 #if defined(__LITTLE_ENDIAN__) || \ 30 defined(__i386__) || defined(__ia64__) || defined(WIN32) || \ 31 defined(__alpha__) || defined(__alpha) || defined(__arm__) || \ 32 (defined(__mips__) && defined(__MIPSEL__)) || \ 33 defined(__SYMBIAN32__) || defined(__x86_64__) 34 #define EPI_BYTEORDER EPI_LIL_ENDIAN 35 #else 36 #define EPI_BYTEORDER EPI_BIG_ENDIAN 37 #endif 38 39 // The macros used to swap values. Try to use superfast macros on systems 40 // that support them, otherwise use C++ inline functions. 41 #ifdef LINUX 42 #ifdef __FreeBSD__ 43 #include <sys/endian.h> 44 #else 45 #include <endian.h> 46 #endif 47 #ifdef __arch__swab16 48 #define EPI_Swap16 __arch__swab16 49 #endif 50 #ifdef __arch__swab32 51 #define EPI_Swap32 __arch__swab32 52 #endif 53 #endif /* LINUX */ 54 55 #ifndef EPI_Swap16 56 #define EPI_Swap16 epi::endian_swapper_c::Swap16 57 #endif 58 59 #ifndef EPI_Swap32 60 #define EPI_Swap32 epi::endian_swapper_c::Swap32 61 #endif 62 63 64 // Byteswap item between the specified endianness to the native endianness 65 #if EPI_BYTEORDER == EPI_LIL_ENDIAN 66 #define EPI_LE_U16(X) ((u16_t)(X)) 67 #define EPI_LE_U32(X) ((u32_t)(X)) 68 #define EPI_BE_U16(X) EPI_Swap16(X) 69 #define EPI_BE_U32(X) EPI_Swap32(X) 70 #else 71 #define EPI_LE_U16(X) EPI_Swap16(X) 72 #define EPI_LE_U32(X) EPI_Swap32(X) 73 #define EPI_BE_U16(X) ((u16_t)(X)) 74 #define EPI_BE_U32(X) ((u32_t)(X)) 75 #endif 76 77 #define EPI_LE_S16(X) ((s16_t) EPI_LE_U16((u16_t) (X))) 78 #define EPI_LE_S32(X) ((s32_t) EPI_LE_U32((u32_t) (X))) 79 #define EPI_BE_S16(X) ((s16_t) EPI_BE_U16((u16_t) (X))) 80 #define EPI_BE_S32(X) ((s32_t) EPI_BE_U32((u32_t) (X))) 81 82 namespace epi 83 { 84 class endian_swapper_c 85 { 86 public: 87 static u16_t Swap16(u16_t x); 88 static u32_t Swap32(u32_t x); 89 }; 90 91 // Swap 16bit, that is, MSB and LSB byte. Swap16(u16_t x)92 inline u16_t endian_swapper_c::Swap16(u16_t x) 93 { 94 // No masking with 0xFF should be necessary. 95 return (x >> 8) | (x << 8); 96 } 97 98 // Swapping 32bit. Swap32(u32_t x)99 inline u32_t endian_swapper_c::Swap32(u32_t x) 100 { 101 return 102 (x >> 24) 103 | ((x >> 8) & 0xff00) 104 | ((x << 8) & 0xff0000) 105 | (x << 24); 106 } 107 108 } // namespace epi 109 110 #endif /* __EPI_ENDIAN_H__ */ 111 112 //--- editor settings --- 113 // vi:ts=4:sw=4:noexpandtab 114