… | |
… | |
626 | #endif |
626 | #endif |
627 | |
627 | |
628 | /* try to tell the compiler that some condition is definitely true */ |
628 | /* try to tell the compiler that some condition is definitely true */ |
629 | #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 |
629 | #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 |
630 | |
630 | |
631 | ecb_inline ecb_const unsigned char ecb_byteorder_helper (void); |
631 | ecb_inline ecb_const uint32_t ecb_byteorder_helper (void); |
632 | ecb_inline ecb_const unsigned char |
632 | ecb_inline ecb_const uint32_t |
633 | ecb_byteorder_helper (void) |
633 | ecb_byteorder_helper (void) |
634 | { |
634 | { |
635 | /* the union code still generates code under pressure in gcc, */ |
635 | /* the union code still generates code under pressure in gcc, */ |
636 | /* but less than using pointers, and always seems to */ |
636 | /* but less than using pointers, and always seems to */ |
637 | /* successfully return a constant. */ |
637 | /* successfully return a constant. */ |
638 | /* the reason why we have this horrible preprocessor mess */ |
638 | /* the reason why we have this horrible preprocessor mess */ |
639 | /* is to avoid it in all cases, at least on common architectures */ |
639 | /* is to avoid it in all cases, at least on common architectures */ |
640 | /* or when using a recent enough gcc version (>= 4.6) */ |
640 | /* or when using a recent enough gcc version (>= 4.6) */ |
641 | #if ((__i386 || __i386__) && !__VOS__) || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64 |
|
|
642 | return 0x44; |
|
|
643 | #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
641 | #if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ |
|
|
642 | || ((__i386 || __i386__ || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64) && !__VOS__) |
|
|
643 | #define ECB_LITTLE_ENDIAN 1 |
644 | return 0x44; |
644 | return 0x44332211; |
645 | #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
645 | #elif (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \ |
|
|
646 | || ((__AARCH64EB__ || __MIPSEB__ || __ARMEB__) && !__VOS__) |
|
|
647 | #define ECB_BIG_ENDIAN 1 |
646 | return 0x11; |
648 | return 0x11223344; |
647 | #else |
649 | #else |
648 | union |
650 | union |
649 | { |
651 | { |
|
|
652 | uint8_t c[4]; |
650 | uint32_t i; |
653 | uint32_t u; |
651 | uint8_t c; |
|
|
652 | } u = { 0x11223344 }; |
654 | } u = { 0x11, 0x22, 0x33, 0x44 }; |
653 | return u.c; |
655 | return u.u; |
654 | #endif |
656 | #endif |
655 | } |
657 | } |
656 | |
658 | |
657 | ecb_inline ecb_const ecb_bool ecb_big_endian (void); |
659 | ecb_inline ecb_const ecb_bool ecb_big_endian (void); |
658 | ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; } |
660 | ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; } |
659 | ecb_inline ecb_const ecb_bool ecb_little_endian (void); |
661 | ecb_inline ecb_const ecb_bool ecb_little_endian (void); |
660 | ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; } |
662 | ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; } |
661 | |
663 | |
662 | #if ECB_GCC_VERSION(3,0) || ECB_C99 |
664 | #if ECB_GCC_VERSION(3,0) || ECB_C99 |
663 | #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) |
665 | #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) |
664 | #else |
666 | #else |
665 | #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) |
667 | #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) |