Commit 1e5ffbedded7ded797f5042d82b70109a712b4c0
1 parent
79638566
fixed float to int overflow bug - added ARM host correct roundings for float rounding
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@237 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
76 additions
and
79 deletions
helper-i386.c
| ... | ... | @@ -19,6 +19,57 @@ |
| 19 | 19 | */ |
| 20 | 20 | #include "exec-i386.h" |
| 21 | 21 | |
| 22 | +const uint8_t parity_table[256] = { | |
| 23 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 24 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 25 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 26 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 27 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 28 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 29 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 30 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 31 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 32 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 33 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 34 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 35 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 36 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 37 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 38 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 39 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 40 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 41 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 42 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 43 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 44 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 45 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 46 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 47 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 48 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 49 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 50 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 51 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 52 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 53 | + CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 54 | + 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 55 | +}; | |
| 56 | + | |
| 57 | +/* modulo 17 table */ | |
| 58 | +const uint8_t rclw_table[32] = { | |
| 59 | + 0, 1, 2, 3, 4, 5, 6, 7, | |
| 60 | + 8, 9,10,11,12,13,14,15, | |
| 61 | + 16, 0, 1, 2, 3, 4, 5, 6, | |
| 62 | + 7, 8, 9,10,11,12,13,14, | |
| 63 | +}; | |
| 64 | + | |
| 65 | +/* modulo 9 table */ | |
| 66 | +const uint8_t rclb_table[32] = { | |
| 67 | + 0, 1, 2, 3, 4, 5, 6, 7, | |
| 68 | + 8, 0, 1, 2, 3, 4, 5, 6, | |
| 69 | + 7, 8, 0, 1, 2, 3, 4, 5, | |
| 70 | + 6, 7, 8, 0, 1, 2, 3, 4, | |
| 71 | +}; | |
| 72 | + | |
| 22 | 73 | const CPU86_LDouble f15rk[7] = |
| 23 | 74 | { |
| 24 | 75 | 0.00000000000000000000L, |
| ... | ... | @@ -693,7 +744,29 @@ void helper_fsincos(void) |
| 693 | 744 | |
| 694 | 745 | void helper_frndint(void) |
| 695 | 746 | { |
| 696 | - ST0 = rint(ST0); | |
| 747 | + CPU86_LDouble a; | |
| 748 | + | |
| 749 | + a = ST0; | |
| 750 | +#ifdef __arm__ | |
| 751 | + switch(env->fpuc & RC_MASK) { | |
| 752 | + default: | |
| 753 | + case RC_NEAR: | |
| 754 | + asm("rndd %0, %1" : "=f" (a) : "f"(a)); | |
| 755 | + break; | |
| 756 | + case RC_DOWN: | |
| 757 | + asm("rnddm %0, %1" : "=f" (a) : "f"(a)); | |
| 758 | + break; | |
| 759 | + case RC_UP: | |
| 760 | + asm("rnddp %0, %1" : "=f" (a) : "f"(a)); | |
| 761 | + break; | |
| 762 | + case RC_CHOP: | |
| 763 | + asm("rnddz %0, %1" : "=f" (a) : "f"(a)); | |
| 764 | + break; | |
| 765 | + } | |
| 766 | +#else | |
| 767 | + a = rint(a); | |
| 768 | +#endif | |
| 769 | + ST0 = a; | |
| 697 | 770 | } |
| 698 | 771 | |
| 699 | 772 | void helper_fscale(void) | ... | ... |
op-i386.c
| ... | ... | @@ -19,57 +19,6 @@ |
| 19 | 19 | */ |
| 20 | 20 | #include "exec-i386.h" |
| 21 | 21 | |
| 22 | -uint8_t parity_table[256] = { | |
| 23 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 24 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 25 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 26 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 27 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 28 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 29 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 30 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 31 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 32 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 33 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 34 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 35 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 36 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 37 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 38 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 39 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 40 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 41 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 42 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 43 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 44 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 45 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 46 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 47 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 48 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 49 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 50 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 51 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 52 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 53 | - CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, | |
| 54 | - 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, | |
| 55 | -}; | |
| 56 | - | |
| 57 | -/* modulo 17 table */ | |
| 58 | -const uint8_t rclw_table[32] = { | |
| 59 | - 0, 1, 2, 3, 4, 5, 6, 7, | |
| 60 | - 8, 9,10,11,12,13,14,15, | |
| 61 | - 16, 0, 1, 2, 3, 4, 5, 6, | |
| 62 | - 7, 8, 9,10,11,12,13,14, | |
| 63 | -}; | |
| 64 | - | |
| 65 | -/* modulo 9 table */ | |
| 66 | -const uint8_t rclb_table[32] = { | |
| 67 | - 0, 1, 2, 3, 4, 5, 6, 7, | |
| 68 | - 8, 0, 1, 2, 3, 4, 5, 6, | |
| 69 | - 7, 8, 0, 1, 2, 3, 4, 5, | |
| 70 | - 6, 7, 8, 0, 1, 2, 3, 4, | |
| 71 | -}; | |
| 72 | - | |
| 73 | 22 | /* n must be a constant to be efficient */ |
| 74 | 23 | static inline int lshift(int x, int n) |
| 75 | 24 | { |
| ... | ... | @@ -624,33 +573,6 @@ void OPPROTO op_cmpxchg8b(void) |
| 624 | 573 | helper_cmpxchg8b(); |
| 625 | 574 | } |
| 626 | 575 | |
| 627 | -#if defined(__powerpc__) | |
| 628 | - | |
| 629 | -/* on PowerPC we patch the jump instruction directly */ | |
| 630 | -#define JUMP_TB(tbparam, n, eip)\ | |
| 631 | -do {\ | |
| 632 | - static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ | |
| 633 | - asm volatile ("b %0" : : "i" (&__op_jmp ## n));\ | |
| 634 | -label ## n:\ | |
| 635 | - T0 = (long)(tbparam) + (n);\ | |
| 636 | - EIP = eip;\ | |
| 637 | -} while (0) | |
| 638 | - | |
| 639 | -#else | |
| 640 | - | |
| 641 | -/* jump to next block operations (more portable code, does not need | |
| 642 | - cache flushing, but slower because of indirect jump) */ | |
| 643 | -#define JUMP_TB(tbparam, n, eip)\ | |
| 644 | -do {\ | |
| 645 | - static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ | |
| 646 | - goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\ | |
| 647 | -label ## n:\ | |
| 648 | - T0 = (long)(tbparam) + (n);\ | |
| 649 | - EIP = eip;\ | |
| 650 | -} while (0) | |
| 651 | - | |
| 652 | -#endif | |
| 653 | - | |
| 654 | 576 | void OPPROTO op_jmp_tb_next(void) |
| 655 | 577 | { |
| 656 | 578 | JUMP_TB(PARAM1, 0, PARAM2); |
| ... | ... | @@ -1561,6 +1483,8 @@ void OPPROTO op_fist_ST0_A0(void) |
| 1561 | 1483 | |
| 1562 | 1484 | d = ST0; |
| 1563 | 1485 | val = lrint(d); |
| 1486 | + if (val != (int16_t)val) | |
| 1487 | + val = -32768; | |
| 1564 | 1488 | stw((void *)A0, val); |
| 1565 | 1489 | } |
| 1566 | 1490 | ... | ... |