| @@ -1,3 +1,12 @@ |
| | 1 | /* uses alias to allow building with gcc/clang */ |
| | 2 | #ifdef __TINYC__ |
| | 3 | #define BUILTIN(x) __builtin_##x |
| | 4 | #define BUILTINN(x) "__builtin_" # x |
| | 5 | #else |
| | 6 | #define BUILTIN(x) __tcc_builtin_##x |
| | 7 | #define BUILTINN(x) "__tcc_builtin_" # x |
| | 8 | #endif |
| | 9 | |
| 1 | /* ---------------------------------------------- */ | 10 | /* ---------------------------------------------- */ |
| 2 | /* This file implements: | 11 | /* This file implements: |
| 3 | * __builtin_ffs | 12 | * __builtin_ffs |
| @@ -66,59 +75,90 @@ static const unsigned char table_2_64[] = { · 62 unmodified lines |
| 66 | | 75 | |
| 67 | /* Returns one plus the index of the least significant 1-bit of x, | 76 | /* Returns one plus the index of the least significant 1-bit of x, |
| 68 | or if x is zero, returns zero. */ | 77 | or if x is zero, returns zero. */ |
| 69 | int __builtin_ffs (int x) { FFSI(x) } | 78 | int BUILTIN(ffs) (int x) { FFSI(x) } |
| | 79 | int BUILTIN(ffsll) (long long x) { FFSL(x) } |
| 70 | #if __SIZEOF_LONG__ == 4 | 80 | #if __SIZEOF_LONG__ == 4 |
| 71 | int __builtin_ffsl (long x) { FFSI(x) } | 81 | int BUILTIN(ffsl) (long x) __attribute__((alias(BUILTINN(ffs)))); |
| 72 | #else | 82 | #else |
| 73 | int __builtin_ffsl (long x) { FFSL(x) } | 83 | int BUILTIN(ffsl) (long x) __attribute__((alias(BUILTINN(ffsll)))); |
| 74 | #endif | 84 | #endif |
| 75 | int __builtin_ffsll (long long x) { FFSL(x) } | | |
| 76 | | 85 | |
| 77 | /* Returns the number of leading 0-bits in x, starting at the most significant | 86 | /* Returns the number of leading 0-bits in x, starting at the most significant |
| 78 | bit position. If x is 0, the result is undefined. */ | 87 | bit position. If x is 0, the result is undefined. */ |
| 79 | int __builtin_clz (unsigned int x) { CLZI(x) } | 88 | int BUILTIN(clz) (unsigned int x) { CLZI(x) } |
| | 89 | int BUILTIN(clzll) (unsigned long long x) { CLZL(x) } |
| 80 | #if __SIZEOF_LONG__ == 4 | 90 | #if __SIZEOF_LONG__ == 4 |
| 81 | int __builtin_clzl (unsigned long x) { CLZI(x) } | 91 | int BUILTIN(clzl) (unsigned long x) __attribute__((alias(BUILTINN(clz)))); |
| 82 | #else | 92 | #else |
| 83 | int __builtin_clzl (unsigned long x) { CLZL(x) } | 93 | int BUILTIN(clzl) (unsigned long x) __attribute__((alias(BUILTINN(clzll)))); |
| 84 | #endif | 94 | #endif |
| 85 | int __builtin_clzll (unsigned long long x) { CLZL(x) } | | |
| 86 | | 95 | |
| 87 | /* Returns the number of trailing 0-bits in x, starting at the least | 96 | /* Returns the number of trailing 0-bits in x, starting at the least |
| 88 | significant bit position. If x is 0, the result is undefined. */ | 97 | significant bit position. If x is 0, the result is undefined. */ |
| 89 | int __builtin_ctz (unsigned int x) { CTZI(x) } | 98 | int BUILTIN(ctz) (unsigned int x) { CTZI(x) } |
| | 99 | int BUILTIN(ctzll) (unsigned long long x) { CTZL(x) } |
| 90 | #if __SIZEOF_LONG__ == 4 | 100 | #if __SIZEOF_LONG__ == 4 |
| 91 | int __builtin_ctzl (unsigned long x) { CTZI(x) } | 101 | int BUILTIN(ctzl) (unsigned long x) __attribute__((alias(BUILTINN(ctz)))); |
| 92 | #else | 102 | #else |
| 93 | int __builtin_ctzl (unsigned long x) { CTZL(x) } | 103 | int BUILTIN(ctzl) (unsigned long x) __attribute__((alias(BUILTINN(ctzll)))); |
| 94 | #endif | 104 | #endif |
| 95 | int __builtin_ctzll (unsigned long long x) { CTZL(x) } | | |
| 96 | | 105 | |
| 97 | /* Returns the number of leading redundant sign bits in x, i.e. the number | 106 | /* Returns the number of leading redundant sign bits in x, i.e. the number |
| 98 | of bits following the most significant bit that are identical to it. | 107 | of bits following the most significant bit that are identical to it. |
| 99 | There are no special cases for 0 or other values. */ | 108 | There are no special cases for 0 or other values. */ |
| 100 | int __builtin_clrsb (int x) { if (x < 0) x = ~x; x <<= 1; CLZI(x) } | 109 | int BUILTIN(clrsb) (int x) { if (x < 0) x = ~x; x <<= 1; CLZI(x) } |
| | 110 | int BUILTIN(clrsbll) (long long x) { if (x < 0) x = ~x; x <<= 1; CLZL(x) } |
| 101 | #if __SIZEOF_LONG__ == 4 | 111 | #if __SIZEOF_LONG__ == 4 |
| 102 | int __builtin_clrsbl (long x) { if (x < 0) x = ~x; x <<= 1; CLZI(x) } | 112 | int BUILTIN(clrsbl) (long x) __attribute__((alias(BUILTINN(clrsb)))); |
| 103 | #else | 113 | #else |
| 104 | int __builtin_clrsbl (long x) { if (x < 0) x = ~x; x <<= 1; CLZL(x) } | 114 | int BUILTIN(clrsbl) (long x) __attribute__((alias(BUILTINN(clrsbll)))); |
| 105 | #endif | 115 | #endif |
| 106 | int __builtin_clrsbll (long long x) { if (x < 0) x = ~x; x <<= 1; CLZL(x) } | | |
| 107 | | 116 | |
| 108 | /* Returns the number of 1-bits in x.*/ | 117 | /* Returns the number of 1-bits in x.*/ |
| 109 | int __builtin_popcount (unsigned int x) { POPCOUNTI(x, 0x3f) } | 118 | int BUILTIN(popcount) (unsigned int x) { POPCOUNTI(x, 0x3f) } |
| | 119 | int BUILTIN(popcountll) (unsigned long long x) { POPCOUNTL(x, 0x7f) } |
| 110 | #if __SIZEOF_LONG__ == 4 | 120 | #if __SIZEOF_LONG__ == 4 |
| 111 | int __builtin_popcountl (unsigned long x) { POPCOUNTI(x, 0x3f) } | 121 | int BUILTIN(popcountl) (unsigned long x) __attribute__((alias(BUILTINN(popcount)))); |
| 112 | #else | 122 | #else |
| 113 | int __builtin_popcountl (unsigned long x) { POPCOUNTL(x, 0x7f) } | 123 | int BUILTIN(popcountl ) (unsigned long x) __attribute__((alias(BUILTINN(popcountll)))); |
| 114 | #endif | 124 | #endif |
| 115 | int __builtin_popcountll (unsigned long long x) { POPCOUNTL(x, 0x7f) } | | |
| 116 | | 125 | |
| 117 | /* Returns the parity of x, i.e. the number of 1-bits in x modulo 2. */ | 126 | /* Returns the parity of x, i.e. the number of 1-bits in x modulo 2. */ |
| 118 | int __builtin_parity (unsigned int x) { POPCOUNTI(x, 0x01) } | 127 | int BUILTIN(parity) (unsigned int x) { POPCOUNTI(x, 0x01) } |
| | 128 | int BUILTIN(parityll) (unsigned long long x) { POPCOUNTL(x, 0x01) } |
| 119 | #if __SIZEOF_LONG__ == 4 | 129 | #if __SIZEOF_LONG__ == 4 |
| 120 | int __builtin_parityl (unsigned long x) { POPCOUNTI(x, 0x01) } | 130 | int BUILTIN(parityl) (unsigned long x) __attribute__((alias(BUILTINN(parity)))); |
| 121 | #else | 131 | #else |
| 122 | int __builtin_parityl (unsigned long x) { POPCOUNTL(x, 0x01) } | 132 | int BUILTIN(parityl) (unsigned long x) __attribute__((alias(BUILTINN(parityll)))); |
| | 133 | #endif |
| | 134 | |
| | 135 | #ifndef __TINYC__ |
| | 136 | #if defined(__GNUC__) && (__GNUC__ >= 6) |
| | 137 | /* gcc overrides alias from __builtin_ffs... to ffs.. so use assembly code */ |
| | 138 | __asm__(".globl __builtin_ffs"); |
| | 139 | __asm__(".set __builtin_ffs,__tcc_builtin_ffs"); |
| | 140 | __asm__(".globl __builtin_ffsl"); |
| | 141 | __asm__(".set __builtin_ffsl,__tcc_builtin_ffsl"); |
| | 142 | __asm__(".globl __builtin_ffsll"); |
| | 143 | __asm__(".set __builtin_ffsll,__tcc_builtin_ffsll"); |
| | 144 | #else |
| | 145 | int __builtin_ffs(int x) __attribute__((alias("__tcc_builtin_ffs"))); |
| | 146 | int __builtin_ffsl(long x) __attribute__((alias("__tcc_builtin_ffsl"))); |
| | 147 | int __builtin_ffsll(long long x) __attribute__((alias("__tcc_builtin_ffsll"))); |
| | 148 | #endif |
| | 149 | int __builtin_clz(unsigned int x) __attribute__((alias("__tcc_builtin_clz"))); |
| | 150 | int __builtin_clzl(unsigned long x) __attribute__((alias("__tcc_builtin_clzl"))); |
| | 151 | int __builtin_clzll(unsigned long long x) __attribute__((alias("__tcc_builtin_clzll"))); |
| | 152 | int __builtin_ctz(unsigned int x) __attribute__((alias("__tcc_builtin_ctz"))); |
| | 153 | int __builtin_ctzl(unsigned long x) __attribute__((alias("__tcc_builtin_ctzl"))); |
| | 154 | int __builtin_ctzll(unsigned long long x) __attribute__((alias("__tcc_builtin_ctzll"))); |
| | 155 | int __builtin_clrsb(int x) __attribute__((alias("__tcc_builtin_clrsb"))); |
| | 156 | int __builtin_clrsbl(long x) __attribute__((alias("__tcc_builtin_clrsbl"))); |
| | 157 | int __builtin_clrsbll(long long x) __attribute__((alias("__tcc_builtin_clrsbll"))); |
| | 158 | int __builtin_popcount(unsigned int x) __attribute__((alias("__tcc_builtin_popcount"))); |
| | 159 | int __builtin_popcountl(unsigned long x) __attribute__((alias("__tcc_builtin_popcountl"))); |
| | 160 | int __builtin_popcountll(unsigned long long x) __attribute__((alias("__tcc_builtin_popcountll"))); |
| | 161 | int __builtin_parity(unsigned int x) __attribute__((alias("__tcc_builtin_parity"))); |
| | 162 | int __builtin_parityl(unsigned long x) __attribute__((alias("__tcc_builtin_parityl"))); |
| | 163 | int __builtin_parityll(unsigned long long x) __attribute__((alias("__tcc_builtin_parityll"))); |
| 123 | #endif | 164 | #endif |
| 124 | int __builtin_parityll (unsigned long long x) { POPCOUNTL(x, 0x01) } | | |