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 | } | ... | ... |