diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/ex.cc | 200 | ||||
-rw-r--r-- | src/sim/id.cc | 40 | ||||
-rw-r--r-- | src/sim/stage.cc | 14 |
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; |