Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add/subtract

2006-05-01 Thread Stefan Weil

Dirk Behme schrieb:


 Fix overflow conditions for MIPS add/subtract as proposed by
 Daniel Jacobowitz.

 http://lists.gnu.org/archive/html/qemu-devel/2006-04/msg00538.html

 Regards

 Dirk



--- target-mips/op.c_orig 2006-04-30 09:40:46.0 +0200
+++ target-mips/op.c 2006-04-30 09:41:52.0 +0200
@@ -206,7 +206,7 @@ void op_addo (void)

 tmp = T0;
 T0 += T1;
- if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
+ if (~(T0 ^ T1)  (T0 ^ tmp)  0x8000) {
 /* operands of same sign, result different sign */
 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
 }
@@ -225,7 +225,7 @@ void op_subo (void)

 tmp = T0;
 T0 = (int32_t)T0 - (int32_t)T1;
- if (((tmp ^ T1)  (tmp ^ T0))  31) {
+ if ((T0 ^ T1)  (T0 ^ tmp)  0x8000) {
 /* operands of different sign, first operand and result different sign */
 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
 }






___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel



Hello Dirk,

which additions / subtractions are handled incorrectly by the current code?
Here is the result of a test which shows that the current code (which is
based on my patch)
raises an exception for 0x8000 + 0x8000.

Daniel, perhaps you could sent the code you used to check overflow
conditions?
Maybe there is no need to change functions op_addo and op_subo for MIPS.

Regards
Stefan

IN:
0x9400: lui v0,0x8000
0x9404: lui v1,0x8000
0x9408: add a0,v0,v1
0x940c: b 0x940c
0x9410: nop

 2 0002
do_raise_exception_err: 19 0
do_interrupt enter: PC 9408 EPC  cause -1 excp 19
do_interrupt: PC bfc00380 EPC 9408 cause 12 excp 19
S 1040 C 0030 A  D 
cpu_mips_handle_mmu_fault pc bfc00380 ad bfc00380 rw 2 is_user 0 smmu 1
cpu_mips_handle_mmu_fault address=bfc00380 ret 0 physical 1fc00380 prot 1

pc=0xbfc00380 HI=0x LO=0x ds 0006  0
GPR00: r0  at  v0 8000 v1 8000
GPR04: a0  a1  a2  a3 
GPR08: t0  t1  t2  t3 
GPR12: t4  t5  t6  t7 
GPR16: s0  s1  s2  s3 
GPR20: s4  s5  s6  s7 
GPR24: t8  t9  k0  k1 
GPR28: gp  sp 94001040 s8  ra 
CP0 Status 0x1046 Cause 0x0030 EPC 0x9408
Config0 0x80008090 Config1 0x1e9b4d8a LLAddr 0x




___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add/subtract

2006-05-01 Thread Fabrice Bellard

OK. I hope this is correct now :-)

Just a note : there is already a lot of code in QEMU to compute 
correctly the overflow and carry flags (for example in the i386 
target)... don't spend your time on reinventing them !


Fabrice.

Dirk Behme wrote:


Fix overflow conditions for MIPS add/subtract as proposed by
Daniel Jacobowitz.

http://lists.gnu.org/archive/html/qemu-devel/2006-04/msg00538.html

Regards

Dirk




--- target-mips/op.c_orig   2006-04-30 09:40:46.0 +0200
+++ target-mips/op.c2006-04-30 09:41:52.0 +0200
@@ -206,7 +206,7 @@ void op_addo (void)
 
 tmp = T0;

 T0 += T1;
-if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
+if (~(T0 ^ T1)  (T0 ^ tmp)  0x8000) {
/* operands of same sign, result different sign */
 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
 }
@@ -225,7 +225,7 @@ void op_subo (void)
 
 tmp = T0;

 T0 = (int32_t)T0 - (int32_t)T1;
-if (((tmp ^ T1)  (tmp ^ T0))  31) {
+if ((T0 ^ T1)  (T0 ^ tmp)  0x8000) {
/* operands of different sign, first operand and result different sign 
*/
 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
 }






___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel




___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add/subtract

2006-05-01 Thread Daniel Jacobowitz
On Mon, May 01, 2006 at 08:42:08PM +0200, Stefan Weil wrote:
 - if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
 + if (~(T0 ^ T1)  (T0 ^ tmp)  0x8000) {

 Hello Dirk,
 
 which additions / subtractions are handled incorrectly by the current code?
 Here is the result of a test which shows that the current code (which is
 based on my patch)
 raises an exception for 0x8000 + 0x8000.
 
 Daniel, perhaps you could sent the code you used to check overflow
 conditions?

I used GDB.

(gdb) set $T0 = 0x8000
(gdb) set $T1 = 0x8000
(gdb) set $tmp = $T0 + $T1
(gdb) p (($tmp ^ $T1 ^ (-1))  ($T0 ^ $T1))  31
$1 = 0

I see no reason why it should be wrong.  $tmp is of course zero.
The high bit of tmp is not the same as the high bit of T1, therefore
$tmp ^ $T1 ^ (-1) == 0.  Therefore the if is false.  I even compiled
and ran the sample - no exception.

Oh, damn!  tmp is not the result, T0 is the result.  No wonder this
didn't make any sense.  I apologize, I'm really batting zero today.


-- 
Daniel Jacobowitz
CodeSourcery


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add/subtract

2006-05-01 Thread Fabrice Bellard
The current code seems correct to me too (it is the same as the x86 
reference).


Fabrice.

Stefan Weil wrote:

Dirk Behme schrieb:

 
  Fix overflow conditions for MIPS add/subtract as proposed by
  Daniel Jacobowitz.
 
  http://lists.gnu.org/archive/html/qemu-devel/2006-04/msg00538.html
 
  Regards
 
  Dirk
 
 
 
 --- target-mips/op.c_orig 2006-04-30 09:40:46.0 +0200
 +++ target-mips/op.c 2006-04-30 09:41:52.0 +0200
 @@ -206,7 +206,7 @@ void op_addo (void)
 
  tmp = T0;
  T0 += T1;
 - if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
 + if (~(T0 ^ T1)  (T0 ^ tmp)  0x8000) {
  /* operands of same sign, result different sign */
  CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
  }
 @@ -225,7 +225,7 @@ void op_subo (void)
 
  tmp = T0;
  T0 = (int32_t)T0 - (int32_t)T1;
 - if (((tmp ^ T1)  (tmp ^ T0))  31) {
 + if ((T0 ^ T1)  (T0 ^ tmp)  0x8000) {
  /* operands of different sign, first operand and result different 
sign */

  CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
  }
 
 
 
 
 
 
 ___
 Qemu-devel mailing list
 Qemu-devel@nongnu.org
 http://lists.nongnu.org/mailman/listinfo/qemu-devel
 
 

Hello Dirk,

which additions / subtractions are handled incorrectly by the current code?
Here is the result of a test which shows that the current code (which is
based on my patch)
raises an exception for 0x8000 + 0x8000.

Daniel, perhaps you could sent the code you used to check overflow
conditions?
Maybe there is no need to change functions op_addo and op_subo for MIPS.

Regards
Stefan

IN:
0x9400: lui v0,0x8000
0x9404: lui v1,0x8000
0x9408: add a0,v0,v1
0x940c: b 0x940c
0x9410: nop

 2 0002
do_raise_exception_err: 19 0
do_interrupt enter: PC 9408 EPC  cause -1 excp 19
do_interrupt: PC bfc00380 EPC 9408 cause 12 excp 19
S 1040 C 0030 A  D 
cpu_mips_handle_mmu_fault pc bfc00380 ad bfc00380 rw 2 is_user 0 smmu 1
cpu_mips_handle_mmu_fault address=bfc00380 ret 0 physical 1fc00380 prot 1

pc=0xbfc00380 HI=0x LO=0x ds 0006  0
GPR00: r0  at  v0 8000 v1 8000
GPR04: a0  a1  a2  a3 
GPR08: t0  t1  t2  t3 
GPR12: t4  t5  t6  t7 
GPR16: s0  s1  s2  s3 
GPR20: s4  s5  s6  s7 
GPR24: t8  t9  k0  k1 
GPR28: gp  sp 94001040 s8  ra 
CP0 Status 0x1046 Cause 0x0030 EPC 0x9408
Config0 0x80008090 Config1 0x1e9b4d8a LLAddr 0x




___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel






___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add / subtract

2006-04-28 Thread Daniel Jacobowitz
On Thu, Apr 13, 2006 at 08:49:19PM +0200, Stefan Weil wrote:
 -if ((T0  31) ^ (T1  31) ^ (tmp  31)) {
 +if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
 +   /* operands of same sign, result different sign */
 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
 }

I see this went in, but - huh?  The math doesn't make sense.

T0 ^ T1 - operands of different sign
tmp ^ T1 ^ (-1) - result has same sign as T1

Which is a who cares case.  This is addition, it can't overflow if
the operands have the same sign.

 -if (!((T0  31) ^ (T1  31) ^ (tmp  31))) {
 +if (((tmp ^ T1)  (tmp ^ T0))  31) {
 +   /* operands of different sign, first operand and result 
 different sign */
 CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
 }

tmp ^ T1 - result and T1 of different sign
tmp ^ T0 - result and T0 of different sign

Which implies that the operands have the same sign.  Again, this case
can't overflow.

I haven't tested the patched qemu, but I did test the expressions
themselves in standalone code, and they definitely do not detect
overflow.

-- 
Daniel Jacobowitz
CodeSourcery


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add / subtract

2006-04-28 Thread Dirk Behme

Daniel Jacobowitz wrote:

I haven't tested the patched qemu, but I did test the expressions
themselves in standalone code, and they definitely do not detect
overflow.


Maybe you can test Ralf's alternative proposal

http://lists.gnu.org/archive/html/qemu-devel/2006-02/msg00154.html

as well?

Thanks

Dirk





___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add / subtract

2006-04-28 Thread Daniel Jacobowitz
On Fri, Apr 28, 2006 at 04:51:39PM +0200, Dirk Behme wrote:
 Daniel Jacobowitz wrote:
 I haven't tested the patched qemu, but I did test the expressions
 themselves in standalone code, and they definitely do not detect
 overflow.
 
 Maybe you can test Ralf's alternative proposal
 
 http://lists.gnu.org/archive/html/qemu-devel/2006-02/msg00154.html
 
 as well?

Using 64-bit math for this would be awful for performance.  My original
checks were wrong; we just need to use a correct fix...  Lightly
tested, but I think this is right for add:

-if ((T0  31) ^ (T1  31) ^ (tmp  31)) {
+if (~(T0 ^ T1)  (T0 ^ tmp)  0x8000) {

And this for sub:

-if (!((T0  31) ^ (T1  31) ^ (tmp  31))) {
+if ((T0 ^ T1)  (T0 ^ tmp)  0x8000) {


-- 
Daniel Jacobowitz
CodeSourcery


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add / subtract

2006-04-28 Thread Julian Seward

  -if ((T0  31) ^ (T1  31) ^ (tmp  31)) {
  +if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
  +   /* operands of same sign, result different sign */
  CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
  }

 I see this went in, but - huh?  The math doesn't make sense.

 T0 ^ T1 - operands of different sign
 tmp ^ T1 ^ (-1) - result has same sign as T1

The definitive reference for all this bit twiddling magic and
much more besides is an excellent book, Hacker's Delight, by
Hank Warren.  It has loads of stuff about integer overflow and
whatnot.

J


___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] [PATCH] Fix overflow conditions for MIPS add / subtract

2006-04-13 Thread Stefan Weil

Hi,

I had problems with MIPS system emulation (AR7 based DSL router)
which were caused by wrong overflow exceptions.

With the patch given below emulation works. See this link for
first results: http://forum.openwrt.org/viewtopic.php?id=4381

In user mode emulation, the MIPS emulation currently ignores
exceptions. So the bug might have an effect on emulation speed
but not on functionality for user mode emulation.

Regards
Stefan Weil

PS. Please include this and also my last MIPS patch in CVS HEAD.


Index: target-mips/op.c
===
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.5
diff -u -b -B -r1.5 op.c
--- target-mips/op.c5 Dec 2005 19:59:36 -   1.5
+++ target-mips/op.c13 Apr 2006 18:38:19 -
@@ -206,7 +206,8 @@

tmp = T0;
T0 += T1;
-if ((T0  31) ^ (T1  31) ^ (tmp  31)) {
+if (((tmp ^ T1 ^ (-1))  (T0 ^ T1))  31) {
+   /* operands of same sign, result different sign */
CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
}
RETURN();
@@ -224,7 +225,8 @@

tmp = T0;
T0 = (int32_t)T0 - (int32_t)T1;
-if (!((T0  31) ^ (T1  31) ^ (tmp  31))) {
+if (((tmp ^ T1)  (tmp ^ T0))  31) {
+   /* operands of different sign, first operand and result 
different sign */

CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW);
}
RETURN();



___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel