diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-03 10:33:05 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-03 10:33:05 +0100 |
commit | 53c75d278a958e40b9c0b0ca3b04cfb11f356827 (patch) | |
tree | 87472f3d8df4b6fbb44fe7b2afd7bf0c89c55035 /qtmips_machine/alu.cpp | |
parent | 12536c28a74e3b1fd6f5d1213311c809f9ddf824 (diff) | |
download | qtmips-53c75d278a958e40b9c0b0ca3b04cfb11f356827.tar.gz qtmips-53c75d278a958e40b9c0b0ca3b04cfb11f356827.tar.bz2 qtmips-53c75d278a958e40b9c0b0ca3b04cfb11f356827.zip |
Implement instructions MULT, MULTU, DIV, DIVU.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine/alu.cpp')
-rw-r--r-- | qtmips_machine/alu.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp index 176a9a5..bb3a745 100644 --- a/qtmips_machine/alu.cpp +++ b/qtmips_machine/alu.cpp @@ -5,6 +5,9 @@ using namespace machine; std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s, std::uint32_t t, std::uint8_t sa, Registers *regs) { + std::int64_t s64_val; + std::uint64_t u64_val; + switch(operation) { case ALU_OP_SLL: return t << sa; @@ -42,6 +45,24 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s, std::u case ALU_OP_MTLO: regs->write_hi_lo(false, s); return 0x0; + case ALU_OP_MULT: + s64_val = (std::int64_t)(std::int32_t)s * (std::int32_t)t; + regs->write_hi_lo(false, (std::uint32_t)(s64_val & 0xffffffff)); + regs->write_hi_lo(true, (std::uint32_t)(s64_val >> 32)); + return 0x0; + case ALU_OP_MULTU: + u64_val = (std::uint64_t)s * t; + regs->write_hi_lo(false, (std::uint32_t)(u64_val & 0xffffffff)); + regs->write_hi_lo(true, (std::uint32_t)(u64_val >> 32)); + return 0x0; + case ALU_OP_DIV: + 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: + regs->write_hi_lo(false, s / t); + regs->write_hi_lo(true, s % t); + return 0x0; case ALU_OP_ADD: /* s(31) ^ ~t(31) ... same signs on input */ /* (s + t)(31) ^ s(31) ... different sign on output */ |