Commit b854608e0c10eb31d545d1fa7db2412522a315f5

Authored by bellard
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
... ...