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,14 +47,16 @@ void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b); | ||
47 | void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); | 47 | void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); |
48 | #endif | 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 | /* Binary search for leading zeros. */ | 50 | /* Binary search for leading zeros. */ |
55 | 51 | ||
56 | static always_inline int clz32(uint32_t val) | 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 | int cnt = 0; | 60 | int cnt = 0; |
59 | 61 | ||
60 | if (!(val & 0xFFFF0000U)) { | 62 | if (!(val & 0xFFFF0000U)) { |
@@ -81,6 +83,7 @@ static always_inline int clz32(uint32_t val) | @@ -81,6 +83,7 @@ static always_inline int clz32(uint32_t val) | ||
81 | cnt++; | 83 | cnt++; |
82 | } | 84 | } |
83 | return cnt; | 85 | return cnt; |
86 | +#endif | ||
84 | } | 87 | } |
85 | 88 | ||
86 | static always_inline int clo32(uint32_t val) | 89 | static always_inline int clo32(uint32_t val) |
@@ -90,6 +93,12 @@ static always_inline int clo32(uint32_t val) | @@ -90,6 +93,12 @@ static always_inline int clo32(uint32_t val) | ||
90 | 93 | ||
91 | static always_inline int clz64(uint64_t val) | 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 | int cnt = 0; | 102 | int cnt = 0; |
94 | 103 | ||
95 | if (!(val >> 32)) { | 104 | if (!(val >> 32)) { |
@@ -99,6 +108,7 @@ static always_inline int clz64(uint64_t val) | @@ -99,6 +108,7 @@ static always_inline int clz64(uint64_t val) | ||
99 | } | 108 | } |
100 | 109 | ||
101 | return cnt + clz32(val); | 110 | return cnt + clz32(val); |
111 | +#endif | ||
102 | } | 112 | } |
103 | 113 | ||
104 | static always_inline int clo64(uint64_t val) | 114 | static always_inline int clo64(uint64_t val) |
@@ -108,6 +118,12 @@ static always_inline int clo64(uint64_t val) | @@ -108,6 +118,12 @@ static always_inline int clo64(uint64_t val) | ||
108 | 118 | ||
109 | static always_inline int ctz32 (uint32_t val) | 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 | int cnt; | 127 | int cnt; |
112 | 128 | ||
113 | cnt = 0; | 129 | cnt = 0; |
@@ -136,6 +152,7 @@ static always_inline int ctz32 (uint32_t val) | @@ -136,6 +152,7 @@ static always_inline int ctz32 (uint32_t val) | ||
136 | } | 152 | } |
137 | 153 | ||
138 | return cnt; | 154 | return cnt; |
155 | +#endif | ||
139 | } | 156 | } |
140 | 157 | ||
141 | static always_inline int cto32 (uint32_t val) | 158 | static always_inline int cto32 (uint32_t val) |
@@ -145,6 +162,12 @@ static always_inline int cto32 (uint32_t val) | @@ -145,6 +162,12 @@ static always_inline int cto32 (uint32_t val) | ||
145 | 162 | ||
146 | static always_inline int ctz64 (uint64_t val) | 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 | int cnt; | 171 | int cnt; |
149 | 172 | ||
150 | cnt = 0; | 173 | cnt = 0; |
@@ -154,6 +177,7 @@ static always_inline int ctz64 (uint64_t val) | @@ -154,6 +177,7 @@ static always_inline int ctz64 (uint64_t val) | ||
154 | } | 177 | } |
155 | 178 | ||
156 | return cnt + ctz32(val); | 179 | return cnt + ctz32(val); |
180 | +#endif | ||
157 | } | 181 | } |
158 | 182 | ||
159 | static always_inline int cto64 (uint64_t val) | 183 | static always_inline int cto64 (uint64_t val) |
@@ -182,6 +206,9 @@ static always_inline int ctpop16 (uint16_t val) | @@ -182,6 +206,9 @@ static always_inline int ctpop16 (uint16_t val) | ||
182 | 206 | ||
183 | static always_inline int ctpop32 (uint32_t val) | 207 | static always_inline int ctpop32 (uint32_t val) |
184 | { | 208 | { |
209 | +#if defined(__GNUC__) | ||
210 | + return __builtin_popcount(val); | ||
211 | +#else | ||
185 | val = (val & 0x55555555) + ((val >> 1) & 0x55555555); | 212 | val = (val & 0x55555555) + ((val >> 1) & 0x55555555); |
186 | val = (val & 0x33333333) + ((val >> 2) & 0x33333333); | 213 | val = (val & 0x33333333) + ((val >> 2) & 0x33333333); |
187 | val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f); | 214 | val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f); |
@@ -189,10 +216,14 @@ static always_inline int ctpop32 (uint32_t val) | @@ -189,10 +216,14 @@ static always_inline int ctpop32 (uint32_t val) | ||
189 | val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); | 216 | val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff); |
190 | 217 | ||
191 | return val; | 218 | return val; |
219 | +#endif | ||
192 | } | 220 | } |
193 | 221 | ||
194 | static always_inline int ctpop64 (uint64_t val) | 222 | static always_inline int ctpop64 (uint64_t val) |
195 | { | 223 | { |
224 | +#if defined(__GNUC__) | ||
225 | + return __builtin_popcountll(val); | ||
226 | +#else | ||
196 | val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); | 227 | val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL); |
197 | val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); | 228 | val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); |
198 | val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL); | 229 | val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL); |
@@ -201,4 +232,5 @@ static always_inline int ctpop64 (uint64_t val) | @@ -201,4 +232,5 @@ static always_inline int ctpop64 (uint64_t val) | ||
201 | val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL); | 232 | val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL); |
202 | 233 | ||
203 | return val; | 234 | return val; |
235 | +#endif | ||
204 | } | 236 | } |