Commit 603fcccece43303c623df2561f85ab2baba95e5f
1 parent
b9ef45ff
Make Alpha and PowerPC targets use shared helpers
for clz, clo, ctz, cto and ctpop. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3466 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
29 additions
and
162 deletions
target-alpha/op_helper.c
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | */ |
20 | 20 | |
21 | 21 | #include "exec.h" |
22 | +#include "host-utils.h" | |
22 | 23 | #include "softfloat.h" |
23 | 24 | |
24 | 25 | #include "op_helper.h" |
... | ... | @@ -211,87 +212,17 @@ void helper_mulqv () |
211 | 212 | |
212 | 213 | void helper_ctpop (void) |
213 | 214 | { |
214 | - int n; | |
215 | - | |
216 | - for (n = 0; T0 != 0; n++) | |
217 | - T0 = T0 ^ (T0 - 1); | |
218 | - T0 = n; | |
215 | + T0 = ctpop64(T0); | |
219 | 216 | } |
220 | 217 | |
221 | 218 | void helper_ctlz (void) |
222 | 219 | { |
223 | - uint32_t op32; | |
224 | - int n; | |
225 | - | |
226 | - n = 0; | |
227 | - if (!(T0 & 0xFFFFFFFF00000000ULL)) { | |
228 | - n += 32; | |
229 | - T0 <<= 32; | |
230 | - } | |
231 | - /* Make it easier for 32 bits hosts */ | |
232 | - op32 = T0 >> 32; | |
233 | - if (!(op32 & 0xFFFF0000UL)) { | |
234 | - n += 16; | |
235 | - op32 <<= 16; | |
236 | - } | |
237 | - if (!(op32 & 0xFF000000UL)) { | |
238 | - n += 8; | |
239 | - op32 <<= 8; | |
240 | - } | |
241 | - if (!(op32 & 0xF0000000UL)) { | |
242 | - n += 4; | |
243 | - op32 <<= 4; | |
244 | - } | |
245 | - if (!(op32 & 0xC0000000UL)) { | |
246 | - n += 2; | |
247 | - op32 <<= 2; | |
248 | - } | |
249 | - if (!(op32 & 0x80000000UL)) { | |
250 | - n++; | |
251 | - op32 <<= 1; | |
252 | - } | |
253 | - if (!(op32 & 0x80000000UL)) { | |
254 | - n++; | |
255 | - } | |
256 | - T0 = n; | |
220 | + T0 = clz64(T0); | |
257 | 221 | } |
258 | 222 | |
259 | 223 | void helper_cttz (void) |
260 | 224 | { |
261 | - uint32_t op32; | |
262 | - int n; | |
263 | - | |
264 | - n = 0; | |
265 | - if (!(T0 & 0x00000000FFFFFFFFULL)) { | |
266 | - n += 32; | |
267 | - T0 >>= 32; | |
268 | - } | |
269 | - /* Make it easier for 32 bits hosts */ | |
270 | - op32 = T0; | |
271 | - if (!(op32 & 0x0000FFFFUL)) { | |
272 | - n += 16; | |
273 | - op32 >>= 16; | |
274 | - } | |
275 | - if (!(op32 & 0x000000FFUL)) { | |
276 | - n += 8; | |
277 | - op32 >>= 8; | |
278 | - } | |
279 | - if (!(op32 & 0x0000000FUL)) { | |
280 | - n += 4; | |
281 | - op32 >>= 4; | |
282 | - } | |
283 | - if (!(op32 & 0x00000003UL)) { | |
284 | - n += 2; | |
285 | - op32 >>= 2; | |
286 | - } | |
287 | - if (!(op32 & 0x00000001UL)) { | |
288 | - n++; | |
289 | - op32 >>= 1; | |
290 | - } | |
291 | - if (!(op32 & 0x00000001UL)) { | |
292 | - n++; | |
293 | - } | |
294 | - T0 = n; | |
225 | + T0 = ctz64(T0); | |
295 | 226 | } |
296 | 227 | |
297 | 228 | static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb) | ... | ... |
target-ppc/op.c
... | ... | @@ -22,6 +22,7 @@ |
22 | 22 | |
23 | 23 | #include "config.h" |
24 | 24 | #include "exec.h" |
25 | +#include "host-utils.h" | |
25 | 26 | #include "helper_regs.h" |
26 | 27 | #include "op_helper.h" |
27 | 28 | |
... | ... | @@ -1508,14 +1509,14 @@ void OPPROTO op_andi_T1_64 (void) |
1508 | 1509 | /* count leading zero */ |
1509 | 1510 | void OPPROTO op_cntlzw (void) |
1510 | 1511 | { |
1511 | - T0 = _do_cntlzw(T0); | |
1512 | + do_cntlzw(); | |
1512 | 1513 | RETURN(); |
1513 | 1514 | } |
1514 | 1515 | |
1515 | 1516 | #if defined(TARGET_PPC64) |
1516 | 1517 | void OPPROTO op_cntlzd (void) |
1517 | 1518 | { |
1518 | - T0 = _do_cntlzd(T0); | |
1519 | + do_cntlzd(); | |
1519 | 1520 | RETURN(); |
1520 | 1521 | } |
1521 | 1522 | #endif | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 | */ |
20 | 20 | #include "exec.h" |
21 | +#include "host-utils.h" | |
21 | 22 | |
22 | 23 | #include "helper_regs.h" |
23 | 24 | #include "op_helper.h" |
... | ... | @@ -381,6 +382,18 @@ void do_subfzeo_64 (void) |
381 | 382 | } |
382 | 383 | #endif |
383 | 384 | |
385 | +void do_cntlzw (void) | |
386 | +{ | |
387 | + T0 = clz32(T0); | |
388 | +} | |
389 | + | |
390 | +#if defined(TARGET_PPC64) | |
391 | +void do_cntlzd (void) | |
392 | +{ | |
393 | + T0 = clz64(T0); | |
394 | +} | |
395 | +#endif | |
396 | + | |
384 | 397 | /* shift right arithmetic helper */ |
385 | 398 | void do_sraw (void) |
386 | 399 | { |
... | ... | @@ -438,16 +451,6 @@ void do_srad (void) |
438 | 451 | } |
439 | 452 | #endif |
440 | 453 | |
441 | -static always_inline int popcnt (uint32_t val) | |
442 | -{ | |
443 | - int i; | |
444 | - | |
445 | - for (i = 0; val != 0;) | |
446 | - val = val ^ (val - 1); | |
447 | - | |
448 | - return i; | |
449 | -} | |
450 | - | |
451 | 454 | void do_popcntb (void) |
452 | 455 | { |
453 | 456 | uint32_t ret; |
... | ... | @@ -455,7 +458,7 @@ void do_popcntb (void) |
455 | 458 | |
456 | 459 | ret = 0; |
457 | 460 | for (i = 0; i < 32; i += 8) |
458 | - ret |= popcnt((T0 >> i) & 0xFF) << i; | |
461 | + ret |= ctpop8((T0 >> i) & 0xFF) << i; | |
459 | 462 | T0 = ret; |
460 | 463 | } |
461 | 464 | |
... | ... | @@ -467,7 +470,7 @@ void do_popcntb_64 (void) |
467 | 470 | |
468 | 471 | ret = 0; |
469 | 472 | for (i = 0; i < 64; i += 8) |
470 | - ret |= popcnt((T0 >> i) & 0xFF) << i; | |
473 | + ret |= ctpop8((T0 >> i) & 0xFF) << i; | |
471 | 474 | T0 = ret; |
472 | 475 | } |
473 | 476 | #endif |
... | ... | @@ -1924,14 +1927,14 @@ static always_inline uint32_t _do_eaddw (uint32_t op1, uint32_t op2) |
1924 | 1927 | static always_inline int _do_ecntlsw (uint32_t val) |
1925 | 1928 | { |
1926 | 1929 | if (val & 0x80000000) |
1927 | - return _do_cntlzw(~val); | |
1930 | + return clz32(~val); | |
1928 | 1931 | else |
1929 | - return _do_cntlzw(val); | |
1932 | + return clz32(val); | |
1930 | 1933 | } |
1931 | 1934 | |
1932 | 1935 | static always_inline int _do_ecntlzw (uint32_t val) |
1933 | 1936 | { |
1934 | - return _do_cntlzw(val); | |
1937 | + return clz32(val); | |
1935 | 1938 | } |
1936 | 1939 | |
1937 | 1940 | static always_inline uint32_t _do_eneg (uint32_t val) | ... | ... |
target-ppc/op_helper.h
... | ... | @@ -75,6 +75,10 @@ void do_nego (void); |
75 | 75 | void do_subfe (void); |
76 | 76 | void do_subfmeo (void); |
77 | 77 | void do_subfzeo (void); |
78 | +void do_cntlzw (void); | |
79 | +#if defined(TARGET_PPC64) | |
80 | +void do_cntlzd (void); | |
81 | +#endif | |
78 | 82 | void do_sraw (void); |
79 | 83 | #if defined(TARGET_PPC64) |
80 | 84 | void do_adde_64 (void); |
... | ... | @@ -285,78 +289,6 @@ void do_evfsctsiz (void); |
285 | 289 | void do_evfsctuiz (void); |
286 | 290 | #endif /* defined(TARGET_PPCEMB) */ |
287 | 291 | |
288 | -/* Inlined helpers: used in micro-operation as well as helpers */ | |
289 | -/* Generic fixed-point helpers */ | |
290 | -static always_inline int _do_cntlzw (uint32_t val) | |
291 | -{ | |
292 | - int cnt = 0; | |
293 | - if (!(val & 0xFFFF0000UL)) { | |
294 | - cnt += 16; | |
295 | - val <<= 16; | |
296 | - } | |
297 | - if (!(val & 0xFF000000UL)) { | |
298 | - cnt += 8; | |
299 | - val <<= 8; | |
300 | - } | |
301 | - if (!(val & 0xF0000000UL)) { | |
302 | - cnt += 4; | |
303 | - val <<= 4; | |
304 | - } | |
305 | - if (!(val & 0xC0000000UL)) { | |
306 | - cnt += 2; | |
307 | - val <<= 2; | |
308 | - } | |
309 | - if (!(val & 0x80000000UL)) { | |
310 | - cnt++; | |
311 | - val <<= 1; | |
312 | - } | |
313 | - if (!(val & 0x80000000UL)) { | |
314 | - cnt++; | |
315 | - } | |
316 | - return cnt; | |
317 | -} | |
318 | - | |
319 | -static always_inline int _do_cntlzd (uint64_t val) | |
320 | -{ | |
321 | - int cnt = 0; | |
322 | -#if HOST_LONG_BITS == 64 | |
323 | - if (!(val & 0xFFFFFFFF00000000ULL)) { | |
324 | - cnt += 32; | |
325 | - val <<= 32; | |
326 | - } | |
327 | - if (!(val & 0xFFFF000000000000ULL)) { | |
328 | - cnt += 16; | |
329 | - val <<= 16; | |
330 | - } | |
331 | - if (!(val & 0xFF00000000000000ULL)) { | |
332 | - cnt += 8; | |
333 | - val <<= 8; | |
334 | - } | |
335 | - if (!(val & 0xF000000000000000ULL)) { | |
336 | - cnt += 4; | |
337 | - val <<= 4; | |
338 | - } | |
339 | - if (!(val & 0xC000000000000000ULL)) { | |
340 | - cnt += 2; | |
341 | - val <<= 2; | |
342 | - } | |
343 | - if (!(val & 0x8000000000000000ULL)) { | |
344 | - cnt++; | |
345 | - val <<= 1; | |
346 | - } | |
347 | - if (!(val & 0x8000000000000000ULL)) { | |
348 | - cnt++; | |
349 | - } | |
350 | -#else | |
351 | - /* Make it easier on 32 bits host machines */ | |
352 | - if (!(val >> 32)) | |
353 | - cnt = _do_cntlzw(val) + 32; | |
354 | - else | |
355 | - cnt = _do_cntlzw(val >> 32); | |
356 | -#endif | |
357 | - return cnt; | |
358 | -} | |
359 | - | |
360 | 292 | #if defined(TARGET_PPCEMB) |
361 | 293 | /* SPE extension */ |
362 | 294 | /* Single precision floating-point helpers */ | ... | ... |