50 #ifndef COMMON_ENDIAN_H 51 #define COMMON_ENDIAN_H 57 #if !defined(XOREOS_LITTLE_ENDIAN) && !defined(XOREOS_BIG_ENDIAN) 58 #error No endianness defined 61 #define SWAP_CONSTANT_64(a) \ 62 ((uint64)((((a) >> 56) & 0x000000FF) | \ 63 (((a) >> 40) & 0x0000FF00) | \ 64 (((a) >> 24) & 0x00FF0000) | \ 65 (((a) >> 8) & 0xFF000000) | \ 66 (((a) & 0xFF000000) << 8) | \ 67 (((a) & 0x00FF0000) << 24) | \ 68 (((a) & 0x0000FF00) << 40) | \ 69 (((a) & 0x000000FF) << 56) )) 71 #define SWAP_CONSTANT_32(a) \ 72 ((uint32)((((a) >> 24) & 0x00FF) | \ 73 (((a) >> 8) & 0xFF00) | \ 74 (((a) & 0xFF00) << 8) | \ 75 (((a) & 0x00FF) << 24) )) 77 #define SWAP_CONSTANT_16(a) \ 78 ((uint16)((((a) >> 8) & 0x00FF) | \ 79 (((a) << 8) & 0xFF00) )) 82 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) 85 return __builtin_bswap64(a);
89 return __builtin_bswap32(a);
93 #elif defined(_MSC_VER) && _MSC_VER >= 1300 98 return _byteswap_uint64(a);
102 return _byteswap_ulong(a);
115 | (
uint16)((low >> 8) | (low << 8)))) << 32)
117 | (
uint16)((highhigh >> 8) | (highhigh << 8));
122 return ((
uint32)(
uint16)((low >> 8) | (low << 8)) << 16)
123 | (
uint16)((high >> 8) | (high << 8));
129 return (a >> 8) | (a << 8);
140 #define MKTAG(a0,a1,a2,a3) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24))) 143 #define MKTAG_16(a0,a1) ((uint16)((a1) | ((a0) << 8))) 148 #if !defined(XOREOS_NEED_ALIGNMENT) 151 return *(
static_cast<const uint16 *
>(ptr));
155 return *(
static_cast<const uint32 *
>(ptr));
159 return *(
static_cast<const uint64 *
>(ptr));
163 *
static_cast<uint16 *
>(ptr) = value;
167 *
static_cast<uint32 *
>(ptr) = value;
171 *
static_cast<uint64 *
>(ptr) = value;
176 #elif defined(__GNUC__) && (__GNUC__ >= 4) 179 struct Unaligned16 {
uint16 val; } __attribute__ ((__packed__));
180 return static_cast<const Unaligned16 *
>(ptr)->val;
184 struct Unaligned32 {
uint32 val; } __attribute__ ((__packed__));
185 return static_cast<const Unaligned32 *
>(ptr)->val;
189 struct Unaligned64 {
uint64 val; } __attribute__ ((__packed__));
190 return static_cast<const Unaligned64 *
>(ptr)->val;
194 struct Unaligned16 {
uint16 val; } __attribute__ ((__packed__));
195 static_cast<Unaligned16 *
>(ptr)->val = value;
199 struct Unaligned32 {
uint32 val; } __attribute__ ((__packed__));
200 static_cast<Unaligned32 *
>(ptr)->val = value;
204 struct Unaligned64 {
uint64 val; } __attribute__ ((__packed__));
205 static_cast<Unaligned64 *
>(ptr)->val = value;
211 #if defined(XOREOS_LITTLE_ENDIAN) 214 const uint8 *b =
static_cast<const uint8 *
>(ptr);
218 const uint8 *b =
static_cast<const uint8 *
>(ptr);
222 const uint8 *b =
static_cast<const uint8 *
>(ptr);
228 b[0] = (
uint8)(value >> 0);
229 b[1] = (
uint8)(value >> 8);
233 b[0] = (
uint8)(value >> 0);
234 b[1] = (
uint8)(value >> 8);
235 b[2] = (
uint8)(value >> 16);
236 b[3] = (
uint8)(value >> 24);
240 b[0] = (
uint8)(value >> 0);
241 b[1] = (
uint8)(value >> 8);
242 b[2] = (
uint8)(value >> 16);
243 b[3] = (
uint8)(value >> 24);
244 b[4] = (
uint8)(value >> 32);
245 b[5] = (
uint8)(value >> 40);
246 b[6] = (
uint8)(value >> 48);
247 b[7] = (
uint8)(value >> 56);
250 #elif defined(XOREOS_BIG_ENDIAN) 253 const uint8 *b =
static_cast<const uint8 *
>(ptr);
257 const uint8 *b =
static_cast<const uint8 *
>(ptr);
261 const uint8 *b =
static_cast<const uint8 *
>(ptr);
267 b[0] = (
uint8)(value >> 8);
268 b[1] = (
uint8)(value >> 0);
272 b[0] = (
uint8)(value >> 24);
273 b[1] = (
uint8)(value >> 16);
274 b[2] = (
uint8)(value >> 8);
275 b[3] = (
uint8)(value >> 0);
279 b[0] = (
uint8)(value >> 56);
280 b[1] = (
uint8)(value >> 48);
281 b[2] = (
uint8)(value >> 40);
282 b[3] = (
uint8)(value >> 32);
283 b[4] = (
uint8)(value >> 24);
284 b[5] = (
uint8)(value >> 16);
285 b[6] = (
uint8)(value >> 8);
286 b[7] = (
uint8)(value >> 0);
294 #if defined(XOREOS_LITTLE_ENDIAN) 296 #define READ_LE_UINT16(a) READ_UINT16(a) 297 #define READ_LE_UINT32(a) READ_UINT32(a) 298 #define READ_LE_UINT64(a) READ_UINT64(a) 300 #define WRITE_LE_UINT16(a, v) WRITE_UINT16(a, v) 301 #define WRITE_LE_UINT32(a, v) WRITE_UINT32(a, v) 302 #define WRITE_LE_UINT64(a, v) WRITE_UINT64(a, v) 304 #define FROM_LE_16(a) ((uint16)(a)) 305 #define FROM_LE_32(a) ((uint32)(a)) 306 #define FROM_LE_64(a) ((uint64)(a)) 308 #define FROM_BE_16(a) SWAP_BYTES_16(a) 309 #define FROM_BE_32(a) SWAP_BYTES_32(a) 310 #define FROM_BE_64(a) SWAP_BYTES_64(a) 312 #define TO_LE_16(a) ((uint16)(a)) 313 #define TO_LE_32(a) ((uint32)(a)) 314 #define TO_LE_64(a) ((uint64)(a)) 316 #define TO_BE_16(a) SWAP_BYTES_16(a) 317 #define TO_BE_32(a) SWAP_BYTES_32(a) 318 #define TO_BE_64(a) SWAP_BYTES_64(a) 320 #define CONSTANT_LE_16(a) ((uint16)(a)) 321 #define CONSTANT_LE_32(a) ((uint32)(a)) 322 #define CONSTANT_LE_64(a) ((uint64)(a)) 324 #define CONSTANT_BE_16(a) SWAP_CONSTANT_16(a) 325 #define CONSTANT_BE_32(a) SWAP_CONSTANT_32(a) 326 #define CONSTANT_BE_64(a) SWAP_CONSTANT_64(a) 329 #if defined(XOREOS_NEED_ALIGNMENT) && !defined(__mips__) 331 static inline uint16 READ_BE_UINT16(
const void *ptr) {
332 const uint8 *b =
static_cast<const uint8 *
>(ptr);
335 static inline uint32 READ_BE_UINT32(
const void *ptr) {
336 const uint8 *b =
static_cast<const uint8 *
>(ptr);
339 static inline uint32 READ_BE_UINT64(
const void *ptr) {
340 const uint8 *b =
static_cast<const uint8 *
>(ptr);
344 static inline void WRITE_BE_UINT16(
void *ptr,
uint16 value) {
346 b[0] = (
uint8)(value >> 8);
347 b[1] = (
uint8)(value >> 0);
349 static inline void WRITE_BE_UINT32(
void *ptr,
uint32 value) {
351 b[0] = (
uint8)(value >> 24);
352 b[1] = (
uint8)(value >> 16);
353 b[2] = (
uint8)(value >> 8);
354 b[3] = (
uint8)(value >> 0);
356 static inline void WRITE_BE_UINT64(
void *ptr,
uint64 value) {
358 b[0] = (
uint8)(value >> 56);
359 b[1] = (
uint8)(value >> 48);
360 b[2] = (
uint8)(value >> 40);
361 b[3] = (
uint8)(value >> 32);
362 b[4] = (
uint8)(value >> 24);
363 b[5] = (
uint8)(value >> 16);
364 b[6] = (
uint8)(value >> 8);
365 b[7] = (
uint8)(value >> 0);
370 static inline uint16 READ_BE_UINT16(
const void *ptr) {
373 static inline uint32 READ_BE_UINT32(
const void *ptr) {
376 static inline uint64 READ_BE_UINT64(
const void *ptr) {
379 static inline void WRITE_BE_UINT16(
void *ptr,
uint16 value) {
382 static inline void WRITE_BE_UINT32(
void *ptr,
uint32 value) {
385 static inline void WRITE_BE_UINT64(
void *ptr,
uint64 value) {
389 #endif // if defined(XOREOS_NEED_ALIGNMENT) 391 #elif defined(XOREOS_BIG_ENDIAN) 393 #define READ_BE_UINT16(a) READ_UINT16(a) 394 #define READ_BE_UINT32(a) READ_UINT32(a) 395 #define READ_BE_UINT64(a) READ_UINT64(a) 397 #define WRITE_BE_UINT16(a, v) WRITE_UINT16(a, v) 398 #define WRITE_BE_UINT32(a, v) WRITE_UINT32(a, v) 399 #define WRITE_BE_UINT64(a, v) WRITE_UINT64(a, v) 401 #define FROM_LE_16(a) SWAP_BYTES_16(a) 402 #define FROM_LE_32(a) SWAP_BYTES_32(a) 403 #define FROM_LE_64(a) SWAP_BYTES_64(a) 405 #define FROM_BE_16(a) ((uint16)(a)) 406 #define FROM_BE_32(a) ((uint32)(a)) 407 #define FROM_BE_64(a) ((uint64)(a)) 409 #define TO_LE_16(a) SWAP_BYTES_16(a) 410 #define TO_LE_32(a) SWAP_BYTES_32(a) 411 #define TO_LE_64(a) SWAP_BYTES_64(a) 413 #define TO_BE_16(a) ((uint16)(a)) 414 #define TO_BE_32(a) ((uint32)(a)) 415 #define TO_BE_64(a) ((uint64)(a)) 417 #define CONSTANT_LE_16(a) SWAP_CONSTANT_16(a) 418 #define CONSTANT_LE_32(a) SWAP_CONSTANT_32(a) 419 #define CONSTANT_LE_64(a) SWAP_CONSTANT_64(a) 421 #define CONSTANT_BE_16(a) ((uint16)(a)) 422 #define CONSTANT_BE_32(a) ((uint32)(a)) 423 #define CONSTANT_BE_64(a) ((uint64)(a)) 426 #if defined(XOREOS_NEED_ALIGNMENT) && !defined(__mips__) 428 static inline uint16 READ_LE_UINT16(
const void *ptr) {
429 const uint8 *b =
static_cast<const uint8 *
>(ptr);
432 static inline uint32 READ_LE_UINT32(
const void *ptr) {
433 const uint8 *b =
static_cast<const uint8 *
>(ptr);
436 static inline uint64 READ_LE_UINT64(
const void *ptr) {
437 const uint8 *b =
static_cast<const uint8 *
>(ptr);
441 static inline void WRITE_LE_UINT16(
void *ptr,
uint16 value) {
443 b[0] = (
uint8)(value >> 0);
444 b[1] = (
uint8)(value >> 8);
446 static inline void WRITE_LE_UINT32(
void *ptr,
uint32 value) {
448 b[0] = (
uint8)(value >> 0);
449 b[1] = (
uint8)(value >> 8);
450 b[2] = (
uint8)(value >> 16);
451 b[3] = (
uint8)(value >> 24);
453 static inline void WRITE_LE_UINT64(
void *ptr,
uint64 value) {
455 b[0] = (
uint8)(value >> 0);
456 b[1] = (
uint8)(value >> 8);
457 b[2] = (
uint8)(value >> 16);
458 b[3] = (
uint8)(value >> 24);
459 b[4] = (
uint8)(value >> 32);
460 b[5] = (
uint8)(value >> 40);
461 b[6] = (
uint8)(value >> 48);
462 b[7] = (
uint8)(value >> 56);
467 static inline uint16 READ_LE_UINT16(
const void *ptr) {
470 static inline uint32 READ_LE_UINT32(
const void *ptr) {
473 static inline uint64 READ_LE_UINT64(
const void *ptr) {
476 static inline void WRITE_LE_UINT16(
void *ptr,
uint16 value) {
479 static inline void WRITE_LE_UINT32(
void *ptr,
uint32 value) {
482 static inline void WRITE_LE_UINT64(
void *ptr,
uint64 value) {
486 #endif // if defined(XOREOS_NEED_ALIGNMENT) 488 #endif // if defined(XOREOS_LITTLE_ENDIAN) 490 #endif // COMMON_ENDIAN_H
FORCEINLINE void WRITE_UINT64(void *ptr, uint64 value)
FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value)
FORCEINLINE uint16 READ_UINT16(const void *ptr)
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value)
Low-level type definitions to handle fixed width types portably.
static uint16 SWAP_BYTES_16(const uint16 a)
static uint32 SWAP_BYTES_32(uint32 a)
static uint64 SWAP_BYTES_64(uint64 a)
Low-level detection of architecture/system properties.
FORCEINLINE uint32 READ_UINT32(const void *ptr)
FORCEINLINE uint64 READ_UINT64(const void *ptr)