diff options
author | Karel Kočí <cynerd@email.cz> | 2017-11-19 21:23:04 +0100 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2017-11-19 21:23:04 +0100 |
commit | f0ad502e4651243d6a96194b3393bd460c0f7fc9 (patch) | |
tree | 4f912c24b5943bd93b5a3378df75f9611de6779b /qtmips_machine/alu.cpp | |
parent | 2c6562fa78e884d66b8c2a306f020101e8803f2e (diff) | |
download | qtmips-f0ad502e4651243d6a96194b3393bd460c0f7fc9.tar.gz qtmips-f0ad502e4651243d6a96194b3393bd460c0f7fc9.tar.bz2 qtmips-f0ad502e4651243d6a96194b3393bd460c0f7fc9.zip |
Another huge pile of work for about two months
Well I should commit every change instead of this madness. I am not
documenting changes as all this is just improvements and implementation
progression.
Diffstat (limited to 'qtmips_machine/alu.cpp')
-rw-r--r-- | qtmips_machine/alu.cpp | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp index 5c74a5d..85bc804 100644 --- a/qtmips_machine/alu.cpp +++ b/qtmips_machine/alu.cpp @@ -1,6 +1,53 @@ #include "alu.h" +#include "qtmipsexception.h" -Alu::Alu() -{ +std::uint32_t alu_operate(enum AluOp operation, std::uint32_t s, std::uint32_t t, std::uint8_t sa) { + switch(operation) { + case ALU_OP_SLL: + return t << sa; + case ALU_OP_SRL: + return t >> sa; + case ALU_OP_SRA: + // TODO is this correct implementation? (Shouldn't we be masking top most bit?) + return (t >> sa) | (t & 0x80000000); + case ALU_OP_SLLV: + return t << s; + case ALU_OP_SRLV: + return t >> s; + case ALU_OP_SRAV: + // TODO is this correct implementation? (Shouldn't we be masking top most bit?) + return (t >> s) | (t & 0x80000000); + case ALU_OP_ADD: + if (s > (0xFFFFFFFF - t)) + throw QTMIPS_EXCEPTION(Overflow, "ADD operation overflow/underflow", QString::number(s) + QString(" + ") + QString::number(t)); + // Intentional falltrough + case ALU_OP_ADDU: + return s + t; + case ALU_OP_SUB: + if (s < t) + throw QTMIPS_EXCEPTION(Overflow, "SUB operation overflow/underflow", QString::number(s) + QString(" - ") + QString::number(t)); + // Intentional falltrough + case ALU_OP_SUBU: + return s - t; + case ALU_OP_AND: + return s & t; + case ALU_OP_OR: + return s | t; + case ALU_OP_XOR: + return s ^ t; + case ALU_OP_NOR: + return ~(s | t); + case ALU_OP_SLTU: + // TODO is this correct implementation? (this is two's complement signed representation so do we care?) + // Intentional falltrough + case ALU_OP_SLT: + return (s < t) ? 1 : 0; + default: + throw QTMIPS_EXCEPTION(UnsupportedAluOperation, "Unknown ALU operation", QString::number(operation, 16)); + } +} +QString alu_str(enum AluOp operation, std::uint32_t s, std::uint32_t t, std::uint8_t sa) { + // TODO + return QString(""); } |