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,6 +19,7 @@ | ||
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include "exec.h" | 21 | #include "exec.h" |
| 22 | +#include "host-utils.h" | ||
| 22 | #include "softfloat.h" | 23 | #include "softfloat.h" |
| 23 | 24 | ||
| 24 | #include "op_helper.h" | 25 | #include "op_helper.h" |
| @@ -211,87 +212,17 @@ void helper_mulqv () | @@ -211,87 +212,17 @@ void helper_mulqv () | ||
| 211 | 212 | ||
| 212 | void helper_ctpop (void) | 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 | void helper_ctlz (void) | 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 | void helper_cttz (void) | 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 | static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb) | 228 | static always_inline uint64_t byte_zap (uint64_t op, uint8_t mskb) |
target-ppc/op.c
| @@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
| 22 | 22 | ||
| 23 | #include "config.h" | 23 | #include "config.h" |
| 24 | #include "exec.h" | 24 | #include "exec.h" |
| 25 | +#include "host-utils.h" | ||
| 25 | #include "helper_regs.h" | 26 | #include "helper_regs.h" |
| 26 | #include "op_helper.h" | 27 | #include "op_helper.h" |
| 27 | 28 | ||
| @@ -1508,14 +1509,14 @@ void OPPROTO op_andi_T1_64 (void) | @@ -1508,14 +1509,14 @@ void OPPROTO op_andi_T1_64 (void) | ||
| 1508 | /* count leading zero */ | 1509 | /* count leading zero */ |
| 1509 | void OPPROTO op_cntlzw (void) | 1510 | void OPPROTO op_cntlzw (void) |
| 1510 | { | 1511 | { |
| 1511 | - T0 = _do_cntlzw(T0); | 1512 | + do_cntlzw(); |
| 1512 | RETURN(); | 1513 | RETURN(); |
| 1513 | } | 1514 | } |
| 1514 | 1515 | ||
| 1515 | #if defined(TARGET_PPC64) | 1516 | #if defined(TARGET_PPC64) |
| 1516 | void OPPROTO op_cntlzd (void) | 1517 | void OPPROTO op_cntlzd (void) |
| 1517 | { | 1518 | { |
| 1518 | - T0 = _do_cntlzd(T0); | 1519 | + do_cntlzd(); |
| 1519 | RETURN(); | 1520 | RETURN(); |
| 1520 | } | 1521 | } |
| 1521 | #endif | 1522 | #endif |
target-ppc/op_helper.c
| @@ -18,6 +18,7 @@ | @@ -18,6 +18,7 @@ | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | #include "exec.h" | 20 | #include "exec.h" |
| 21 | +#include "host-utils.h" | ||
| 21 | 22 | ||
| 22 | #include "helper_regs.h" | 23 | #include "helper_regs.h" |
| 23 | #include "op_helper.h" | 24 | #include "op_helper.h" |
| @@ -381,6 +382,18 @@ void do_subfzeo_64 (void) | @@ -381,6 +382,18 @@ void do_subfzeo_64 (void) | ||
| 381 | } | 382 | } |
| 382 | #endif | 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 | /* shift right arithmetic helper */ | 397 | /* shift right arithmetic helper */ |
| 385 | void do_sraw (void) | 398 | void do_sraw (void) |
| 386 | { | 399 | { |
| @@ -438,16 +451,6 @@ void do_srad (void) | @@ -438,16 +451,6 @@ void do_srad (void) | ||
| 438 | } | 451 | } |
| 439 | #endif | 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 | void do_popcntb (void) | 454 | void do_popcntb (void) |
| 452 | { | 455 | { |
| 453 | uint32_t ret; | 456 | uint32_t ret; |
| @@ -455,7 +458,7 @@ void do_popcntb (void) | @@ -455,7 +458,7 @@ void do_popcntb (void) | ||
| 455 | 458 | ||
| 456 | ret = 0; | 459 | ret = 0; |
| 457 | for (i = 0; i < 32; i += 8) | 460 | for (i = 0; i < 32; i += 8) |
| 458 | - ret |= popcnt((T0 >> i) & 0xFF) << i; | 461 | + ret |= ctpop8((T0 >> i) & 0xFF) << i; |
| 459 | T0 = ret; | 462 | T0 = ret; |
| 460 | } | 463 | } |
| 461 | 464 | ||
| @@ -467,7 +470,7 @@ void do_popcntb_64 (void) | @@ -467,7 +470,7 @@ void do_popcntb_64 (void) | ||
| 467 | 470 | ||
| 468 | ret = 0; | 471 | ret = 0; |
| 469 | for (i = 0; i < 64; i += 8) | 472 | for (i = 0; i < 64; i += 8) |
| 470 | - ret |= popcnt((T0 >> i) & 0xFF) << i; | 473 | + ret |= ctpop8((T0 >> i) & 0xFF) << i; |
| 471 | T0 = ret; | 474 | T0 = ret; |
| 472 | } | 475 | } |
| 473 | #endif | 476 | #endif |
| @@ -1924,14 +1927,14 @@ static always_inline uint32_t _do_eaddw (uint32_t op1, uint32_t op2) | @@ -1924,14 +1927,14 @@ static always_inline uint32_t _do_eaddw (uint32_t op1, uint32_t op2) | ||
| 1924 | static always_inline int _do_ecntlsw (uint32_t val) | 1927 | static always_inline int _do_ecntlsw (uint32_t val) |
| 1925 | { | 1928 | { |
| 1926 | if (val & 0x80000000) | 1929 | if (val & 0x80000000) |
| 1927 | - return _do_cntlzw(~val); | 1930 | + return clz32(~val); |
| 1928 | else | 1931 | else |
| 1929 | - return _do_cntlzw(val); | 1932 | + return clz32(val); |
| 1930 | } | 1933 | } |
| 1931 | 1934 | ||
| 1932 | static always_inline int _do_ecntlzw (uint32_t val) | 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 | static always_inline uint32_t _do_eneg (uint32_t val) | 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,6 +75,10 @@ void do_nego (void); | ||
| 75 | void do_subfe (void); | 75 | void do_subfe (void); |
| 76 | void do_subfmeo (void); | 76 | void do_subfmeo (void); |
| 77 | void do_subfzeo (void); | 77 | void do_subfzeo (void); |
| 78 | +void do_cntlzw (void); | ||
| 79 | +#if defined(TARGET_PPC64) | ||
| 80 | +void do_cntlzd (void); | ||
| 81 | +#endif | ||
| 78 | void do_sraw (void); | 82 | void do_sraw (void); |
| 79 | #if defined(TARGET_PPC64) | 83 | #if defined(TARGET_PPC64) |
| 80 | void do_adde_64 (void); | 84 | void do_adde_64 (void); |
| @@ -285,78 +289,6 @@ void do_evfsctsiz (void); | @@ -285,78 +289,6 @@ void do_evfsctsiz (void); | ||
| 285 | void do_evfsctuiz (void); | 289 | void do_evfsctuiz (void); |
| 286 | #endif /* defined(TARGET_PPCEMB) */ | 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 | #if defined(TARGET_PPCEMB) | 292 | #if defined(TARGET_PPCEMB) |
| 361 | /* SPE extension */ | 293 | /* SPE extension */ |
| 362 | /* Single precision floating-point helpers */ | 294 | /* Single precision floating-point helpers */ |