for DIV: check for div by zero and int overflow
authorGavin Romig-Koch <gavin@redhat.com>
Mon, 21 Apr 1997 21:26:17 +0000 (21:26 +0000)
committerGavin Romig-Koch <gavin@redhat.com>
Mon, 21 Apr 1997 21:26:17 +0000 (21:26 +0000)
sim/mips/ChangeLog
sim/mips/gencode.c

index f54c1c551c94c8dc2ab3e02b241f22a2bbea35f9..26d4d858af497c91728c91c71fda39a94c4b907e 100644 (file)
@@ -1,3 +1,9 @@
+Mon Apr 21 17:16:13 1997  Gavin Koch  <gavin@cygnus.com>
+
+       * gencode.c (build_instruction): DIV instructions: check 
+       for division by zero and integer overflow before using 
+       host's division operation.
+
 Thu Apr 17 03:18:14 1997  Doug Evans  <dje@canuck.cygnus.com>
 
        * Makefile.in (SIM_OBJS): Add sim-load.o.
index 524489e333caec3bee58a7d1804cd6b32c9d035d..73521c3dc0749e04128e532bed39f19b31592bc1 100644 (file)
@@ -2241,30 +2241,53 @@ build_instruction (doisa, features, mips16, insn)
     case DIV:
      {
       int boolU = (insn->flags & UNSIGNED);
-      int pipe1 = (insn->flags & PIPE1);
+      char* pipe = (insn->flags & PIPE1) ? "1" : "";
 
       if (features & FEATURE_WARN_LOHI) {
-       printf("   CHECKHILO(\"Division\");\n");
+        printf("   CHECKHILO(\"Division\");\n");
       }
       printf("   {\n");
+
       if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
-       printf("   LO%s = ((%sword64)op1 / (%sword64)op2);\n",
-               (pipe1 ? "1" : ""),
-               (boolU ? "u" : ""),(boolU ? "u" : ""));
-       printf("   HI%s = ((%sword64)op1 %c (%sword64)op2);\n",
-               (pipe1 ? "1" : ""),
-               (boolU ? "u" : ""),'%',(boolU ? "u" : ""));
+        printf("   %sword64 d1 = op1;\n", (boolU ? "u" : ""));
+        printf("   %sword64 d2 = op2;\n", (boolU ? "u" : ""));
+        printf("   if (d2 == 0)\n");
+        printf("     {\n");
+        printf("     LO%s = 0x8000000000000000LL;\n", pipe);
+        printf("     HI%s = 0;\n", pipe);
+        printf("     }\n");
+        printf("   else if (d2 == -1 && d1 == 0x8000000000000000LL)\n");
+        printf("     {\n");
+        printf("     LO%s = 0x8000000000000000LL;\n", pipe);
+        printf("     HI%s = 0;\n", pipe);
+        printf("     }\n");
+        printf("   else\n");
+        printf("     {\n");
+        printf("     LO%s = (d1 / d2);\n", pipe);
+        printf("     HI%s = (d1 %% d2);\n", pipe);
+        printf("     }\n");
       } else {
-       printf("   LO%s = SIGNEXTEND(((%sint)op1 / (%sint)op2),32);\n",
-               (pipe1 ? "1" : ""),
-               (boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
-       printf("   HI%s = SIGNEXTEND(((%sint)op1 %c (%sint)op2),32);\n",
-               (pipe1 ? "1" : ""),
-               (boolU ? "unsigned " : ""),'%',(boolU ? "unsigned " : ""));
+        printf("   %sint d1 = op1;\n", (boolU ? "unsigned " : ""));
+        printf("   %sint d2 = op2;\n", (boolU ? "unsigned " : ""));
+        printf("   if (d2 == 0)\n");
+        printf("     {\n");
+       printf("     LO%s = SIGNEXTEND(0x80000000,32);\n",pipe);
+       printf("     HI%s = SIGNEXTEND(0,32);\n", pipe);
+        printf("     }\n");
+        printf("   else if (d2 == -1 && d1 == 0x80000000)\n");
+        printf("     {\n");
+       printf("     LO%s = SIGNEXTEND(0x80000000,32);\n",pipe);
+       printf("     HI%s = SIGNEXTEND(0,32);\n", pipe);
+        printf("     }\n");
+        printf("   else\n");
+        printf("     {\n");
+       printf("     LO%s = SIGNEXTEND((d1 / d2),32);\n", pipe);
+       printf("     HI%s = SIGNEXTEND((d1 %% d2),32);\n", pipe);
+        printf("     }\n");
       }
       printf("   }\n");
      }
-     break ;
+    break ;
 
     case SHIFT:
      {