1 /* vim: set expandtab ts=4 sw=4: */ 2 /* 3 * You may redistribute this program and/or modify it under the terms of 4 * the GNU General Public License as published by the Free Software Foundation, 5 * either version 3 of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program. If not, see <https://www.gnu.org/licenses/>. 14 */ 15 #ifndef Endian_H 16 #define Endian_H 17 18 #include <stdint.h> 19 20 #if defined(Endian_BIG) || defined(Endian_LITTLE) 21 // fallthrough 22 #elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ 23 __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 24 #define Endian_LITTLE 25 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ 26 __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 27 #define Endian_BIG 28 #elif defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || \ 29 defined(_M_X64) || defined(__amd64) || defined(__i386__) || defined(__x86__) || \ 30 defined(__X86__) || defined(_M_IX86) || defined(__i386) || defined(_MIPSEL) || \ 31 defined(MIPSEL) 32 #define Endian_LITTLE 33 #elif defined(__SPU__) || defined(__powerpc64__) || defined(__ppc64__) || \ 34 defined(__PPC64__) || defined(_ARCH_PPC64) || defined(__powerpc__) || \ 35 defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC) || \ 36 defined(__sparcv9__) || defined(__sparcv9) || defined(__sparc_v8__) || \ 37 defined(__sparc__) || defined(__sparc) || defined(_MIPSEB) || defined(MIPSEB) 38 #define Endian_BIG 39 #else 40 #error Unable to determine byte order of target machine, please specify -DEndian_BIG=1 or \ 41 -DEndian_LITTLE=1 42 #endif 43 44 45 #if defined(Endian_LITTLE) 46 #define Endian_isBigEndian() 0 47 #elif defined(Endian_BIG) 48 #define Endian_isBigEndian() 1 49 #endif 50 51 #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 52 #define Endian_byteSwapNoCast16(x) __builtin_bswap16(x) 53 #else 54 #define Endian_byteSwapNoCast16(x) \ 55 (__extension__ ({ \ 56 uint16_t _x = (x); \ 57 _x >> 8 | _x << 8; \ 58 })) 59 #endif 60 #define Endian_byteSwapNoCast32(x) __builtin_bswap32(x) 61 #define Endian_byteSwapNoCast64(x) __builtin_bswap64(x) 62 63 // Make sure the size is right. 64 #define Endian_byteSwap16(x) ((uint16_t)Endian_byteSwapNoCast16(((uint16_t)(x)))) 65 #define Endian_byteSwap32(x) ((uint32_t)Endian_byteSwapNoCast32(((uint32_t)(x)))) 66 #define Endian_byteSwap64(x) ((uint64_t)Endian_byteSwapNoCast64(((uint64_t)(x)))) 67 68 #if defined(Endian_BIG) 69 #define Endian_hostToLittleEndian16(input) Endian_byteSwap16(input) 70 #define Endian_hostToBigEndian16(input) (input) 71 #define Endian_hostToLittleEndian32(input) Endian_byteSwap32(input) 72 #define Endian_hostToBigEndian32(input) (input) 73 #define Endian_hostToLittleEndian64(input) Endian_byteSwap64(input) 74 #define Endian_hostToBigEndian64(input) (input) 75 #elif defined(Endian_LITTLE) 76 #define Endian_hostToLittleEndian16(input) (input) 77 #define Endian_hostToBigEndian16(input) Endian_byteSwap16(input) 78 #define Endian_hostToLittleEndian32(input) (input) 79 #define Endian_hostToBigEndian32(input) Endian_byteSwap32(input) 80 #define Endian_hostToLittleEndian64(input) (input) 81 #define Endian_hostToBigEndian64(input) Endian_byteSwap64(input) 82 #endif 83 84 // looks silly but some macros want to be able to do generic swapping for any common int type. 85 #define Endian_littleEndianToHost8(x) (x) 86 #define Endian_bigEndianToHost8(x) (x) 87 #define Endian_hostToLittleEndian8(x) (x) 88 #define Endian_hostToBigEndian8(x) (x) 89 90 #define Endian_littleEndianToHost16(x) Endian_hostToLittleEndian16(x) 91 #define Endian_bigEndianToHost16(x) Endian_hostToBigEndian16(x) 92 #define Endian_littleEndianToHost32(x) Endian_hostToLittleEndian32(x) 93 #define Endian_bigEndianToHost32(x) Endian_hostToBigEndian32(x) 94 #define Endian_littleEndianToHost64(x) Endian_hostToLittleEndian64(x) 95 #define Endian_bigEndianToHost64(x) Endian_hostToBigEndian64(x) 96 97 #endif 98