diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-03-10 18:54:35 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-03-10 18:54:35 +0100 |
commit | 596bb6231115aa29cde804c27c899afb4cf03a25 (patch) | |
tree | d9bfa173e1138b9dd36574bb168ebb4884c6d7f9 /qtmips_machine | |
parent | ab28ba46d6dcbf8539fc724bfbfb982722339036 (diff) | |
download | qtmips-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.cpp | 10 |
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; |