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,6 +19,57 @@ | ||
| 19 | */ | 19 | */ |
| 20 | #include "exec-i386.h" | 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 | const CPU86_LDouble f15rk[7] = | 73 | const CPU86_LDouble f15rk[7] = |
| 23 | { | 74 | { |
| 24 | 0.00000000000000000000L, | 75 | 0.00000000000000000000L, |
| @@ -693,7 +744,29 @@ void helper_fsincos(void) | @@ -693,7 +744,29 @@ void helper_fsincos(void) | ||
| 693 | 744 | ||
| 694 | void helper_frndint(void) | 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 | void helper_fscale(void) | 772 | void helper_fscale(void) |
op-i386.c
| @@ -19,57 +19,6 @@ | @@ -19,57 +19,6 @@ | ||
| 19 | */ | 19 | */ |
| 20 | #include "exec-i386.h" | 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 | /* n must be a constant to be efficient */ | 22 | /* n must be a constant to be efficient */ |
| 74 | static inline int lshift(int x, int n) | 23 | static inline int lshift(int x, int n) |
| 75 | { | 24 | { |
| @@ -624,33 +573,6 @@ void OPPROTO op_cmpxchg8b(void) | @@ -624,33 +573,6 @@ void OPPROTO op_cmpxchg8b(void) | ||
| 624 | helper_cmpxchg8b(); | 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 | void OPPROTO op_jmp_tb_next(void) | 576 | void OPPROTO op_jmp_tb_next(void) |
| 655 | { | 577 | { |
| 656 | JUMP_TB(PARAM1, 0, PARAM2); | 578 | JUMP_TB(PARAM1, 0, PARAM2); |
| @@ -1561,6 +1483,8 @@ void OPPROTO op_fist_ST0_A0(void) | @@ -1561,6 +1483,8 @@ void OPPROTO op_fist_ST0_A0(void) | ||
| 1561 | 1483 | ||
| 1562 | d = ST0; | 1484 | d = ST0; |
| 1563 | val = lrint(d); | 1485 | val = lrint(d); |
| 1486 | + if (val != (int16_t)val) | ||
| 1487 | + val = -32768; | ||
| 1564 | stw((void *)A0, val); | 1488 | stw((void *)A0, val); |
| 1565 | } | 1489 | } |
| 1566 | 1490 |