From d654ba0acf2e16f7c259bde9d86d28826aa66425 Mon Sep 17 00:00:00 2001 From: Gavin Romig-Koch Date: Mon, 21 Apr 1997 21:26:17 +0000 Subject: [PATCH] for DIV: check for div by zero and int overflow --- sim/mips/ChangeLog | 6 ++++++ sim/mips/gencode.c | 53 +++++++++++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/sim/mips/ChangeLog b/sim/mips/ChangeLog index f54c1c551c9..26d4d858af4 100644 --- a/sim/mips/ChangeLog +++ b/sim/mips/ChangeLog @@ -1,3 +1,9 @@ +Mon Apr 21 17:16:13 1997 Gavin Koch + + * 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 * Makefile.in (SIM_OBJS): Add sim-load.o. diff --git a/sim/mips/gencode.c b/sim/mips/gencode.c index 524489e333c..73521c3dc07 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: { -- 2.30.2