endianness.h (3783B)
1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr) 2 * 3 * The RSys library is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published 5 * by the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * The RSys library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #ifndef ENDIANNESS_H 17 #define ENDIANNESS_H 18 19 #include "rsys.h" 20 21 #if defined(COMPILER_GCC) 22 #define BYTE_ORDER __BYTE_ORDER__ 23 #define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ 24 #define BIG_ENDIAN __ORDER_BIG_ENDIAN__ 25 #include <byteswap.h> 26 #else 27 #error "Undefined byte ordering macros" 28 #endif 29 30 static FINLINE uint16_t 31 byte_swap_16(const uint16_t ui) 32 { 33 union { uint16_t ui; uint8_t bytes[2]; } ucast; 34 ucast.ui = ui; 35 SWAP(uint8_t, ucast.bytes[0], ucast.bytes[1]); 36 return ucast.ui; 37 } 38 39 static FINLINE uint32_t 40 byte_swap_32(const uint32_t ui) 41 { 42 union { uint32_t ui; uint8_t bytes[4]; } ucast; 43 ucast.ui = ui; 44 SWAP(uint8_t, ucast.bytes[0], ucast.bytes[3]); 45 SWAP(uint8_t, ucast.bytes[1], ucast.bytes[2]); 46 return ucast.ui; 47 } 48 static FINLINE uint64_t 49 byte_swap_64(const uint64_t ui) 50 { 51 union { uint64_t ui; uint8_t bytes[8]; } ucast; 52 ucast.ui = ui; 53 SWAP(uint8_t, ucast.bytes[0], ucast.bytes[7]); 54 SWAP(uint8_t, ucast.bytes[1], ucast.bytes[6]); 55 SWAP(uint8_t, ucast.bytes[2], ucast.bytes[5]); 56 SWAP(uint8_t, ucast.bytes[3], ucast.bytes[4]); 57 return ucast.ui; 58 } 59 60 static FINLINE uint16_t 61 little_endian_16(const uint16_t ui) 62 { 63 union { uint16_t ui; uint8_t bytes[2]; } ucast; 64 ucast.ui = ui; 65 return ((uint16_t)ucast.bytes[0] << 0) 66 | ((uint16_t)ucast.bytes[1] << 8); 67 } 68 69 static FINLINE uint32_t 70 little_endian_32(const uint32_t ui) 71 { 72 union { uint32_t ui; uint8_t bytes[4]; } ucast; 73 ucast.ui = ui; 74 return ((uint32_t)ucast.bytes[0] << 0) 75 | ((uint32_t)ucast.bytes[1] << 8) 76 | ((uint32_t)ucast.bytes[2] << 16) 77 | ((uint32_t)ucast.bytes[3] << 24); 78 } 79 80 static FINLINE uint64_t 81 little_endian_64(const uint64_t ui) 82 { 83 union { uint64_t ui; uint8_t bytes[8]; } ucast; 84 ucast.ui = ui; 85 return ((uint64_t)ucast.bytes[0] << 0) 86 | ((uint64_t)ucast.bytes[1] << 8) 87 | ((uint64_t)ucast.bytes[2] << 16) 88 | ((uint64_t)ucast.bytes[3] << 24) 89 | ((uint64_t)ucast.bytes[4] << 32) 90 | ((uint64_t)ucast.bytes[5] << 40) 91 | ((uint64_t)ucast.bytes[6] << 48) 92 | ((uint64_t)ucast.bytes[7] << 56); 93 } 94 95 static FINLINE uint16_t 96 big_endian_16(const uint16_t ui) 97 { 98 union { uint16_t ui; uint8_t bytes[2]; } ucast; 99 ucast.ui = ui; 100 return ((uint16_t)ucast.bytes[0] << 8) 101 | ((uint16_t)ucast.bytes[1] << 0); 102 } 103 104 static FINLINE uint32_t 105 big_endian_32(const uint32_t ui) 106 { 107 union { uint32_t ui; uint8_t bytes[2]; } ucast; 108 ucast.ui = ui; 109 return ((uint32_t)ucast.bytes[0] << 24) 110 | ((uint32_t)ucast.bytes[1] << 16) 111 | ((uint32_t)ucast.bytes[2] << 8) 112 | ((uint32_t)ucast.bytes[3] << 0); 113 } 114 115 static FINLINE uint64_t 116 big_endian_64(const uint64_t ui) 117 { 118 union { uint64_t ui; uint8_t bytes[8]; } ucast; 119 ucast.ui = ui; 120 return ((uint64_t)ucast.bytes[0] << 56) 121 | ((uint64_t)ucast.bytes[1] << 48) 122 | ((uint64_t)ucast.bytes[2] << 40) 123 | ((uint64_t)ucast.bytes[3] << 32) 124 | ((uint64_t)ucast.bytes[4] << 24) 125 | ((uint64_t)ucast.bytes[5] << 16) 126 | ((uint64_t)ucast.bytes[6] << 8) 127 | ((uint64_t)ucast.bytes[7] << 0); 128 } 129 130 #endif /* ENDIANNESS_H */