Commit 9c7e37e7fad48f6e7bbafa29f7980a4a9bf191b7

Authored by j_mayer
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
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 }
... ...