… | |
… | |
355 | #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b) |
355 | #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b) |
356 | #define ECB_STRINGIFY_(a) # a |
356 | #define ECB_STRINGIFY_(a) # a |
357 | #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a) |
357 | #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a) |
358 | #define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr)) |
358 | #define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr)) |
359 | |
359 | |
|
|
360 | /* This marks larger functions that do not neccessarily need to be inlined */ |
|
|
361 | /* The idea is to possibly compile the header twice, */ |
|
|
362 | /* once exposing only the declarations, another time to define external functions */ |
|
|
363 | /* TODO: possibly static would be best for these at the moment? */ |
360 | #define ecb_function_ ecb_inline |
364 | #define ecb_function_ ecb_inline |
361 | |
365 | |
362 | #if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8) |
366 | #if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8) |
363 | #define ecb_attribute(attrlist) __attribute__ (attrlist) |
367 | #define ecb_attribute(attrlist) __attribute__ (attrlist) |
364 | #else |
368 | #else |
… | |
… | |
464 | #define ecb_ld64(x) (ecb_clz64 (x) ^ 63) |
468 | #define ecb_ld64(x) (ecb_clz64 (x) ^ 63) |
465 | #define ecb_popcount32(x) __builtin_popcount (x) |
469 | #define ecb_popcount32(x) __builtin_popcount (x) |
466 | /* ecb_popcount64 is more difficult, see below */ |
470 | /* ecb_popcount64 is more difficult, see below */ |
467 | #else |
471 | #else |
468 | ecb_function_ ecb_const int ecb_ctz32 (uint32_t x); |
472 | ecb_function_ ecb_const int ecb_ctz32 (uint32_t x); |
469 | ecb_function_ ecb_const int |
473 | ecb_function_ ecb_const int ecb_ctz32 (uint32_t x) |
470 | ecb_ctz32 (uint32_t x) |
|
|
471 | { |
474 | { |
472 | #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) |
475 | #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) |
473 | unsigned long r; |
476 | unsigned long r; |
474 | _BitScanForward (&r, x); |
477 | _BitScanForward (&r, x); |
475 | return (int)r; |
478 | return (int)r; |
… | |
… | |
514 | return r; |
517 | return r; |
515 | #endif |
518 | #endif |
516 | } |
519 | } |
517 | |
520 | |
518 | ecb_function_ ecb_const int ecb_ctz64 (uint64_t x); |
521 | ecb_function_ ecb_const int ecb_ctz64 (uint64_t x); |
519 | ecb_function_ ecb_const int |
522 | ecb_function_ ecb_const int ecb_ctz64 (uint64_t x) |
520 | ecb_ctz64 (uint64_t x) |
|
|
521 | { |
523 | { |
522 | #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) |
524 | #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) |
523 | unsigned long r; |
525 | unsigned long r; |
524 | _BitScanForward64 (&r, x); |
526 | _BitScanForward64 (&r, x); |
525 | return (int)r; |
527 | return (int)r; |
… | |
… | |
528 | return ecb_ctz32 (x >> shift) + shift; |
530 | return ecb_ctz32 (x >> shift) + shift; |
529 | #endif |
531 | #endif |
530 | } |
532 | } |
531 | |
533 | |
532 | ecb_function_ ecb_const int ecb_clz32 (uint32_t x); |
534 | ecb_function_ ecb_const int ecb_clz32 (uint32_t x); |
533 | ecb_function_ ecb_const int |
535 | ecb_function_ ecb_const int ecb_clz32 (uint32_t x) |
534 | ecb_clz32 (uint32_t x) |
|
|
535 | { |
536 | { |
536 | #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) |
537 | #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) |
537 | unsigned long r; |
538 | unsigned long r; |
538 | _BitScanReverse (&r, x); |
539 | _BitScanReverse (&r, x); |
539 | return (int)r; |
540 | return (int)r; |
… | |
… | |
564 | return table [x >> 26]; |
565 | return table [x >> 26]; |
565 | #endif |
566 | #endif |
566 | } |
567 | } |
567 | |
568 | |
568 | ecb_function_ ecb_const int ecb_clz64 (uint64_t x); |
569 | ecb_function_ ecb_const int ecb_clz64 (uint64_t x); |
569 | ecb_function_ ecb_const int |
570 | ecb_function_ ecb_const int ecb_clz64 (uint64_t x) |
570 | ecb_clz64 (uint64_t x) |
|
|
571 | { |
571 | { |
572 | #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) |
572 | #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) |
573 | unsigned long r; |
573 | unsigned long r; |
574 | _BitScanReverse64 (&r, x); |
574 | _BitScanReverse64 (&r, x); |
575 | return (int)r; |
575 | return (int)r; |
… | |
… | |
663 | |
663 | |
664 | return x; |
664 | return x; |
665 | } |
665 | } |
666 | |
666 | |
667 | ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); |
667 | ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); |
668 | ecb_function_ ecb_const int |
668 | ecb_function_ ecb_const int ecb_popcount64 (uint64_t x) |
669 | ecb_popcount64 (uint64_t x) |
|
|
670 | { |
669 | { |
671 | /* popcount64 is only available on 64 bit cpus as gcc builtin. */ |
670 | /* popcount64 is only available on 64 bit cpus as gcc builtin. */ |
672 | /* also, gcc/clang make this surprisingly difficult to use */ |
671 | /* also, gcc/clang make this surprisingly difficult to use */ |
673 | #if (__SIZEOF_LONG__ == 8) && (ECB_GCC_VERSION(3,4) || ECB_CLANG_BUILTIN (__builtin_popcountl)) |
672 | #if (__SIZEOF_LONG__ == 8) && (ECB_GCC_VERSION(3,4) || ECB_CLANG_BUILTIN (__builtin_popcountl)) |
674 | return __builtin_popcountl (x); |
673 | return __builtin_popcountl (x); |
… | |
… | |
746 | #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x))) |
745 | #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x))) |
747 | #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x))) |
746 | #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x))) |
748 | #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x))) |
747 | #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x))) |
749 | #else |
748 | #else |
750 | ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x); |
749 | ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x); |
751 | ecb_function_ ecb_const uint16_t |
750 | ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x) |
752 | ecb_bswap16 (uint16_t x) |
|
|
753 | { |
751 | { |
754 | return ecb_rotl16 (x, 8); |
752 | return ecb_rotl16 (x, 8); |
755 | } |
753 | } |
756 | |
754 | |
757 | ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x); |
755 | ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x); |
758 | ecb_function_ ecb_const uint32_t |
756 | ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x) |
759 | ecb_bswap32 (uint32_t x) |
|
|
760 | { |
757 | { |
761 | return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16); |
758 | return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16); |
762 | } |
759 | } |
763 | |
760 | |
764 | ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x); |
761 | ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x); |
765 | ecb_function_ ecb_const uint64_t |
762 | ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x) |
766 | ecb_bswap64 (uint64_t x) |
|
|
767 | { |
763 | { |
768 | return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32); |
764 | return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32); |
769 | } |
765 | } |
770 | #endif |
766 | #endif |
771 | |
767 | |
… | |
… | |
779 | |
775 | |
780 | /* try to tell the compiler that some condition is definitely true */ |
776 | /* try to tell the compiler that some condition is definitely true */ |
781 | #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 |
777 | #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 |
782 | |
778 | |
783 | ecb_inline ecb_const uint32_t ecb_byteorder_helper (void); |
779 | ecb_inline ecb_const uint32_t ecb_byteorder_helper (void); |
784 | ecb_inline ecb_const uint32_t |
780 | ecb_inline ecb_const uint32_t ecb_byteorder_helper (void) |
785 | ecb_byteorder_helper (void) |
|
|
786 | { |
781 | { |
787 | /* the union code still generates code under pressure in gcc, */ |
782 | /* the union code still generates code under pressure in gcc, */ |
788 | /* but less than using pointers, and always seems to */ |
783 | /* but less than using pointers, and always seems to */ |
789 | /* successfully return a constant. */ |
784 | /* successfully return a constant. */ |
790 | /* the reason why we have this horrible preprocessor mess */ |
785 | /* the reason why we have this horrible preprocessor mess */ |
… | |
… | |
961 | #endif |
956 | #endif |
962 | |
957 | |
963 | /*****************************************************************************/ |
958 | /*****************************************************************************/ |
964 | /* gray code */ |
959 | /* gray code */ |
965 | |
960 | |
966 | ecb_function_ uint_fast8_t ecb_gray8_encode (uint_fast8_t b) { return b ^ (b >> 1); } |
961 | ecb_inline uint_fast8_t ecb_gray_encode8 (uint_fast8_t b) { return b ^ (b >> 1); } |
967 | ecb_function_ uint_fast16_t ecb_gray16_encode (uint_fast16_t b) { return b ^ (b >> 1); } |
962 | ecb_inline uint_fast16_t ecb_gray_encode16 (uint_fast16_t b) { return b ^ (b >> 1); } |
968 | ecb_function_ uint_fast32_t ecb_gray32_encode (uint_fast32_t b) { return b ^ (b >> 1); } |
963 | ecb_inline uint_fast32_t ecb_gray_encode32 (uint_fast32_t b) { return b ^ (b >> 1); } |
969 | ecb_function_ uint_fast64_t ecb_gray64_encode (uint_fast64_t b) { return b ^ (b >> 1); } |
964 | ecb_inline uint_fast64_t ecb_gray_encode64 (uint_fast64_t b) { return b ^ (b >> 1); } |
970 | |
965 | |
|
|
966 | ecb_function_ uint8_t ecb_gray_decode8 (uint8_t g); |
971 | ecb_function_ uint8_t ecb_gray8_decode (uint8_t g) |
967 | ecb_function_ uint8_t ecb_gray_decode8 (uint8_t g) |
972 | { |
968 | { |
973 | g ^= g >> 1; |
969 | g ^= g >> 1; |
974 | g ^= g >> 2; |
970 | g ^= g >> 2; |
975 | g ^= g >> 4; |
971 | g ^= g >> 4; |
976 | |
972 | |
977 | return g; |
973 | return g; |
978 | } |
974 | } |
979 | |
975 | |
|
|
976 | ecb_function_ uint16_t ecb_gray_decode16 (uint16_t g); |
980 | ecb_function_ uint16_t ecb_gray16_decode (uint16_t g) |
977 | ecb_function_ uint16_t ecb_gray_decode16 (uint16_t g) |
981 | { |
978 | { |
982 | g ^= g >> 1; |
979 | g ^= g >> 1; |
983 | g ^= g >> 2; |
980 | g ^= g >> 2; |
984 | g ^= g >> 4; |
981 | g ^= g >> 4; |
985 | g ^= g >> 8; |
982 | g ^= g >> 8; |
986 | |
983 | |
987 | return g; |
984 | return g; |
988 | } |
985 | } |
989 | |
986 | |
|
|
987 | ecb_function_ uint32_t ecb_gray_decode32 (uint32_t g); |
990 | ecb_function_ uint32_t ecb_gray32_decode (uint32_t g) |
988 | ecb_function_ uint32_t ecb_gray_decode32 (uint32_t g) |
991 | { |
989 | { |
992 | g ^= g >> 1; |
990 | g ^= g >> 1; |
993 | g ^= g >> 2; |
991 | g ^= g >> 2; |
994 | g ^= g >> 4; |
992 | g ^= g >> 4; |
995 | g ^= g >> 8; |
993 | g ^= g >> 8; |
996 | g ^= g >> 16; |
994 | g ^= g >> 16; |
997 | |
995 | |
998 | return g; |
996 | return g; |
999 | } |
997 | } |
1000 | |
998 | |
|
|
999 | ecb_function_ uint64_t ecb_gray_decode64 (uint64_t g); |
1001 | ecb_function_ uint64_t ecb_gray64_decode (uint64_t g) |
1000 | ecb_function_ uint64_t ecb_gray_decode64 (uint64_t g) |
1002 | { |
1001 | { |
1003 | g ^= g >> 1; |
1002 | g ^= g >> 1; |
1004 | g ^= g >> 2; |
1003 | g ^= g >> 2; |
1005 | g ^= g >> 4; |
1004 | g ^= g >> 4; |
1006 | g ^= g >> 8; |
1005 | g ^= g >> 8; |
… | |
… | |
1010 | return g; |
1009 | return g; |
1011 | } |
1010 | } |
1012 | |
1011 | |
1013 | #if ECB_CPP |
1012 | #if ECB_CPP |
1014 | |
1013 | |
1015 | ecb_function_ uint8_t ecb_gray_encode (uint8_t b) { return ecb_gray8_encode (b); } |
1014 | ecb_inline uint8_t ecb_gray_encode (uint8_t b) { return ecb_gray_encode8 (b); } |
1016 | ecb_function_ uint16_t ecb_gray_encode (uint16_t b) { return ecb_gray16_encode (b); } |
1015 | ecb_inline uint16_t ecb_gray_encode (uint16_t b) { return ecb_gray_encode16 (b); } |
1017 | ecb_function_ uint32_t ecb_gray_encode (uint32_t b) { return ecb_gray32_encode (b); } |
1016 | ecb_inline uint32_t ecb_gray_encode (uint32_t b) { return ecb_gray_encode32 (b); } |
1018 | ecb_function_ uint64_t ecb_gray_encode (uint64_t b) { return ecb_gray64_encode (b); } |
1017 | ecb_inline uint64_t ecb_gray_encode (uint64_t b) { return ecb_gray_encode64 (b); } |
1019 | |
1018 | |
1020 | ecb_function_ uint8_t ecb_gray_decode (uint8_t g) { return ecb_gray8_decode (g); } |
1019 | ecb_inline uint8_t ecb_gray_decode (uint8_t g) { return ecb_gray_decode8 (g); } |
1021 | ecb_function_ uint16_t ecb_gray_decode (uint16_t g) { return ecb_gray16_decode (g); } |
1020 | ecb_inline uint16_t ecb_gray_decode (uint16_t g) { return ecb_gray_decode16 (g); } |
1022 | ecb_function_ uint32_t ecb_gray_decode (uint32_t g) { return ecb_gray32_decode (g); } |
1021 | ecb_inline uint32_t ecb_gray_decode (uint32_t g) { return ecb_gray_decode32 (g); } |
1023 | ecb_function_ uint64_t ecb_gray_decode (uint64_t g) { return ecb_gray64_decode (g); } |
1022 | ecb_inline uint64_t ecb_gray_decode (uint64_t g) { return ecb_gray_decode64 (g); } |
1024 | |
1023 | |
1025 | #endif |
1024 | #endif |
1026 | |
1025 | |
1027 | /*****************************************************************************/ |
1026 | /*****************************************************************************/ |
1028 | /* 2d hilbert curves */ |
1027 | /* 2d hilbert curves */ |
1029 | |
1028 | |
1030 | /* algorithm from the book Hacker's Delight, modified to not */ |
1029 | /* algorithm from the book Hacker's Delight, modified to not */ |
1031 | /* run into undefined behaviour for n==16 */ |
1030 | /* run into undefined behaviour for n==16 */ |
1032 | static uint32_t |
1031 | static uint32_t ecb_hilbert2d_index_to_coord32 (int n, uint32_t s); |
1033 | ecb_hilbert2d_index_to_coord32 (int n, uint32_t s) |
1032 | static uint32_t ecb_hilbert2d_index_to_coord32 (int n, uint32_t s) |
1034 | { |
1033 | { |
1035 | uint32_t comp, swap, cs, t, sr; |
1034 | uint32_t comp, swap, cs, t, sr; |
1036 | |
1035 | |
1037 | /* pad s on the left (unused) bits with 01 (no change groups) */ |
1036 | /* pad s on the left (unused) bits with 01 (no change groups) */ |
1038 | s |= 0x55555555U << n << n; |
1037 | s |= 0x55555555U << n << n; |
… | |
… | |
1072 | /* now s contains two 16-bit coordinates */ |
1071 | /* now s contains two 16-bit coordinates */ |
1073 | return s; |
1072 | return s; |
1074 | } |
1073 | } |
1075 | |
1074 | |
1076 | /* 64 bit, a straightforward extension to the 32 bit case */ |
1075 | /* 64 bit, a straightforward extension to the 32 bit case */ |
1077 | static uint64_t |
1076 | static uint64_t ecb_hilbert2d_index_to_coord64 (int n, uint64_t s); |
1078 | ecb_hilbert2d_index_to_coord64 (int n, uint64_t s) |
1077 | static uint64_t ecb_hilbert2d_index_to_coord64 (int n, uint64_t s) |
1079 | { |
1078 | { |
1080 | uint64_t comp, swap, cs, t, sr; |
1079 | uint64_t comp, swap, cs, t, sr; |
1081 | |
1080 | |
1082 | /* pad s on the left (unused) bits with 01 (no change groups) */ |
1081 | /* pad s on the left (unused) bits with 01 (no change groups) */ |
1083 | s |= 0x5555555555555555U << n << n; |
1082 | s |= 0x5555555555555555U << n << n; |
… | |
… | |
1121 | } |
1120 | } |
1122 | |
1121 | |
1123 | /* algorithm from the book Hacker's Delight, but a similar algorithm*/ |
1122 | /* algorithm from the book Hacker's Delight, but a similar algorithm*/ |
1124 | /* is given in https://doi.org/10.1002/spe.4380160103 */ |
1123 | /* is given in https://doi.org/10.1002/spe.4380160103 */ |
1125 | /* this has been slightly improved over the original version */ |
1124 | /* this has been slightly improved over the original version */ |
1126 | ecb_function_ uint32_t |
1125 | ecb_function_ uint32_t ecb_hilbert2d_coord_to_index32 (int n, uint32_t xy); |
1127 | ecb_hilbert2d_coord_to_index32 (int n, uint32_t xy) |
1126 | ecb_function_ uint32_t ecb_hilbert2d_coord_to_index32 (int n, uint32_t xy) |
1128 | { |
1127 | { |
1129 | uint32_t row; |
1128 | uint32_t row; |
1130 | uint32_t state = 0; |
1129 | uint32_t state = 0; |
1131 | uint32_t s = 0; |
1130 | uint32_t s = 0; |
1132 | |
1131 | |
… | |
… | |
1146 | |
1145 | |
1147 | return s; |
1146 | return s; |
1148 | } |
1147 | } |
1149 | |
1148 | |
1150 | /* 64 bit, essentially the same as 32 bit */ |
1149 | /* 64 bit, essentially the same as 32 bit */ |
1151 | ecb_function_ uint64_t |
1150 | ecb_function_ uint64_t ecb_hilbert2d_coord_to_index64 (int n, uint64_t xy); |
1152 | ecb_hilbert2d_coord_to_index64 (int n, uint64_t xy) |
1151 | ecb_function_ uint64_t ecb_hilbert2d_coord_to_index64 (int n, uint64_t xy) |
1153 | { |
1152 | { |
1154 | uint32_t row; |
1153 | uint32_t row; |
1155 | uint32_t state = 0; |
1154 | uint32_t state = 0; |
1156 | uint64_t s = 0; |
1155 | uint64_t s = 0; |
1157 | |
1156 | |
… | |
… | |
1214 | |
1213 | |
1215 | /*****************************************************************************/ |
1214 | /*****************************************************************************/ |
1216 | /* IEEE 754-2008 half float conversions */ |
1215 | /* IEEE 754-2008 half float conversions */ |
1217 | |
1216 | |
1218 | ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x); |
1217 | ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x); |
1219 | ecb_function_ ecb_const uint32_t |
1218 | ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x) |
1220 | ecb_binary16_to_binary32 (uint32_t x) |
|
|
1221 | { |
1219 | { |
1222 | unsigned int s = (x & 0x8000) << (31 - 15); |
1220 | unsigned int s = (x & 0x8000) << (31 - 15); |
1223 | int e = (x >> 10) & 0x001f; |
1221 | int e = (x >> 10) & 0x001f; |
1224 | unsigned int m = x & 0x03ff; |
1222 | unsigned int m = x & 0x03ff; |
1225 | |
1223 | |
… | |
… | |
1246 | |
1244 | |
1247 | return s | (e << 23) | (m << (23 - 10)); |
1245 | return s | (e << 23) | (m << (23 - 10)); |
1248 | } |
1246 | } |
1249 | |
1247 | |
1250 | ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x); |
1248 | ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x); |
1251 | ecb_function_ ecb_const uint16_t |
1249 | ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x) |
1252 | ecb_binary32_to_binary16 (uint32_t x) |
|
|
1253 | { |
1250 | { |
1254 | unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */ |
1251 | unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */ |
1255 | int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */ |
1252 | int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */ |
1256 | unsigned int m = x & 0x007fffff; |
1253 | unsigned int m = x & 0x007fffff; |
1257 | |
1254 | |
… | |
… | |
1398 | #define ECB_I2A_U32_DIGITS 10 |
1395 | #define ECB_I2A_U32_DIGITS 10 |
1399 | #define ECB_I2A_I64_DIGITS 20 |
1396 | #define ECB_I2A_I64_DIGITS 20 |
1400 | #define ECB_I2A_U64_DIGITS 21 |
1397 | #define ECB_I2A_U64_DIGITS 21 |
1401 | #define ECB_I2A_MAX_DIGITS 21 |
1398 | #define ECB_I2A_MAX_DIGITS 21 |
1402 | |
1399 | |
1403 | ecb_inline char * |
|
|
1404 | ecb_i2a_u32 (char *ptr, uint32_t u) |
1400 | ecb_function_ char * ecb_i2a_u32 (char *ptr, uint32_t u) |
|
|
1401 | ecb_function_ char * ecb_i2a_u32 (char *ptr, uint32_t u) |
1405 | { |
1402 | { |
1406 | #if ECB_64BIT_NATIVE |
1403 | #if ECB_64BIT_NATIVE |
1407 | if (ecb_expect_true (u <= ECB_I2A_MAX_X10)) |
1404 | if (ecb_expect_true (u <= ECB_I2A_MAX_X10)) |
1408 | ptr = ecb_i2a_x10 (ptr, u); |
1405 | ptr = ecb_i2a_x10 (ptr, u); |
1409 | else /* x10 almost, but not fully, covers 32 bit */ |
1406 | else /* x10 almost, but not fully, covers 32 bit */ |
… | |
… | |
1439 | #endif |
1436 | #endif |
1440 | |
1437 | |
1441 | return ptr; |
1438 | return ptr; |
1442 | } |
1439 | } |
1443 | |
1440 | |
1444 | ecb_inline char * |
1441 | ecb_function_ char * ecb_i2a_i32 (char *ptr, int32_t v); |
1445 | ecb_i2a_i32 (char *ptr, int32_t v) |
1442 | ecb_function_ char * ecb_i2a_i32 (char *ptr, int32_t v) |
1446 | { |
1443 | { |
1447 | *ptr = '-'; ptr += v < 0; |
1444 | *ptr = '-'; ptr += v < 0; |
1448 | uint32_t u = v < 0 ? -(uint32_t)v : v; |
1445 | uint32_t u = v < 0 ? -(uint32_t)v : v; |
1449 | |
1446 | |
1450 | #if ECB_64BIT_NATIVE |
1447 | #if ECB_64BIT_NATIVE |
… | |
… | |
1454 | #endif |
1451 | #endif |
1455 | |
1452 | |
1456 | return ptr; |
1453 | return ptr; |
1457 | } |
1454 | } |
1458 | |
1455 | |
1459 | ecb_inline char * |
1456 | ecb_function_ char * ecb_i2a_u64 (char *ptr, uint64_t u); |
1460 | ecb_i2a_u64 (char *ptr, uint64_t u) |
1457 | ecb_function_ char * ecb_i2a_u64 (char *ptr, uint64_t u) |
1461 | { |
1458 | { |
1462 | #if ECB_64BIT_NATIVE |
1459 | #if ECB_64BIT_NATIVE |
1463 | if (ecb_expect_true (u <= ECB_I2A_MAX_X10)) |
1460 | if (ecb_expect_true (u <= ECB_I2A_MAX_X10)) |
1464 | ptr = ecb_i2a_x10 (ptr, u); |
1461 | ptr = ecb_i2a_x10 (ptr, u); |
1465 | else if (ecb_expect_false (u <= ECB_I2A_MAX_X10 * 1000000000)) |
1462 | else if (ecb_expect_false (u <= ECB_I2A_MAX_X10 * 1000000000)) |
… | |
… | |
1495 | #endif |
1492 | #endif |
1496 | |
1493 | |
1497 | return ptr; |
1494 | return ptr; |
1498 | } |
1495 | } |
1499 | |
1496 | |
1500 | ecb_inline char * |
|
|
1501 | ecb_i2a_i64 (char *ptr, int64_t v) |
1497 | ecb_function_ char * ecb_i2a_i64 (char *ptr, int64_t v) |
|
|
1498 | ecb_function_ char * ecb_i2a_i64 (char *ptr, int64_t v) |
1502 | { |
1499 | { |
1503 | *ptr = '-'; ptr += v < 0; |
1500 | *ptr = '-'; ptr += v < 0; |
1504 | uint64_t u = v < 0 ? -(uint64_t)v : v; |
1501 | uint64_t u = v < 0 ? -(uint64_t)v : v; |
1505 | |
1502 | |
1506 | #if ECB_64BIT_NATIVE |
1503 | #if ECB_64BIT_NATIVE |
… | |
… | |
1583 | #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) |
1580 | #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) |
1584 | #endif |
1581 | #endif |
1585 | |
1582 | |
1586 | /* convert a float to ieee single/binary32 */ |
1583 | /* convert a float to ieee single/binary32 */ |
1587 | ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); |
1584 | ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); |
1588 | ecb_function_ ecb_const uint32_t |
1585 | ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x) |
1589 | ecb_float_to_binary32 (float x) |
|
|
1590 | { |
1586 | { |
1591 | uint32_t r; |
1587 | uint32_t r; |
1592 | |
1588 | |
1593 | #if ECB_STDFP |
1589 | #if ECB_STDFP |
1594 | memcpy (&r, &x, 4); |
1590 | memcpy (&r, &x, 4); |
… | |
… | |
1623 | return r; |
1619 | return r; |
1624 | } |
1620 | } |
1625 | |
1621 | |
1626 | /* converts an ieee single/binary32 to a float */ |
1622 | /* converts an ieee single/binary32 to a float */ |
1627 | ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x); |
1623 | ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x); |
1628 | ecb_function_ ecb_const float |
1624 | ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x) |
1629 | ecb_binary32_to_float (uint32_t x) |
|
|
1630 | { |
1625 | { |
1631 | float r; |
1626 | float r; |
1632 | |
1627 | |
1633 | #if ECB_STDFP |
1628 | #if ECB_STDFP |
1634 | memcpy (&r, &x, 4); |
1629 | memcpy (&r, &x, 4); |
… | |
… | |
1653 | return r; |
1648 | return r; |
1654 | } |
1649 | } |
1655 | |
1650 | |
1656 | /* convert a double to ieee double/binary64 */ |
1651 | /* convert a double to ieee double/binary64 */ |
1657 | ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x); |
1652 | ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x); |
1658 | ecb_function_ ecb_const uint64_t |
1653 | ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x) |
1659 | ecb_double_to_binary64 (double x) |
|
|
1660 | { |
1654 | { |
1661 | uint64_t r; |
1655 | uint64_t r; |
1662 | |
1656 | |
1663 | #if ECB_STDFP |
1657 | #if ECB_STDFP |
1664 | memcpy (&r, &x, 8); |
1658 | memcpy (&r, &x, 8); |
… | |
… | |
1693 | return r; |
1687 | return r; |
1694 | } |
1688 | } |
1695 | |
1689 | |
1696 | /* converts an ieee double/binary64 to a double */ |
1690 | /* converts an ieee double/binary64 to a double */ |
1697 | ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x); |
1691 | ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x); |
1698 | ecb_function_ ecb_const double |
1692 | ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x) |
1699 | ecb_binary64_to_double (uint64_t x) |
|
|
1700 | { |
1693 | { |
1701 | double r; |
1694 | double r; |
1702 | |
1695 | |
1703 | #if ECB_STDFP |
1696 | #if ECB_STDFP |
1704 | memcpy (&r, &x, 8); |
1697 | memcpy (&r, &x, 8); |
… | |
… | |
1723 | return r; |
1716 | return r; |
1724 | } |
1717 | } |
1725 | |
1718 | |
1726 | /* convert a float to ieee half/binary16 */ |
1719 | /* convert a float to ieee half/binary16 */ |
1727 | ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x); |
1720 | ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x); |
1728 | ecb_function_ ecb_const uint16_t |
1721 | ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x) |
1729 | ecb_float_to_binary16 (float x) |
|
|
1730 | { |
1722 | { |
1731 | return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x)); |
1723 | return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x)); |
1732 | } |
1724 | } |
1733 | |
1725 | |
1734 | /* convert an ieee half/binary16 to float */ |
1726 | /* convert an ieee half/binary16 to float */ |
1735 | ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x); |
1727 | ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x); |
1736 | ecb_function_ ecb_const float |
1728 | ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x) |
1737 | ecb_binary16_to_float (uint16_t x) |
|
|
1738 | { |
1729 | { |
1739 | return ecb_binary32_to_float (ecb_binary16_to_binary32 (x)); |
1730 | return ecb_binary32_to_float (ecb_binary16_to_binary32 (x)); |
1740 | } |
1731 | } |
1741 | |
1732 | |
1742 | #endif |
1733 | #endif |