aboutsummaryrefslogtreecommitdiff
path: root/sim/mips
diff options
context:
space:
mode:
authorGavin Romig-Koch <gavin@redhat.com>1997-04-21 21:26:17 +0000
committerGavin Romig-Koch <gavin@redhat.com>1997-04-21 21:26:17 +0000
commitd654ba0acf2e16f7c259bde9d86d28826aa66425 (patch)
tree4be82cb1671d6248ec5481d7ed409e09a0fd4853 /sim/mips
parente4bb90271600b757264581fa80c3a4884f9abc8c (diff)
downloadgdb-d654ba0acf2e16f7c259bde9d86d28826aa66425.zip
gdb-d654ba0acf2e16f7c259bde9d86d28826aa66425.tar.gz
gdb-d654ba0acf2e16f7c259bde9d86d28826aa66425.tar.bz2
for DIV: check for div by zero and int overflow
Diffstat (limited to 'sim/mips')
-rw-r--r--sim/mips/ChangeLog6
-rw-r--r--sim/mips/gencode.c53
2 files changed, 44 insertions, 15 deletions
diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog
index f54c1c5..26d4d85 100644
--- a/sim/mips/ChangeLog
+++ b/sim/mips/ChangeLog
@@ -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.
diff --git a/sim/mips/gencode.c b/sim/mips/gencode.c
index 524489e..73521c3 100644
--- a/sim/mips/gencode.c
+++ b/sim/mips/gencode.c
@@ -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:
{