diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ex.cc | 137 | ||||
-rw-r--r-- | src/id.cc | 14 | ||||
-rw-r--r-- | src/mm.cc | 52 | ||||
-rw-r--r-- | src/wb.cc | 2 |
4 files changed, 83 insertions, 122 deletions
@@ -21,45 +21,12 @@ #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; - v_len = this->curr_instr->slot_B; - pc = this->curr_instr->slot_B; - - if (this->curr_instr->type != SI_INT) { - if (this->curr_instr->type == R_VECT) { - 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.i_vector.immediate; - v_base_addr = - this->curr_instr->operands.i_vector.base_addr; - } - 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; - } - switch (m) { case ADD: this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); @@ -196,36 +163,55 @@ 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!"); + } +} + +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; + + 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++) { + this->set_condition(OF, ADDITION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, 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++) { + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, 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++) { + this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, 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++) { + this->handle_divide(s1[i], s2[i], false); } break; case CEV: - int i; + for (i = 0; i < v_len; i++) { - if (v1[i] != v2[i]) { + if (s1[i] != s2[i]) { break; } } @@ -235,26 +221,53 @@ void EX::advance_helper() this->set_condition(EQ, false); } break; + + default: + throw std::invalid_argument( + "handle_vector_operations received an integer operation!"); + } +} + +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->curr_instr->type != SI_INT) { - if (this->curr_instr->mnemonic != LOADV && - this->curr_instr->mnemonic != STOREV) { - this->curr_instr->operands.vector.slot_one = v1; - } else { - this->curr_instr->operands.i_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; } @@ -147,7 +147,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) { @@ -166,31 +166,31 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: - this->curr_instr->operands.i_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<signed int>(s1, s1); - this->curr_instr->operands.i_vector.base_addr = s1; + this->curr_instr->operands.i_vector.slot_one = s1; // vector value to be stored r2 = this->read_guard<std::array<signed int, V_R_LIMIT>>( - s2, this->curr_instr->operands.i_vector.vector_register); + 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.i_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<signed int>(s1, s1); - this->curr_instr->operands.i_vector.base_addr = s1; + this->curr_instr->operands.i_vector.slot_one = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->curr_instr->operands.i_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; @@ -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); @@ -57,7 +57,7 @@ void WB::write_handler() 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.i_vector.vector_register); + this->store_register<std::array<signed int, V_R_LIMIT>>(reg, this->curr_instr->operands.i_vector.slot_three); } } else{ this->store_register<signed int>(reg, this->curr_instr->operands.integer.slot_one); |