diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/controller.cc | 1 | ||||
-rw-r--r-- | src/ex.cc | 211 | ||||
-rw-r--r-- | src/id.cc | 159 | ||||
-rw-r--r-- | src/instr.cc | 11 | ||||
-rw-r--r-- | src/mm.cc | 52 | ||||
-rw-r--r-- | src/stage.cc | 14 | ||||
-rw-r--r-- | src/wb.cc | 38 |
7 files changed, 218 insertions, 268 deletions
diff --git a/src/controller.cc b/src/controller.cc index e439b30..190d3e2 100644 --- a/src/controller.cc +++ b/src/controller.cc @@ -32,6 +32,7 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined) this->checked_out = {}; this->gprs = {0}; this->vrs.fill({0}); + this->vrs.at(0).fill(1); // constant 1 vector register this->gprs.at(2) = MEM_WORDS; // set the stack pointer } @@ -16,80 +16,47 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. #include "ex.h" +#include "instr.h" #include "instrDTO.h" #include "pipe_spec.h" #include "response.h" #include "stage.h" +#include <stdexcept> #include <unordered_map> -// Switch statements for each instruction -void EX::advance_helper() +void EX::handle_int_operations( + signed int &s1, signed int s2, signed int s3, Mnemonic m, unsigned int pc) { - signed int s1, s2, s3; - std::array<signed int, V_R_LIMIT> v1, v2, v3; - signed int v_len, v_immediate, v_base_addr; - unsigned int pc; - Mnemonic m; - - s1 = 0, s2 = 0, s3 = 0; - v1 = {0}, v2 = {0}, v3 = {0}; - v_len = 0, v_immediate = 0, v_base_addr = 0; - m = this->curr_instr->mnemonic; - pc = this->curr_instr->slot_B; - - if (this->is_vector_type(m)) { - if (this->curr_instr->mnemonic != LOADV && - this->curr_instr->mnemonic != STOREV) { - v1 = this->curr_instr->operands.vector.slot_one; - v2 = this->curr_instr->operands.vector.slot_two; - v3 = this->curr_instr->operands.vector.slot_three; - } else { - v_immediate = - this->curr_instr->operands.load_store_vector.immediate; - v_base_addr = - this->curr_instr->operands.load_store_vector.base_addr; - } - v_len = this->curr_instr->slot_A; - if (v_len == 0) { - // clear destination vector reg - v1.fill(0); - } - } else { - s1 = this->curr_instr->operands.integer.slot_one; - s2 = this->curr_instr->operands.integer.slot_two; - s3 = this->curr_instr->operands.integer.slot_three; - } - - if (this->is_logical(m)) { - this->set_condition(OF, false); - this->set_condition(UF, false); - } + bool overflow, underflow; + overflow = get_condition(OF), underflow = get_condition(UF); switch (m) { case ADD: - this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); + overflow = ADDITION_OF_GUARD(s1, s2); + underflow = ADDITION_UF_GUARD(s1, s2); s1 = s1 + s2; break; case SUB: - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); + overflow = SUBTRACTION_OF_GUARD(s1, s2); + underflow = SUBTRACTION_UF_GUARD(s1, s2); s1 = s1 - s2; break; case MUL: - this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); - this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); + overflow = MULTIPLICATION_OF_GUARD(s1, s2); + underflow = MULTIPLICATION_UF_GUARD(s1, s2); s1 = s1 * s2; break; case QUOT: - this->handle_divide(s1, s2, false); + overflow = this->handle_divide(s1, s2, false); + underflow = 0; break; case REM: - this->handle_divide(s1, s2, true); + overflow = this->handle_divide(s1, s2, true); + underflow = 0; break; case SFTR: @@ -101,18 +68,26 @@ void EX::advance_helper() break; case AND: + overflow = false; + underflow = false; s1 = s1 & s2; break; case OR: + overflow = false; + underflow = false; s1 = s1 | s2; break; case XOR: + overflow = false; + underflow = false; s1 = s1 ^ s2; break; case NOT: + overflow = false; + underflow = false; s1 = ~s1; break; @@ -124,14 +99,14 @@ void EX::advance_helper() break; case ADDI: - this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); + overflow = ADDITION_OF_GUARD(s1, s3); + underflow = ADDITION_UF_GUARD(s1, s3); s1 = s1 + s3; break; case SUBI: - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); + overflow = SUBTRACTION_OF_GUARD(s1, s3); + underflow = SUBTRACTION_UF_GUARD(s1, s3); s1 = s1 - s3; break; @@ -144,14 +119,20 @@ void EX::advance_helper() break; case ANDI: + overflow = false; + underflow = false; s1 = s1 & s3; break; case ORI: + overflow = false; + underflow = false; s1 = s1 | s3; break; case XORI: + overflow = false; + underflow = false; s1 = s1 ^ s3; break; @@ -187,72 +168,126 @@ void EX::advance_helper() (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; break; + case RET: + case NOP: + break; + + default: + throw std::invalid_argument( + "handle_int_operations received a vector operation!"); + } + + this->set_condition(OF, overflow); + this->set_condition(UF, underflow); +} + +void EX::handle_vector_operations( + std::array<signed int, V_R_LIMIT> &s1, + std::array<signed int, V_R_LIMIT> s2, + Mnemonic m, + unsigned int v_len) +{ + unsigned int i; + bool overflow, underflow; + + overflow = 0, underflow = 0; + + switch (m) { case ADDV: - for (int i = 0; i < v_len; i++) { - this->set_condition(OF, ADDITION_OF_GUARD(v1[i], v2[i])); - this->set_condition(UF, ADDITION_UF_GUARD(v1[i], v2[i])); - v1[i] = v1[i] + v2[i]; + for (i = 0; i < v_len; i++) { + overflow = overflow || (ADDITION_OF_GUARD(s1[i], s2[i])); + underflow = underflow || (ADDITION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] + s2[i]; } break; case SUBV: - for (int i = 0; i < v_len; i++) { - this->set_condition(OF, SUBTRACTION_OF_GUARD(v1[i], v2[i])); - this->set_condition(UF, SUBTRACTION_UF_GUARD(v1[i], v2[i])); - v1[i] = v1[i] - v2[i]; + for (i = 0; i < v_len; i++) { + overflow = overflow || (SUBTRACTION_OF_GUARD(s1[i], s2[i])); + underflow = underflow || (SUBTRACTION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] - s2[i]; } break; case MULV: - for (int i = 0; i < v_len; i++) { - this->set_condition(OF, MULTIPLICATION_OF_GUARD(v1[i], v2[i])); - this->set_condition(UF, MULTIPLICATION_UF_GUARD(v1[i], v2[i])); - v1[i] = v1[i] * v2[i]; + for (i = 0; i < v_len; i++) { + overflow = overflow || (MULTIPLICATION_OF_GUARD(s1[i], s2[i])); + underflow = underflow || (MULTIPLICATION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] * s2[i]; } break; case DIVV: - for (int i = 0; i < v_len; i++) { - this->handle_divide(v1[i], v2[i], false); + for (i = 0; i < v_len; i++) { + // short-circuiting---this order required + overflow = this->handle_divide(s1[i], s2[i], false) | overflow; } break; case CEV: - int i; + bool eq; + eq = true; for (i = 0; i < v_len; i++) { - if (v1[i] != v2[i]) { + if (s1[i] != s2[i]) { + eq = false; break; } } - if (i == v_len) { - this->set_condition(EQ, true); - } else { - this->set_condition(EQ, false); - } + this->set_condition(EQ, eq); break; + default: + throw std::invalid_argument( + "handle_vector_operations received an integer operation!"); + } + + this->set_condition(OF, overflow); + this->set_condition(UF, underflow); +} + +void EX::handle_i_vector_operations(signed int &s1, signed int s2, Mnemonic m) +{ + switch (m) { case LOADV: case STOREV: - v_base_addr = v_base_addr + v_immediate; + s1 = s1 + s2; break; case RET: case NOP: break; + + default: + throw std::invalid_argument("handle_i_vector_operations did not " + "receive a LOADV or STOREV operation!"); } - if (this->is_vector_type(m)) { - if (this->curr_instr->mnemonic != LOADV && - this->curr_instr->mnemonic != STOREV) { - this->curr_instr->operands.vector.slot_one = v1; - } else { - this->curr_instr->operands.load_store_vector.base_addr = - v_base_addr; - } +} + +void EX::advance_helper() +{ + unsigned int v_len_or_pc; + Mnemonic m; + m = this->curr_instr->mnemonic; + v_len_or_pc = this->curr_instr->slot_B; + + if (this->curr_instr->type == FieldType::SI_INT) { + handle_int_operations( + this->curr_instr->operands.integer.slot_one, + this->curr_instr->operands.integer.slot_two, + this->curr_instr->operands.integer.slot_three, m, v_len_or_pc); + } else if (this->curr_instr->type == FieldType::R_VECT) { + handle_vector_operations( + this->curr_instr->operands.vector.slot_one, + this->curr_instr->operands.vector.slot_two, m, v_len_or_pc); } else { - this->curr_instr->operands.integer.slot_one = s1; + handle_i_vector_operations( + this->curr_instr->operands.i_vector.slot_one, + this->curr_instr->operands.i_vector.slot_two, m); } + this->status = OK; } -void EX::handle_divide(signed int &s1, signed int s2, bool is_mod) +bool 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); + bool ret; + + ret = DIVISION_OF_GUARD(s1, s2); if (s2 == 0) { // handle everything here this->curr_instr->operands.integer.slot_one = MAX_INT; @@ -264,4 +299,6 @@ void EX::handle_divide(signed int &s1, signed int s2, bool is_mod) } else { s1 = (is_mod) ? (s1 % s2) : (s1 / s2); } + + return ret; } @@ -22,87 +22,34 @@ #include "response.h" #include "stage.h" -Response ID::read_guard(signed int &v) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - v = this->dereference_register<signed int>(v); - } - return r; -} - -Response -ID::read_vec_guard(signed int v, std::array<signed int, V_R_LIMIT> &vrs) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - vrs = this->dereference_register<std::array<signed int, V_R_LIMIT>>(v); - } - return r; -} - -void ID::write_guard(signed int &v) -{ - // zero register shouldn't be written. - if (v != 0) { - // keep track in the instrDTO for displaying to user and writeback - // keep track in checked_out so we can still access this information! - this->checked_out.push_back(v); - this->curr_instr->checked_out = v; - } - v = this->dereference_register<signed int>(v); -} - -void ID::write_vec_guard(signed int v, std::array<signed int, V_R_LIMIT> &vrs) -{ - - // zero register shouldn't be written. - if (v != 0) { - // keep track in the instrDTO for displaying to user and writeback - // keep track in checked_out so we can still access this information! - this->checked_out.push_back(v); - this->curr_instr->checked_out = v; - } - vrs = this->dereference_register<std::array<signed int, V_R_LIMIT>>(v); -} - void ID::advance_helper() { - signed int s1; - if (this->curr_instr->mnemonic == NOP) this->status = OK; else { // instuction in bits in s1 - s1 = this->curr_instr->slot_A; - get_instr_fields(s1); + get_instr_fields(this->curr_instr->slot_A); } } -void ID::get_instr_fields(signed int &s1) +void ID::get_instr_fields(signed int instr_bits) { unsigned int type; Mnemonic m; - this->split_instr(s1, type, m); + this->split_instr(instr_bits, type, m); this->curr_instr->mnemonic = m; + this->curr_instr->type = instr::get_field_types(m); switch (type) { case 0b00: - this->decode_R_type(s1); + this->decode_R_type(instr_bits); break; case 0b01: - this->decode_I_type(s1); + this->decode_I_type(instr_bits); break; case 0b10: - this->decode_J_type(s1); + this->decode_J_type(instr_bits); break; case 0b11: - // not defined, m = NOP this->status = OK; } } @@ -127,13 +74,13 @@ Response ID::set_vlen() { signed int vlen_reg = 4; Response r; - r = this->read_guard(vlen_reg); + r = this->read_guard<signed int>(vlen_reg, vlen_reg); vlen_reg = vlen_reg & 0xf; if (r == OK) { if (vlen_reg > V_R_LIMIT) { - this->curr_instr->slot_A = V_R_LIMIT; + this->curr_instr->slot_B = V_R_LIMIT; } else { - this->curr_instr->slot_A = vlen_reg; + this->curr_instr->slot_B = vlen_reg; } } return r; @@ -143,8 +90,7 @@ void ID::decode_R_type(signed int &s1) { unsigned int s0b, s1b, s2b; signed int s2, s3; - Response r1, r2; - Response r3 = OK; + Response r1, r2, r3; s0b = REG_SIZE; s1b = s0b + REG_SIZE; @@ -153,17 +99,18 @@ void ID::decode_R_type(signed int &s1) s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - if (this->is_vector_type(this->curr_instr->mnemonic)) { - r1 = this->read_vec_guard( + if (this->curr_instr->type == SI_INT) { + r1 = this->read_guard<signed int>( + s1, this->curr_instr->operands.integer.slot_one); + r2 = this->read_guard<signed int>( + s2, this->curr_instr->operands.integer.slot_two); + r3 = OK; + } else { + r1 = this->read_guard<std::array<signed int, V_R_LIMIT>>( s1, this->curr_instr->operands.vector.slot_one); - r2 = this->read_vec_guard( + r2 = this->read_guard<std::array<signed int, V_R_LIMIT>>( s2, this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); - } else { - r1 = this->read_guard(s1); - this->curr_instr->operands.integer.slot_one = s1; - r2 = this->read_guard(s2); - this->curr_instr->operands.integer.slot_two = s2; } this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; @@ -177,14 +124,14 @@ void ID::decode_R_type(signed int &s1) case MULV: case DIVV: if (this->status == OK) { - this->write_vec_guard( - s3, this->curr_instr->operands.vector.slot_three); + this->curr_instr->operands.vector.slot_three = + this->write_guard<std::array<signed int, V_R_LIMIT>>(s3); } break; default: if (this->status == OK) { - this->write_guard(s3); - this->curr_instr->operands.integer.slot_three = s3; + this->curr_instr->operands.integer.slot_three = + this->write_guard<signed int>(s3); } } } @@ -199,7 +146,7 @@ void ID::decode_I_type(signed int &s1) s0b = REG_SIZE; s1b = s0b + REG_SIZE; s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE; - // s3 is immediate + // s3 is slot_two s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b); switch (this->curr_instr->mnemonic) { @@ -210,41 +157,40 @@ void ID::decode_I_type(signed int &s1) // both operands are read values // s1 is base address - r1 = this->read_guard(s1); + r1 = this->read_guard<signed int>(s1, s1); this->curr_instr->operands.integer.slot_one = s1; // s2 is value to be stored - r2 = this->read_guard(s2); + r2 = this->read_guard<signed int>(s2, s2); this->curr_instr->operands.integer.slot_two = s2; this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: - this->curr_instr->operands.load_store_vector.immediate = s3; + this->curr_instr->operands.i_vector.slot_two = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // base address - r1 = this->read_guard(s1); - this->curr_instr->operands.load_store_vector.base_addr = s1; + r1 = this->read_guard<signed int>(s1, s1); + this->curr_instr->operands.i_vector.slot_one = s1; // vector value to be stored - r2 = this->read_vec_guard( - s2, this->curr_instr->operands.load_store_vector.vector_register); + r2 = this->read_guard<std::array<signed int, V_R_LIMIT>>( + s2, this->curr_instr->operands.i_vector.slot_three); r3 = this->set_vlen(); this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; return; case LOADV: - this->curr_instr->operands.load_store_vector.immediate = s3; + this->curr_instr->operands.i_vector.slot_two = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address - r1 = this->read_guard(s1); - this->curr_instr->operands.load_store_vector.base_addr = s1; + r1 = this->read_guard<signed int>(s1, s1); + this->curr_instr->operands.i_vector.slot_one = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->write_vec_guard( - s2, - this->curr_instr->operands.load_store_vector.vector_register); + this->curr_instr->operands.i_vector.slot_three = + this->write_guard<std::array<signed int, V_R_LIMIT>>(s2); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; case LOAD: @@ -258,11 +204,11 @@ void ID::decode_I_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); } - r1 = this->read_guard(s1); + r1 = this->read_guard<signed int>(s1, s1); this->curr_instr->operands.integer.slot_one = s1; if (r1 == OK) { - this->write_guard(s2); - this->curr_instr->operands.integer.slot_two = s2; + this->curr_instr->operands.integer.slot_two = + this->write_guard<int>(s2); } this->status = r1; } @@ -284,14 +230,16 @@ void ID::decode_J_type(signed int &s1) s2 = s1; // source s3 = 2; // stack pointer s1 = -1; // increment amount - r1 = this->read_guard(s2); + this->curr_instr->operands.integer.slot_one = s1; - this->curr_instr->operands.integer.slot_two = s2; + r1 = this->read_guard<signed int>( + s2, this->curr_instr->operands.integer.slot_two); r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK && r2 == OK) { - this->write_guard(s3); // we write the stack pointer - this->curr_instr->operands.integer.slot_three = s3; + // we write the stack pointer + this->curr_instr->operands.integer.slot_three = + this->write_guard<int>(s3); } this->status = (r1 == OK && r2 == OK) ? OK : STALLED; break; @@ -303,10 +251,11 @@ void ID::decode_J_type(signed int &s1) r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK) { - this->write_guard(s2); - this->curr_instr->operands.integer.slot_two = s2; - this->write_guard(s3); // we write the stack pointer - this->curr_instr->operands.integer.slot_three = s3; + this->curr_instr->operands.integer.slot_two = + this->write_guard<int>(s2); + // we write the stack pointer + this->curr_instr->operands.integer.slot_three = + this->write_guard<int>(s3); } this->status = r1; break; @@ -314,9 +263,9 @@ void ID::decode_J_type(signed int &s1) s1 = 1; // link register [[fallthrough]]; default: - this->status = this->read_guard(s1); - if(this->status == OK){ - this->curr_instr->operands.integer.slot_one = s1; + this->status = this->read_guard<signed int>( + s1, this->curr_instr->operands.integer.slot_one); + if (this->status == OK) { this->curr_instr->operands.integer.slot_two = s2; this->curr_instr->operands.integer.slot_three = s3; } diff --git a/src/instr.cc b/src/instr.cc index 9bd951b..ee2d37f 100644 --- a/src/instr.cc +++ b/src/instr.cc @@ -37,4 +37,15 @@ const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = { {0b0011010, BUF}, {0b0011110, BOF}, {0b0100010, PUSH}, {0b0100110, POP}, {0b0101010, RET}, }; + +FieldType get_field_types(Mnemonic m) +{ + if (m == ADDV || m == SUBV || m == MULV || m == DIVV || m == CEV) { + return R_VECT; + } else if (m == STOREV || m == LOADV) { + return I_VECT; + } else { + return SI_INT; + } +} } // namespace instr @@ -24,7 +24,6 @@ void MM::advance_helper() { signed int data; int i; - int vector_delay = VECTOR_MEM_DELAY; switch (this->curr_instr->mnemonic) { case LOAD: @@ -36,32 +35,6 @@ void MM::advance_helper() } else this->status = STALLED; break; - case LOADV: - if (vector_delay == 0){ - signed int word_address = this->curr_instr->operands.load_store_vector.base_addr; - int j = 0; - while(j < this->curr_instr->slot_A){ - i = this->storage->read_word(this, word_address, data); - this->status = i ? OK : STALLED; - if (this->status == OK) { - this->curr_instr->operands.load_store_vector.vector_register[j] = data; - // +1 or +4? - word_address += 1; - j++; - } else { - break; - } - } - if(this->status == OK){ - // if vector is loaded, reset delay - vector_delay = VECTOR_MEM_DELAY; - } else { - this->status = STALLED; - } - } else { - vector_delay--; - } - break; case PUSH: case STORE: @@ -73,31 +46,6 @@ void MM::advance_helper() this->status = STALLED; } break; - case STOREV: - if (vector_delay == 0){ - signed int word_address = this->curr_instr->operands.load_store_vector.base_addr; - int j = 0; - while(j < this->curr_instr->slot_A){ - this->storage->write_word( - this, this->curr_instr->operands.load_store_vector.vector_register[j], word_address); - this->status = i ? OK : STALLED; - if (this->status != OK) { - break; - } else { - word_address += 1; - j++; - } - } - if(this->status == OK){ - // if vector is stored , reset delay - vector_delay = VECTOR_MEM_DELAY; - } else { - this->status = STALLED; - } - } else { - vector_delay--; - } - break; case POP: i = this->storage->read_word(this, this->curr_instr->operands.integer.slot_three, data); diff --git a/src/stage.cc b/src/stage.cc index 4eab7d3..7db3539 100644 --- a/src/stage.cc +++ b/src/stage.cc @@ -71,20 +71,6 @@ InstrDTO *Stage::advance(Response p) return r; } -bool Stage::is_vector_type(Mnemonic m) -{ - return ( - m == ADDV || m == SUBV || m == MULV || m == DIVV || m == CEV || - m == LOADV || m == STOREV); -} - -bool Stage::is_logical(Mnemonic m) -{ - return ( - m == ANDI || m == ORI || m == XORI || m == AND || m == OR || m == XOR || - m == NOT); -} - InstrDTO *Stage::get_instr() { return this->curr_instr; } void Stage::set_condition(CC c, bool v) @@ -16,6 +16,7 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. #include "wb.h" +#include "instr.h" #include "instrDTO.h" #include "response.h" #include "stage.h" @@ -51,15 +52,21 @@ void WB::write_handler() this->checked_out.pop_front(); reg = this->curr_instr->checked_out; - - if(this->is_vector_type(this->curr_instr->mnemonic)) { - if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { - this->store_register<std::array<signed int, V_R_LIMIT>>(reg, this->curr_instr->operands.vector.slot_one); - } else { - this->store_register<std::array<signed int, V_R_LIMIT>>(reg, this->curr_instr->operands.load_store_vector.vector_register); - } - } else{ - this->store_register<signed int>(reg, this->curr_instr->operands.integer.slot_one); + + switch (this->curr_instr->type) { + case SI_INT: + this->store_register<signed int>( + reg, this->curr_instr->operands.integer.slot_one); + break; + case R_VECT: + this->store_register<std::array<signed int, V_R_LIMIT>>( + reg, this->copy_extra_vector_elements()); + break; + case I_VECT: + this->store_register<std::array<signed int, V_R_LIMIT>>( + reg, this->curr_instr->operands.i_vector.slot_three); + // todo, use copy_extra_vector_elements + break; } } @@ -68,7 +75,6 @@ void WB::jump_handler() if (this->curr_instr->operands.integer.slot_one > 0) { if (this->curr_instr->mnemonic == JAL) this->gprs[1] = this->curr_instr->slot_B + 1; - ; this->pc = this->curr_instr->operands.integer.slot_one; this->checked_out = {}; this->next->squash(); @@ -85,3 +91,15 @@ bool WB::should_jump() else return false; } + +std::array<signed int, V_R_LIMIT> WB::copy_extra_vector_elements() +{ + int i; + std::array<signed int, V_R_LIMIT> v; + + v = this->curr_instr->operands.vector.slot_one; + for (i = V_R_LIMIT - 1; i >= this->curr_instr->slot_B; --i) { + v[i] = this->curr_instr->operands.vector.slot_three[i]; + } + return v; +} |