aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-03-10 18:54:35 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-03-10 18:54:35 +0100
commit596bb6231115aa29cde804c27c899afb4cf03a25 (patch)
treed9bfa173e1138b9dd36574bb168ebb4884c6d7f9 /qtmips_machine
parentab28ba46d6dcbf8539fc724bfbfb982722339036 (diff)
downloadqtmips-596bb6231115aa29cde804c27c899afb4cf03a25.tar.gz
qtmips-596bb6231115aa29cde804c27c899afb4cf03a25.tar.bz2
qtmips-596bb6231115aa29cde804c27c899afb4cf03a25.zip
Fix program end by exception if divisor is zero for div instruction.
Problem reported by Jakub Broz. Correct behaviour according to MIPS Architecture for Programmers Volume II-A: The MIPS32 Instruction Set Manual which describes DIV instruction Format: DIV rs, rt No arithmetic exception occurs under any circumstances. Restrictions: If the divisor in GPR rt is zero, the arithmetic result value is UNPREDICTABLE. Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine')
-rw-r--r--qtmips_machine/alu.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp
index 3889b44..fbbaff4 100644
--- a/qtmips_machine/alu.cpp
+++ b/qtmips_machine/alu.cpp
@@ -154,10 +154,20 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s,
alu_write_hi_lo_64bit(regs, u64_val);
return 0x0;
case ALU_OP_DIV:
+ if (t == 0) {
+ regs->write_hi_lo(false, 0);
+ regs->write_hi_lo(true, 0);
+ return 0;
+ }
regs->write_hi_lo(false, (std::uint32_t)((std::int32_t)s / (std::int32_t)t));
regs->write_hi_lo(true, (std::uint32_t)((std::int32_t)s % (std::int32_t)t));
return 0x0;
case ALU_OP_DIVU:
+ if (t == 0) {
+ regs->write_hi_lo(false, 0);
+ regs->write_hi_lo(true, 0);
+ return 0;
+ }
regs->write_hi_lo(false, s / t);
regs->write_hi_lo(true, s % t);
return 0x0;