… | |
… | |
459 | ecb_inline void ecb_unreachable (void) ecb_noreturn; |
459 | ecb_inline void ecb_unreachable (void) ecb_noreturn; |
460 | ecb_inline void ecb_unreachable (void) { } |
460 | ecb_inline void ecb_unreachable (void) { } |
461 | #endif |
461 | #endif |
462 | |
462 | |
463 | /* try to tell the compiler that some condition is definitely true */ |
463 | /* try to tell the compiler that some condition is definitely true */ |
464 | #define ecb_assume(cond) do { if (!(cond)) ecb_unreachable (); } while (0) |
464 | #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 |
465 | |
465 | |
466 | ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const; |
466 | ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const; |
467 | ecb_inline unsigned char |
467 | ecb_inline unsigned char |
468 | ecb_byteorder_helper (void) |
468 | ecb_byteorder_helper (void) |
469 | { |
469 | { |
470 | const uint32_t u = 0x11223344; |
470 | /* the union code still generates code under pressure in gcc, */ |
471 | return *(unsigned char *)&u; |
471 | /* but less than using pointers, and always seem to */ |
|
|
472 | /* successfully return a constant. */ |
|
|
473 | /* the reason why we have this horrible preprocessor mess */ |
|
|
474 | /* is to avoid it in all cases, at least on common architectures */ |
|
|
475 | /* and yes, gcc defines __BYTE_ORDER__, g++ does not */ |
|
|
476 | #if __i386 || __i386__ || _M_X86 || __amd64 || __amd64__ || _M_X64 |
|
|
477 | return 0x44; |
|
|
478 | #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
|
|
479 | return 0x44; |
|
|
480 | #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
|
|
481 | retrurn 0x11; |
|
|
482 | #else |
|
|
483 | union |
|
|
484 | { |
|
|
485 | uint32_t i; |
|
|
486 | uint8_t c; |
|
|
487 | } u = { 0x11223344 }; |
|
|
488 | return u.c; |
|
|
489 | #endif |
472 | } |
490 | } |
473 | |
491 | |
474 | ecb_inline ecb_bool ecb_big_endian (void) ecb_const; |
492 | ecb_inline ecb_bool ecb_big_endian (void) ecb_const; |
475 | ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; } |
493 | ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; } |
476 | ecb_inline ecb_bool ecb_little_endian (void) ecb_const; |
494 | ecb_inline ecb_bool ecb_little_endian (void) ecb_const; |