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 */ | ... | ... |