diff options
author | Siddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com> | 2025-04-22 15:23:50 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-22 15:23:50 -0400 |
commit | 3d0133c2f793e82d7519d8e2c5023114cd0f0eab (patch) | |
tree | b262ededf7e993090d7a860b76ca528b5651c3c6 /src | |
parent | 1250359dfcbcad18c0a1078290f95479aa23e26a (diff) | |
parent | 86a6253a2fb2d016a63e57d6a5e5461df87668e5 (diff) |
Merge pull request #67 from bdunahu/bdunahu
add RET instruction, JAL ob1 error (full subroutine support), condition codes for everything but shifts
Diffstat (limited to 'src')
-rw-r--r-- | src/sim/ex.cc | 42 | ||||
-rw-r--r-- | src/sim/id.cc | 5 | ||||
-rw-r--r-- | src/sim/instr.cc | 2 | ||||
-rw-r--r-- | src/sim/wb.cc | 2 |
4 files changed, 46 insertions, 5 deletions
diff --git a/src/sim/ex.cc b/src/sim/ex.cc index f098917..d345ecf 100644 --- a/src/sim/ex.cc +++ b/src/sim/ex.cc @@ -39,6 +39,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( ADD, { + this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); + this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); s1 = s1 + s2; (void)pc; (void)s3; @@ -48,6 +50,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( SUB, { + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); s1 = s1 - s2; (void)pc; (void)s3; @@ -57,6 +61,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( MUL, { + this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); + this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); s1 = s1 * s2; (void)pc; (void)s3; @@ -75,7 +81,6 @@ EX::EX(Stage *stage) : Stage(stage) REM, { this->handle_divide(s1, s2, true); - s1 = s1 % s2; (void)pc; (void)s3; (void)this; @@ -102,6 +107,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( AND, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 & s2; (void)pc; (void)s3; @@ -111,6 +118,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( OR, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 | s2; (void)pc; (void)s3; @@ -120,6 +129,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( NOT, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = ~s1; (void)pc; (void)s3; @@ -130,6 +141,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( XOR, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 ^ s2; (void)pc; (void)s3; @@ -220,6 +233,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( ADDI, { + this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); + this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); s1 = s1 + s3; (void)pc; (void)s2; @@ -229,6 +244,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( SUBI, { + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); s1 = s1 - s3; (void)pc; (void)s2; @@ -256,6 +273,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( ANDI, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 & s3; (void)pc; (void)s2; @@ -265,6 +284,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( ORI, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 | s3; (void)pc; (void)s2; @@ -274,6 +295,8 @@ EX::EX(Stage *stage) : Stage(stage) INIT_INSTRUCTION( XORI, { + this->set_condition(OF, false); + this->set_condition(UF, false); s1 = s1 ^ s3; (void)pc; (void)s2; @@ -372,6 +395,16 @@ EX::EX(Stage *stage) : Stage(stage) (void)this; }), + INIT_INSTRUCTION( + RET, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + /* NOP */ INIT_INSTRUCTION( NOP, @@ -405,12 +438,17 @@ void EX::advance_helper() void EX::handle_divide(signed int &s1, signed int s2, bool is_mod) { + this->set_condition(OF, DIVISION_OF_GUARD(s1, s2)); + this->set_condition(UF, false); if (s2 == 0) { // handle everything here this->curr_instr->set_s1(MAX_INT); this->status = OK; throw HaltException(); + } else if ((s1 == -(MAX_INT)-1) && s2 == -1) { + // undefined in C++ + s1 = -(MAX_INT)-1; } else { - s1 = (is_mod) ? s1 % s2 : s1 / s2; + s1 = (is_mod) ? (s1 % s2) : (s1 / s2); } } diff --git a/src/sim/id.cc b/src/sim/id.cc index 3753f83..cdbaba9 100644 --- a/src/sim/id.cc +++ b/src/sim/id.cc @@ -211,8 +211,11 @@ void ID::decode_J_type( } this->status = r1; break; + case RET: + s1 = 1; // link register + [[fallthrough]]; default: - this->status = this->read_guard(*&s1); + this->status = this->read_guard(s1); } } diff --git a/src/sim/instr.cc b/src/sim/instr.cc index c8d1039..9bd951b 100644 --- a/src/sim/instr.cc +++ b/src/sim/instr.cc @@ -35,6 +35,6 @@ const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = { {0b0101101, STOREV}, {0b0000110, JMP}, {0b0001010, JRL}, {0b0001110, JAL}, {0b0010010, BEQ}, {0b0010110, BGT}, {0b0011010, BUF}, {0b0011110, BOF}, {0b0100010, PUSH}, - {0b0100110, POP}, + {0b0100110, POP}, {0b0101010, RET}, }; } // namespace instr diff --git a/src/sim/wb.cc b/src/sim/wb.cc index fbbdd4c..0348b51 100644 --- a/src/sim/wb.cc +++ b/src/sim/wb.cc @@ -62,7 +62,7 @@ void WB::jump_handler() { if (this->curr_instr->get_s1() > 0) { if (this->curr_instr->get_mnemonic() == JAL) - this->gprs[1] = this->pc + 1; + this->gprs[1] = this->curr_instr->get_pc() + 1;; this->pc = this->curr_instr->get_s1(); this->checked_out = {}; this->next->squash(); |