diff options
author | Siddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com> | 2025-04-27 09:12:50 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-27 09:12:50 -0400 |
commit | 5653b2a033e7a4173d2f178b5ce52384666d3d7b (patch) | |
tree | 5c8fc7282ad1ce0c215786a70b35296645df2a1b /src/ex.cc | |
parent | 3d0133c2f793e82d7519d8e2c5023114cd0f0eab (diff) | |
parent | a4dd1f00a5d0108058fb3bfbd5f399a507792859 (diff) |
Merge pull request #68 from bdunahu/bdunahu
[WIP] Pipeline cleanup and revisited GUI storage display
Diffstat (limited to 'src/ex.cc')
-rw-r--r-- | src/ex.cc | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/src/ex.cc b/src/ex.cc new file mode 100644 index 0000000..eac24ff --- /dev/null +++ b/src/ex.cc @@ -0,0 +1,452 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +#include "ex.h" +#include "instrDTO.h" +#include "pipe_spec.h" +#include "response.h" +#include "stage.h" +#include <unordered_map> + +// clang-format off +#define INIT_INSTRUCTION(mnemonic, body) \ + {mnemonic, [this](signed int &s1, signed int s2, signed int s3, unsigned int pc) { \ + body; \ + }} +// clang-format on + +EX::EX(Stage *stage) : Stage(stage) +{ + instr_map = { + + /* R type instructions */ + 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; + (void)this; + }), + + 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; + (void)this; + }), + + 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; + (void)this; + }), + + INIT_INSTRUCTION( + QUOT, + { + this->handle_divide(s1, s2, false); + (void)pc; + (void)s3; + }), + + INIT_INSTRUCTION( + REM, + { + this->handle_divide(s1, s2, true); + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + SFTR, + { + s1 = s1 >> s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + SFTL, + { + s1 = s1 << s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + AND, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = s1 & s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + OR, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = s1 | s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + NOT, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = ~s1; + (void)pc; + (void)s3; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + XOR, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = s1 ^ s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + ADDV, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + INIT_INSTRUCTION( + SUBV, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + INIT_INSTRUCTION( + MULV, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + INIT_INSTRUCTION( + DIVV, + { + (void)pc; + (void)s3; + (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); + (void)pc; + (void)s3; + }), + + INIT_INSTRUCTION( + CEV, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + /* I type instructions */ + INIT_INSTRUCTION( + LOAD, + { + s1 = s1 + s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + LOADV, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + 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; + (void)this; + }), + + 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; + (void)this; + }), + + INIT_INSTRUCTION( + SFTRI, + { + s1 = s1 >> s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + SFTLI, + { + s1 = s1 << s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + ANDI, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = s1 & s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + ORI, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = s1 | s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + XORI, + { + this->set_condition(OF, false); + this->set_condition(UF, false); + s1 = s1 ^ s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + STORE, + { + s1 = s1 + s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + STOREV, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + /* J type instructions */ + INIT_INSTRUCTION( + JMP, + { + s1 = s1 + s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + JRL, + { + s1 = pc + s2; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + JAL, + { + s1 = s1 + s2; + (void)pc; + (void)s3; + (void)this; + }), + + INIT_INSTRUCTION( + BEQ, + { + (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1; + (void)s3; + }), + + INIT_INSTRUCTION( + BGT, + { + (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1; + (void)s3; + }), + + INIT_INSTRUCTION( + BUF, + { + (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1; + (void)s3; + }), + + INIT_INSTRUCTION( + BOF, + { + (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; + (void)s3; + }), + + INIT_INSTRUCTION( + PUSH, + { + s1 = s1 + s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + POP, + { + s1 = s1 + s3; + (void)pc; + (void)s2; + (void)this; + }), + + INIT_INSTRUCTION( + RET, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + + /* NOP */ + INIT_INSTRUCTION( + NOP, + { + (void)pc; + (void)s3; + (void)s2; + (void)s1; + (void)this; + }), + }; +} + +void EX::advance_helper() +{ + signed int s1, s2, s3; + unsigned int pc; + Mnemonic m; + + m = this->curr_instr->mnemonic; + s1 = this->curr_instr->operands.integer.slot_one; + s2 = this->curr_instr->operands.integer.slot_two; + s3 = this->curr_instr->operands.integer.slot_three; + pc = this->curr_instr->slot_B; + + this->instr_map[m](s1, s2, s3, pc); + + this->curr_instr->operands.integer.slot_one = s1; + this->status = OK; +} + +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->operands.integer.slot_one = 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); + } +} |