Commit b854608e0c10eb31d545d1fa7db2412522a315f5
1 parent
f4e15b4b
sparc condition code computation fix (Even Rouault)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1838 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
60 additions
and
20 deletions
target-sparc/op.c
| ... | ... | @@ -415,28 +415,50 @@ void OPPROTO op_addx_T1_T0(void) |
| 415 | 415 | void OPPROTO op_addx_T1_T0_cc(void) |
| 416 | 416 | { |
| 417 | 417 | target_ulong src1; |
| 418 | - | |
| 419 | 418 | src1 = T0; |
| 420 | - T0 += T1 + FLAG_SET(PSR_CARRY); | |
| 421 | - env->psr = 0; | |
| 419 | + if (FLAG_SET(PSR_CARRY)) | |
| 420 | + { | |
| 421 | + T0 += T1 + 1; | |
| 422 | + env->psr = 0; | |
| 423 | +#ifdef TARGET_SPARC64 | |
| 424 | + if ((T0 & 0xffffffff) <= (src1 & 0xffffffff)) | |
| 425 | + env->psr |= PSR_CARRY; | |
| 426 | + env->xcc = 0; | |
| 427 | + if (T0 <= src1) | |
| 428 | + env->xcc |= PSR_CARRY; | |
| 429 | +#else | |
| 430 | + if (T0 <= src1) | |
| 431 | + env->psr |= PSR_CARRY; | |
| 432 | +#endif | |
| 433 | + } | |
| 434 | + else | |
| 435 | + { | |
| 436 | + T0 += T1; | |
| 437 | + env->psr = 0; | |
| 438 | +#ifdef TARGET_SPARC64 | |
| 439 | + if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) | |
| 440 | + env->psr |= PSR_CARRY; | |
| 441 | + env->xcc = 0; | |
| 442 | + if (T0 < src1) | |
| 443 | + env->xcc |= PSR_CARRY; | |
| 444 | +#else | |
| 445 | + if (T0 < src1) | |
| 446 | + env->psr |= PSR_CARRY; | |
| 447 | +#endif | |
| 448 | + } | |
| 422 | 449 | #ifdef TARGET_SPARC64 |
| 423 | 450 | if (!(T0 & 0xffffffff)) |
| 424 | 451 | env->psr |= PSR_ZERO; |
| 425 | 452 | if ((int32_t) T0 < 0) |
| 426 | 453 | env->psr |= PSR_NEG; |
| 427 | - if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) | |
| 428 | - env->psr |= PSR_CARRY; | |
| 429 | 454 | if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & |
| 430 | 455 | ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) |
| 431 | 456 | env->psr |= PSR_OVF; |
| 432 | 457 | |
| 433 | - env->xcc = 0; | |
| 434 | 458 | if (!T0) |
| 435 | 459 | env->xcc |= PSR_ZERO; |
| 436 | 460 | if ((int64_t) T0 < 0) |
| 437 | 461 | env->xcc |= PSR_NEG; |
| 438 | - if (T0 < src1) | |
| 439 | - env->xcc |= PSR_CARRY; | |
| 440 | 462 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63)) |
| 441 | 463 | env->xcc |= PSR_OVF; |
| 442 | 464 | #else |
| ... | ... | @@ -444,8 +466,6 @@ void OPPROTO op_addx_T1_T0_cc(void) |
| 444 | 466 | env->psr |= PSR_ZERO; |
| 445 | 467 | if ((int32_t) T0 < 0) |
| 446 | 468 | env->psr |= PSR_NEG; |
| 447 | - if (T0 < src1) | |
| 448 | - env->psr |= PSR_CARRY; | |
| 449 | 469 | if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) |
| 450 | 470 | env->psr |= PSR_OVF; |
| 451 | 471 | #endif |
| ... | ... | @@ -505,28 +525,50 @@ void OPPROTO op_subx_T1_T0(void) |
| 505 | 525 | void OPPROTO op_subx_T1_T0_cc(void) |
| 506 | 526 | { |
| 507 | 527 | target_ulong src1; |
| 508 | - | |
| 509 | 528 | src1 = T0; |
| 510 | - T0 -= T1 + FLAG_SET(PSR_CARRY); | |
| 511 | - env->psr = 0; | |
| 529 | + if (FLAG_SET(PSR_CARRY)) | |
| 530 | + { | |
| 531 | + T0 -= T1 + 1; | |
| 532 | + env->psr = 0; | |
| 533 | +#ifdef TARGET_SPARC64 | |
| 534 | + if ((src1 & 0xffffffff) <= (T1 & 0xffffffff)) | |
| 535 | + env->psr |= PSR_CARRY; | |
| 536 | + env->xcc = 0; | |
| 537 | + if (src1 <= T1) | |
| 538 | + env->xcc |= PSR_CARRY; | |
| 539 | +#else | |
| 540 | + if (src1 <= T1) | |
| 541 | + env->psr |= PSR_CARRY; | |
| 542 | +#endif | |
| 543 | + } | |
| 544 | + else | |
| 545 | + { | |
| 546 | + T0 -= T1; | |
| 547 | + env->psr = 0; | |
| 548 | +#ifdef TARGET_SPARC64 | |
| 549 | + if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) | |
| 550 | + env->psr |= PSR_CARRY; | |
| 551 | + env->xcc = 0; | |
| 552 | + if (src1 < T1) | |
| 553 | + env->xcc |= PSR_CARRY; | |
| 554 | +#else | |
| 555 | + if (src1 < T1) | |
| 556 | + env->psr |= PSR_CARRY; | |
| 557 | +#endif | |
| 558 | + } | |
| 512 | 559 | #ifdef TARGET_SPARC64 |
| 513 | 560 | if (!(T0 & 0xffffffff)) |
| 514 | 561 | env->psr |= PSR_ZERO; |
| 515 | 562 | if ((int32_t) T0 < 0) |
| 516 | 563 | env->psr |= PSR_NEG; |
| 517 | - if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) | |
| 518 | - env->psr |= PSR_CARRY; | |
| 519 | 564 | if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & |
| 520 | 565 | ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) |
| 521 | 566 | env->psr |= PSR_OVF; |
| 522 | 567 | |
| 523 | - env->xcc = 0; | |
| 524 | 568 | if (!T0) |
| 525 | 569 | env->xcc |= PSR_ZERO; |
| 526 | 570 | if ((int64_t) T0 < 0) |
| 527 | 571 | env->xcc |= PSR_NEG; |
| 528 | - if (src1 < T1) | |
| 529 | - env->xcc |= PSR_CARRY; | |
| 530 | 572 | if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63)) |
| 531 | 573 | env->xcc |= PSR_OVF; |
| 532 | 574 | #else |
| ... | ... | @@ -534,8 +576,6 @@ void OPPROTO op_subx_T1_T0_cc(void) |
| 534 | 576 | env->psr |= PSR_ZERO; |
| 535 | 577 | if ((int32_t) T0 < 0) |
| 536 | 578 | env->psr |= PSR_NEG; |
| 537 | - if (src1 < T1) | |
| 538 | - env->psr |= PSR_CARRY; | |
| 539 | 579 | if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) |
| 540 | 580 | env->psr |= PSR_OVF; |
| 541 | 581 | #endif | ... | ... |