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,9 +2199,9 @@ void OPPROTO op_store_601_batu (void)
2199 /* XXX: those micro-ops need tests ! */ 2199 /* XXX: those micro-ops need tests ! */
2200 void OPPROTO op_POWER_abs (void) 2200 void OPPROTO op_POWER_abs (void)
2201 { 2201 {
2202 - if (T0 == INT32_MIN) 2202 + if ((int32_t)T0 == INT32_MIN)
2203 T0 = INT32_MAX; 2203 T0 = INT32_MAX;
2204 - else if (T0 < 0) 2204 + else if ((int32_t)T0 < 0)
2205 T0 = -T0; 2205 T0 = -T0;
2206 RETURN(); 2206 RETURN();
2207 } 2207 }
target-ppc/op_helper.c
@@ -1512,14 +1512,16 @@ void do_td (int flags) @@ -1512,14 +1512,16 @@ void do_td (int flags)
1512 /* PowerPC 601 specific instructions (POWER bridge) */ 1512 /* PowerPC 601 specific instructions (POWER bridge) */
1513 void do_POWER_abso (void) 1513 void do_POWER_abso (void)
1514 { 1514 {
1515 - if ((uint32_t)T0 == INT32_MIN) { 1515 + if ((int32_t)T0 == INT32_MIN) {
1516 T0 = INT32_MAX; 1516 T0 = INT32_MAX;
1517 xer_ov = 1; 1517 xer_ov = 1;
1518 - xer_so = 1;  
1519 - } else { 1518 + } else if ((int32_t)T0 < 0) {
1520 T0 = -T0; 1519 T0 = -T0;
1521 xer_ov = 0; 1520 xer_ov = 0;
  1521 + } else {
  1522 + xer_ov = 0;
1522 } 1523 }
  1524 + xer_so |= xer_ov;
1523 } 1525 }
1524 1526
1525 void do_POWER_clcs (void) 1527 void do_POWER_clcs (void)
@@ -1896,8 +1898,8 @@ void do_ev##name (void) \ @@ -1896,8 +1898,8 @@ void do_ev##name (void) \
1896 /* Fixed-point vector arithmetic */ 1898 /* Fixed-point vector arithmetic */
1897 static always_inline uint32_t _do_eabs (uint32_t val) 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 return val; 1904 return val;
1903 } 1905 }
@@ -1923,7 +1925,7 @@ static always_inline int _do_ecntlzw (uint32_t val) @@ -1923,7 +1925,7 @@ static always_inline int _do_ecntlzw (uint32_t val)
1923 static always_inline uint32_t _do_eneg (uint32_t val) 1925 static always_inline uint32_t _do_eneg (uint32_t val)
1924 { 1926 {
1925 if (val != 0x80000000) 1927 if (val != 0x80000000)
1926 - val ^= 0x80000000; 1928 + val -= val;
1927 1929
1928 return val; 1930 return val;
1929 } 1931 }