Commit 9c7e37e7fad48f6e7bbafa29f7980a4a9bf191b7
1 parent
c3e10c7b
Fix POWER abs & abso computation.
Fix PowerPC SPE evabs & evneg (thanks to Fabrice Bellard for reporting the bug) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3575 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
10 additions
and
8 deletions
target-ppc/op.c
... | ... | @@ -2199,9 +2199,9 @@ void OPPROTO op_store_601_batu (void) |
2199 | 2199 | /* XXX: those micro-ops need tests ! */ |
2200 | 2200 | void OPPROTO op_POWER_abs (void) |
2201 | 2201 | { |
2202 | - if (T0 == INT32_MIN) | |
2202 | + if ((int32_t)T0 == INT32_MIN) | |
2203 | 2203 | T0 = INT32_MAX; |
2204 | - else if (T0 < 0) | |
2204 | + else if ((int32_t)T0 < 0) | |
2205 | 2205 | T0 = -T0; |
2206 | 2206 | RETURN(); |
2207 | 2207 | } | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -1512,14 +1512,16 @@ void do_td (int flags) |
1512 | 1512 | /* PowerPC 601 specific instructions (POWER bridge) */ |
1513 | 1513 | void do_POWER_abso (void) |
1514 | 1514 | { |
1515 | - if ((uint32_t)T0 == INT32_MIN) { | |
1515 | + if ((int32_t)T0 == INT32_MIN) { | |
1516 | 1516 | T0 = INT32_MAX; |
1517 | 1517 | xer_ov = 1; |
1518 | - xer_so = 1; | |
1519 | - } else { | |
1518 | + } else if ((int32_t)T0 < 0) { | |
1520 | 1519 | T0 = -T0; |
1521 | 1520 | xer_ov = 0; |
1521 | + } else { | |
1522 | + xer_ov = 0; | |
1522 | 1523 | } |
1524 | + xer_so |= xer_ov; | |
1523 | 1525 | } |
1524 | 1526 | |
1525 | 1527 | void do_POWER_clcs (void) |
... | ... | @@ -1896,8 +1898,8 @@ void do_ev##name (void) \ |
1896 | 1898 | /* Fixed-point vector arithmetic */ |
1897 | 1899 | static always_inline uint32_t _do_eabs (uint32_t val) |
1898 | 1900 | { |
1899 | - if (val != 0x80000000) | |
1900 | - val &= ~0x80000000; | |
1901 | + if ((val & 0x80000000) && val != 0x80000000) | |
1902 | + val -= val; | |
1901 | 1903 | |
1902 | 1904 | return val; |
1903 | 1905 | } |
... | ... | @@ -1923,7 +1925,7 @@ static always_inline int _do_ecntlzw (uint32_t val) |
1923 | 1925 | static always_inline uint32_t _do_eneg (uint32_t val) |
1924 | 1926 | { |
1925 | 1927 | if (val != 0x80000000) |
1926 | - val ^= 0x80000000; | |
1928 | + val -= val; | |
1927 | 1929 | |
1928 | 1930 | return val; |
1929 | 1931 | } | ... | ... |