Fix qemu SIGFPE caused by division-by-zero due to underflow.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 15 Apr 2007 21:21:33 +0000 (21:21 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 15 Apr 2007 21:21:33 +0000 (21:21 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2673 c046a42c-6fe2-441c-8c8c-71466251a162

target-mips/exec.h
target-mips/op.c
target-mips/op_helper.c

index 54f4d5a..cfe69a3 100644 (file)
@@ -82,6 +82,9 @@ void do_drotrv (void);
 #endif
 #endif
 
+#if HOST_LONG_BITS < 64
+void do_div (void);
+#endif
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 void do_mult (void);
 void do_multu (void);
@@ -89,10 +92,12 @@ void do_madd (void);
 void do_maddu (void);
 void do_msub (void);
 void do_msubu (void);
+#endif
+#ifdef TARGET_MIPS64
 void do_ddiv (void);
+#if TARGET_LONG_BITS > HOST_LONG_BITS
 void do_ddivu (void);
 #endif
-#ifdef TARGET_MIPS64
 void do_dmult (void);
 void do_dmultu (void);
 #endif
index 9e9f8eb..2ea84b6 100644 (file)
@@ -368,14 +368,22 @@ void op_mul (void)
     RETURN();
 }
 
+#if HOST_LONG_BITS < 64
+void op_div (void)
+{
+    CALL_FROM_TB0(do_div);
+    RETURN();
+}
+#else
 void op_div (void)
 {
     if (T1 != 0) {
-        env->LO = (int32_t)((int32_t)T0 / (int32_t)T1);
-        env->HI = (int32_t)((int32_t)T0 % (int32_t)T1);
+        env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
+        env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
     }
     RETURN();
 }
+#endif
 
 void op_divu (void)
 {
@@ -432,7 +440,6 @@ void op_dmul (void)
     RETURN();
 }
 
-#if TARGET_LONG_BITS > HOST_LONG_BITS
 /* Those might call libgcc functions.  */
 void op_ddiv (void)
 {
@@ -440,21 +447,13 @@ void op_ddiv (void)
     RETURN();
 }
 
+#if TARGET_LONG_BITS > HOST_LONG_BITS
 void op_ddivu (void)
 {
     do_ddivu();
     RETURN();
 }
 #else
-void op_ddiv (void)
-{
-    if (T1 != 0) {
-        env->LO = (int64_t)T0 / (int64_t)T1;
-        env->HI = (int64_t)T0 % (int64_t)T1;
-    }
-    RETURN();
-}
-
 void op_ddivu (void)
 {
     if (T1 != 0) {
index 576787d..14696aa 100644 (file)
@@ -216,6 +216,17 @@ void do_msubu (void)
 }
 #endif
 
+#if HOST_LONG_BITS < 64
+void do_div (void)
+{
+    /* 64bit datatypes because we may see overflow/underflow. */
+    if (T1 != 0) {
+        env->LO = (int32_t)((int64_t)(int32_t)T0 / (int32_t)T1);
+        env->HI = (int32_t)((int64_t)(int32_t)T0 % (int32_t)T1);
+    }
+}
+#endif
+
 #ifdef TARGET_MIPS64
 void do_dmult (void)
 {