summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-05-10 20:35:18 -0400
committerbd <bdunahu@operationnull.com>2025-05-10 20:35:18 -0400
commit727afe4ffac0f193696c99234a2ade3a02f73157 (patch)
treec45fbbf393b6c4042bb8fe9b5ea693e5696f6fbb /src
parentc5e989bbf1adf6cb0ea63f5d215db7c90518c607 (diff)
Separate ex advance into methods handling different field types
Diffstat (limited to 'src')
-rw-r--r--src/ex.cc137
-rw-r--r--src/id.cc14
-rw-r--r--src/mm.cc52
-rw-r--r--src/wb.cc2
4 files changed, 83 insertions, 122 deletions
diff --git a/src/ex.cc b/src/ex.cc
index 3c9632b..810461f 100644
--- a/src/ex.cc
+++ b/src/ex.cc
@@ -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;
}
diff --git a/src/id.cc b/src/id.cc
index 81527db..2645aeb 100644
--- a/src/id.cc
+++ b/src/id.cc
@@ -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;
diff --git a/src/mm.cc b/src/mm.cc
index 8134cf5..ac77433 100644
--- a/src/mm.cc
+++ b/src/mm.cc
@@ -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/wb.cc b/src/wb.cc
index 455c7ad..e174157 100644
--- a/src/wb.cc
+++ b/src/wb.cc
@@ -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);