Commit 7d01998021e38363d53bc93f198023a05d8a52bf
1 parent
bc7b5f87
Optimize some host-utils function with gcc builtins
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5464 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
36 additions
and
4 deletions
host-utils.h
| ... | ... | @@ -47,14 +47,16 @@ void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b); |
| 47 | 47 | void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); |
| 48 | 48 | #endif |
| 49 | 49 | |
| 50 | -/* Note that some of those functions may end up calling libgcc functions, | |
| 51 | - depending on the host machine. It is up to the target emulation to | |
| 52 | - cope with that. */ | |
| 53 | - | |
| 54 | 50 | /* Binary search for leading zeros. */ |
| 55 | 51 | |
| 56 | 52 | static always_inline int clz32(uint32_t val) |
| 57 | 53 | { |
| 54 | +#if defined(__GNUC__) | |
| 55 | + if (val) | |
| 56 | + return __builtin_clz(val); | |
| 57 | + else | |
| 58 | + return 32; | |
| 59 | +#else | |
| 58 | 60 | int cnt = 0; |
| 59 | 61 | |
| 60 | 62 | if (!(val & 0xFFFF0000U)) { |
| ... | ... | @@ -81,6 +83,7 @@ static always_inline int clz32(uint32_t val) |
| 81 | 83 | cnt++; |
| 82 | 84 | } |
| 83 | 85 | return cnt; |
| 86 | +#endif | |
| 84 | 87 | } |
| 85 | 88 | |
| 86 | 89 | static always_inline int clo32(uint32_t val) |
| ... | ... | @@ -90,6 +93,12 @@ static always_inline int clo32(uint32_t val) |
| 90 | 93 | |
| 91 | 94 | static always_inline int clz64(uint64_t val) |
| 92 | 95 | { |
| 96 | +#if defined(__GNUC__) | |
| 97 | + if (val) | |
| 98 | + return __builtin_clzll(val); | |
| 99 | + else | |
| 100 | + return 64; | |
| 101 | +#else | |
| 93 | 102 | int cnt = 0; |
| 94 | 103 | |
| 95 | 104 | if (!(val >> 32)) { |
| ... | ... | @@ -99,6 +108,7 @@ static always_inline int clz64(uint64_t val) |
| 99 | 108 | } |
| 100 | 109 | |
| 101 | 110 | return cnt + clz32(val); |
| 111 | +#endif | |
| 102 | 112 | } |
| 103 | 113 | |
| 104 | 114 | static always_inline int clo64(uint64_t val) |
| ... | ... | @@ -108,6 +118,12 @@ static always_inline int clo64(uint64_t val) |
| 108 | 118 | |
| 109 | 119 | static always_inline int ctz32 (uint32_t val) |
| 110 | 120 | { |
| 121 | +#if defined(__GNUC__) | |
| 122 | + if (val) | |
| 123 | + return __builtin_ctz(val); | |
| 124 | + else | |
| 125 | + return 32; | |
| 126 | +#else | |
| 111 | 127 | int cnt; |
| 112 | 128 | |
| 113 | 129 | cnt = 0; |
| ... | ... | @@ -136,6 +152,7 @@ static always_inline int ctz32 (uint32_t val) |
| 136 | 152 | } |
| 137 | 153 | |
| 138 | 154 | return cnt; |
| 155 | +#endif | |
| 139 | 156 | } |
| 140 | 157 | |
| 141 | 158 | static always_inline int cto32 (uint32_t val) |
| ... | ... | @@ -145,6 +162,12 @@ static always_inline int cto32 (uint32_t val) |
| 145 | 162 | |
| 146 | 163 | static always_inline int ctz64 (uint64_t val) |
| 147 | 164 | { |
| 165 | +#if defined(__GNUC__) | |
| 166 | + if (val) | |
| 167 | + return __builtin_ctz(val); | |
| 168 | + else | |
| 169 | + return 64; | |
| 170 | +#else | |
| 148 | 171 | int cnt; |
| 149 | 172 | |
| 150 | 173 | cnt = 0; |
| ... | ... | @@ -154,6 +177,7 @@ static always_inline int ctz64 (uint64_t val) |
| 154 | 177 | } |
| 155 | 178 | |
| 156 | 179 | return cnt + ctz32(val); |
| 180 | +#endif | |
| 157 | 181 | } |
| 158 | 182 | |
| 159 | 183 | static always_inline int cto64 (uint64_t val) |
| ... | ... | @@ -182,6 +206,9 @@ static always_inline int ctpop16 (uint16_t val) |
| 182 | 206 | |
| 183 | 207 | static always_inline int ctpop32 (uint32_t val) |
| 184 | 208 | { |
| 209 | +#if defined(__GNUC__) | |
| 210 | + return __builtin_popcount(val); | |
| 211 | +#else | |
| 185 | 212 | val = (val & 0x55555555) + ((val >> 1) & 0x55555555); |
| 186 | 213 | val = (val & 0x33333333) + ((val >> 2) & 0x33333333); |
| 187 | 214 | val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f); |
| ... | ... | @@ -189,10 +216,14 @@ static always_inline int ctpop32 (uint32_t val) |
| 189 | 216 | val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); |
| 190 | 217 | |
| 191 | 218 | return val; |
| 219 | +#endif | |
| 192 | 220 | } |
| 193 | 221 | |
| 194 | 222 | static always_inline int ctpop64 (uint64_t val) |
| 195 | 223 | { |
| 224 | +#if defined(__GNUC__) | |
| 225 | + return __builtin_popcountll(val); | |
| 226 | +#else | |
| 196 | 227 | val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); |
| 197 | 228 | val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); |
| 198 | 229 | val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL); |
| ... | ... | @@ -201,4 +232,5 @@ static always_inline int ctpop64 (uint64_t val) |
| 201 | 232 | val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL); |
| 202 | 233 | |
| 203 | 234 | return val; |
| 235 | +#endif | |
| 204 | 236 | } | ... | ... |