summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/ex.cc200
-rw-r--r--src/sim/id.cc40
-rw-r--r--src/sim/stage.cc14
3 files changed, 208 insertions, 46 deletions
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index 50882d2..95cce8d 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, signed int s3) { \
body; \
}}
// clang-format on
@@ -23,6 +23,7 @@ EX::EX(Stage *stage) : Stage(stage)
ADD,
{
s1 = s1 + s2;
+ (void)s3;
(void)this;
}),
@@ -30,6 +31,7 @@ EX::EX(Stage *stage) : Stage(stage)
SUB,
{
s1 = s1 - s2;
+ (void)s3;
(void)this;
}),
@@ -37,6 +39,7 @@ EX::EX(Stage *stage) : Stage(stage)
MUL,
{
s1 = s1 * s2;
+ (void)s3;
(void)this;
}),
@@ -44,6 +47,7 @@ EX::EX(Stage *stage) : Stage(stage)
QUOT,
{
s1 = s1 / s2;
+ (void)s3;
(void)this;
}),
@@ -51,6 +55,7 @@ EX::EX(Stage *stage) : Stage(stage)
REM,
{
s1 = s1 % s2;
+ (void)s3;
(void)this;
}),
@@ -58,6 +63,7 @@ EX::EX(Stage *stage) : Stage(stage)
SFTR,
{
s1 = s1 >> s2;
+ (void)s3;
(void)this;
}),
@@ -65,6 +71,7 @@ EX::EX(Stage *stage) : Stage(stage)
SFTL,
{
s1 = s1 << s2;
+ (void)s3;
(void)this;
}),
@@ -72,6 +79,7 @@ EX::EX(Stage *stage) : Stage(stage)
AND,
{
s1 = s1 & s2;
+ (void)s3;
(void)this;
}),
@@ -79,6 +87,7 @@ EX::EX(Stage *stage) : Stage(stage)
OR,
{
s1 = s1 | s2;
+ (void)s3;
(void)this;
}),
@@ -86,6 +95,7 @@ EX::EX(Stage *stage) : Stage(stage)
NOT,
{
s1 = ~s1;
+ (void)s3;
(void)s2;
(void)this;
}),
@@ -94,12 +104,14 @@ EX::EX(Stage *stage) : Stage(stage)
XOR,
{
s1 = s1 ^ s2;
+ (void)s3;
(void)this;
}),
INIT_INSTRUCTION(
ADDV,
{
+ (void)s3;
(void)s2;
(void)s1;
(void)this;
@@ -108,6 +120,7 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
SUBV,
{
+ (void)s3;
(void)s2;
(void)s1;
(void)this;
@@ -116,6 +129,7 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
MULV,
{
+ (void)s3;
(void)s2;
(void)s1;
(void)this;
@@ -124,6 +138,7 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
DIVV,
{
+ (void)s3;
(void)s2;
(void)s1;
(void)this;
@@ -136,62 +151,185 @@ EX::EX(Stage *stage) : Stage(stage)
: this->set_condition(GT, false);
(s1 == s2) ? this->set_condition(EQ, true)
: this->set_condition(EQ, false);
+ (void)s3;
}),
INIT_INSTRUCTION(
CEV,
{
+ (void)s3;
(void)s2;
(void)s1;
(void)this;
}),
/* I type instructions */
- INIT_INSTRUCTION(LOAD, {}),
+ INIT_INSTRUCTION(
+ LOAD,
+ {
+ s1 = s1 + s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(LOADV, {}),
+ INIT_INSTRUCTION(
+ LOADV,
+ {
+ (void)s3;
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
- INIT_INSTRUCTION(ADDI, {}),
+ INIT_INSTRUCTION(
+ ADDI,
+ {
+ s1 = s1 + s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(SUBI, {}),
+ INIT_INSTRUCTION(
+ SUBI,
+ {
+ s1 = s1 - s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(SFTRI, {}),
+ INIT_INSTRUCTION(
+ SFTRI,
+ {
+ s1 = s1 >> s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(SFTL, {}),
+ INIT_INSTRUCTION(
+ SFTLI,
+ {
+ s1 = s1 << s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(ANDI, {}),
+ INIT_INSTRUCTION(
+ ANDI,
+ {
+ s1 = s1 & s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(ORI, {}),
+ INIT_INSTRUCTION(
+ ORI,
+ {
+ s1 = s1 | s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(XORI, {}),
+ INIT_INSTRUCTION(
+ XORI,
+ {
+ s1 = s1 ^ s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(STORE, {}),
+ INIT_INSTRUCTION(
+ STORE,
+ {
+ s1 = s1 + s3;
+ (void)s2;
+ (void)this;
+ }),
- INIT_INSTRUCTION(STOREV, {}),
+ INIT_INSTRUCTION(
+ STOREV,
+ {
+ (void)s3;
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
/* J type instructions */
- INIT_INSTRUCTION(JMP, {}),
+ INIT_INSTRUCTION(
+ JMP,
+ {
+ s1 = s1 + s2;
+ (void)s3;
+ (void)this;
+ }),
- INIT_INSTRUCTION(JRL, {}),
+ INIT_INSTRUCTION(
+ JRL,
+ {
+ s1 = this->pc + s2;
+ (void)s3;
+ (void)this;
+ }),
- INIT_INSTRUCTION(JAL, {}),
+ INIT_INSTRUCTION(
+ JAL,
+ {
+ s1 = s1 + s2;
+ (void)s3;
+ (void)this;
+ }),
- INIT_INSTRUCTION(BEQ, {}),
+ INIT_INSTRUCTION(
+ BEQ,
+ {
+ s1 = this->pc + s2;
+ (void)s3;
+ }),
- INIT_INSTRUCTION(BGT, {}),
+ INIT_INSTRUCTION(
+ BGT,
+ {
+ s1 = this->pc + s2;
+ (void)s3;
+ }),
- INIT_INSTRUCTION(BUF, {}),
+ INIT_INSTRUCTION(
+ BUF,
+ {
+ s1 = this->pc + s2;
+ (void)s3;
+ }),
- INIT_INSTRUCTION(BOF, {}),
+ INIT_INSTRUCTION(
+ BOF,
+ {
+ s1 = this->pc + s2;
+ (void)s3;
+ }),
- INIT_INSTRUCTION(PUSH, {}),
+ INIT_INSTRUCTION(
+ PUSH,
+ {
+ (void)s3;
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
- INIT_INSTRUCTION(POP, {}),
+ INIT_INSTRUCTION(
+ POP,
+ {
+ (void)s3;
+ (void)s2;
+ (void)s1;
+ (void)this;
+ }),
/* NOP */
INIT_INSTRUCTION(
NOP,
{
+ (void)s3;
(void)s2;
(void)s1;
(void)this;
@@ -199,4 +337,22 @@ EX::EX(Stage *stage) : Stage(stage)
};
}
-void EX::advance_helper() {}
+void EX::advance_helper()
+{
+ signed int s1, s2, s3;
+ Mnemonic m;
+
+ // it may be good to ensure we are not doing
+ // work that has already been done
+ if (this->curr_instr) {
+ m = this->curr_instr->get_mnemonic();
+ s1 = this->curr_instr->get_s1();
+ s2 = this->curr_instr->get_s2();
+ s3 = this->curr_instr->get_s3();
+
+ this->instr_map[m](s1, s2, s3);
+
+ this->curr_instr->set_s1(s1);
+ this->status = OK;
+ }
+}
diff --git a/src/sim/id.cc b/src/sim/id.cc
index 36addbb..edf74e2 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -8,25 +8,6 @@
ID::ID(Stage *stage) : Stage(stage) { this->id = DCDE; }
-void ID::get_instr_fields(
- signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
-{
- unsigned int type;
- this->split_instr(s1, type, m);
-
- switch (type) {
- case 0b00:
- this->decode_R_type(s1, s2, s3);
- break;
- case 0b01:
- this->decode_I_type(s1, s2, s3);
- break;
- case 0b10:
- this->decode_J_type(s1, s2);
- break;
- }
-}
-
void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m)
{
unsigned int opcode, opcode_size;
@@ -80,6 +61,27 @@ void ID::advance_helper()
}
}
+void ID::get_instr_fields(
+ signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
+{
+ unsigned int type;
+ this->split_instr(s1, type, m);
+
+ switch (type) {
+ case 0b00:
+ this->decode_R_type(s1, s2, s3);
+ break;
+ case 0b01:
+ this->decode_I_type(s1, s2, s3);
+ break;
+ case 0b10:
+ this->decode_J_type(s1, s2);
+ break;
+ case 0b11:
+ this->status = OK;
+ }
+}
+
void ID::decode_R_type(signed int &s1, signed int &s2, signed int &s3)
{
unsigned int s0b, s1b, s2b;
diff --git a/src/sim/stage.cc b/src/sim/stage.cc
index 929a4b9..2c03741 100644
--- a/src/sim/stage.cc
+++ b/src/sim/stage.cc
@@ -21,6 +21,14 @@ Storage *Stage::storage;
bool Stage::is_pipelined;
int Stage::clock_cycle;
+bool Stage::get_condition(CC c) {
+ return (this->gprs[3] >> c) & 1;
+}
+
+void Stage::set_pc(unsigned int pc) {
+ this->pc = pc;
+}
+
InstrDTO *Stage::advance(Response p)
{
InstrDTO *r = nullptr;
@@ -45,15 +53,11 @@ InstrDTO *Stage::advance(Response p)
void Stage::set_condition(CC c, bool v)
{
if (v)
- this->gprs[3] = this->gprs[3] & 1 << c;
+ this->gprs[3] = this->gprs[3] | 1 << c;
else
this->gprs[3] = this->gprs[3] & ~(1 << c);
}
-bool Stage::get_condition(CC c) {
- return (this->gprs[3] >> c) & 1;
-}
-
signed int Stage::dereference_register(signed int v)
{
signed int r;