aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine/alu.cpp
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2017-11-19 21:23:04 +0100
committerKarel Kočí <cynerd@email.cz>2017-11-19 21:23:04 +0100
commitf0ad502e4651243d6a96194b3393bd460c0f7fc9 (patch)
tree4f912c24b5943bd93b5a3378df75f9611de6779b /qtmips_machine/alu.cpp
parent2c6562fa78e884d66b8c2a306f020101e8803f2e (diff)
downloadqtmips-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.cpp51
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("");
}