Re: [Qemu-devel] [PATCH] Fix overflow conditions for MIPS add/subtract
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
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
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
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
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
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
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
-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
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