#include "stage.h" #include "utils.h" #include #include Stage::Stage(Stage *next) { this->next = next; this->curr_instr = nullptr; this->status = OK; this->checked_out = {}; } Stage::~Stage() { delete this->next; }; std::array Stage::gprs; std::array Stage::vrs; std::deque Stage::checked_out; unsigned int Stage::pc; 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; Response n; this->advance_helper(); if (this->status == OK && this->curr_instr != nullptr && p == OK) { // mutual consent this->curr_instr->set_time_of(this->id, this->clock_cycle); r = new InstrDTO(*this->curr_instr); delete curr_instr; curr_instr = nullptr; this->status = STALLED; } n = (p != OK || this->status != OK) ? STALLED : OK; // the power of consent this->curr_instr = this->next->advance(n); return r; } void Stage::set_condition(CC c, bool v) { if (v) this->gprs[3] = this->gprs[3] | 1 << c; else this->gprs[3] = this->gprs[3] & ~(1 << c); } signed int Stage::dereference_register(signed int v) { signed int r; if (v < 0 || v >= GPR_NUM + V_NUM) { throw std::out_of_range(string_format( "instruction tried to access register %d, which does " "not exist", v)); } r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v]; return r; } bool Stage::is_checked_out(signed int r) { return std::find(this->checked_out.begin(), this->checked_out.end(), r) != this->checked_out.end(); } void Stage::squash(){ this->curr_instr = nullptr; this->status = OK; if(this->next){ this->next->squash(); } }