From 596bb6231115aa29cde804c27c899afb4cf03a25 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Sun, 10 Mar 2019 18:54:35 +0100 Subject: 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 --- qtmips_machine/alu.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'qtmips_machine/alu.cpp') 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; -- cgit v1.2.3