summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-03-30 12:48:25 -0400
committerbd <bdunahu@operationnull.com>2025-03-30 12:48:25 -0400
commit916949133a5797772dcd6966e469c12230ffc3fa (patch)
treed6385d1021752c8946c8765166bd8f5519b7ceb8
parent6557e7e623140871968776429d241570002a65f5 (diff)
untested ALU type R operations
-rw-r--r--inc/ex.h10
-rw-r--r--src/sim/ex.cc173
2 files changed, 142 insertions, 41 deletions
diff --git a/inc/ex.h b/inc/ex.h
index 4edf873..19c3ac9 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -19,19 +19,13 @@ class EX : public Stage
private:
/**
- * Sets the (over|under)flow condition code if adding `a` and `b` results in
- * either.
- * @param the first operand
- * @param the second operand
- */
- void overflow_guard(signed int a, signed int b);
- /**
* Maps each mnemonic to a function which carries out the instruction's base
* logic.
+ * All instructions store the result into s1.
*/
std::unordered_map<
Mnemonic,
- std::function<void(signed int &s1, signed int &s2)>>
+ std::function<void(signed int &s1, signed int s2)>>
instr_map;
};
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index fbf460f..292337b 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -8,7 +8,7 @@
// clang-format off
#define INIT_INSTRUCTION(mnemonic, body) \
- {mnemonic, [this](signed int &s1, signed int &s2) { \
+ {mnemonic, [this](signed int &s1, signed int s2) { \
body; \
}}
// clang-format on
@@ -22,74 +22,181 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
ADD,
{
- this->overflow_guard(s1, s2);
s1 = s1 + s2;
+ (void)this;
}),
INIT_INSTRUCTION(
SUB,
{
- this->overflow_guard(s1, -s2);
s1 = s1 - s2;
+ (void)this;
}),
- INIT_INSTRUCTION(MUL, {}),
- INIT_INSTRUCTION(QUOT, {}),
- INIT_INSTRUCTION(REM, {}),
- INIT_INSTRUCTION(SFTR, {}),
- INIT_INSTRUCTION(SFTL, {}),
- INIT_INSTRUCTION(AND, {}),
- INIT_INSTRUCTION(OR, {}),
- INIT_INSTRUCTION(NOT, {}),
- INIT_INSTRUCTION(XOR, {}),
- INIT_INSTRUCTION(ADDV, {}),
- INIT_INSTRUCTION(SUBV, {}),
- INIT_INSTRUCTION(MULV, {}),
- INIT_INSTRUCTION(DIVV, {}),
- INIT_INSTRUCTION(CMP, {}),
- INIT_INSTRUCTION(CEV, {}),
+ INIT_INSTRUCTION(
+ MUL,
+ {
+ s1 = s1 * s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ QUOT,
+ {
+ s1 = s1 / s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ REM,
+ {
+ s1 = s1 % s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SFTR,
+ {
+ s1 = s1 >> s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SFTL,
+ {
+ s1 = s1 << s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ AND,
+ {
+ s1 = s1 & s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ OR,
+ {
+ s1 = s1 | s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ NOT,
+ {
+ s1 = ~s1;
+ (void)s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ XOR,
+ {
+ s1 = s1 ^ s2;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ ADDV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ SUBV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ MULV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ DIVV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
+
+ INIT_INSTRUCTION(
+ CMP,
+ {
+ (s1 > s2) ? this->set_condition(GT, true)
+ : this->set_condition(GT, false);
+ (s1 == s2) ? this->set_condition(EQ, true)
+ : this->set_condition(EQ, false);
+ }),
+
+ INIT_INSTRUCTION(
+ CEV,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
/* I type instructions */
INIT_INSTRUCTION(LOAD, {}),
+
INIT_INSTRUCTION(LOADV, {}),
+
INIT_INSTRUCTION(ADDI, {}),
+
INIT_INSTRUCTION(SUBI, {}),
+
INIT_INSTRUCTION(SFTRI, {}),
+
INIT_INSTRUCTION(SFTL, {}),
+
INIT_INSTRUCTION(ANDI, {}),
+
INIT_INSTRUCTION(ORI, {}),
+
INIT_INSTRUCTION(XORI, {}),
+
INIT_INSTRUCTION(STORE, {}),
+
INIT_INSTRUCTION(STOREV, {}),
/* J type instructions */
INIT_INSTRUCTION(JMP, {}),
+
INIT_INSTRUCTION(JRL, {}),
+
INIT_INSTRUCTION(JAL, {}),
+
INIT_INSTRUCTION(BEQ, {}),
+
INIT_INSTRUCTION(BGT, {}),
+
INIT_INSTRUCTION(BUF, {}),
+
INIT_INSTRUCTION(BOF, {}),
+
INIT_INSTRUCTION(PUSH, {}),
+
INIT_INSTRUCTION(POP, {}),
/* NOP */
- INIT_INSTRUCTION(NOP, (void)s2; (void)s1;),
+ INIT_INSTRUCTION(
+ NOP,
+ {
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
};
}
InstrDTO *EX::advance(Response p) { return nullptr; }
-
-void EX::overflow_guard(signed int a, signed int b)
-{
- if (a >= 0 && b >= 0 && (a > MAX_INT - b)) {
- this->set_condition(OF, true);
- this->set_condition(UF, false);
- } else if (a < 0 && b < 0 && (a < (-MAX_INT) - 1 - b)) {
- this->set_condition(OF, false);
- this->set_condition(UF, true);
- } else {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- }
-}