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 | ... | ... |