summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-05-11 19:40:47 -0400
committerbd <bdunahu@operationnull.com>2025-05-11 19:40:47 -0400
commitc9d4b54150b67e1701a920719ba2c7c03d897d27 (patch)
tree9c4c19ff4b0f7eb53bfae632437eff3a0a42d5e3
parent79a68cabb033530871a1dab259149480584b2586 (diff)
Stride load, stride store
-rw-r--r--gui/gui.h15
-rw-r--r--inc/ex.h9
-rw-r--r--inc/mm.h13
-rw-r--r--inc/wb.h3
-rw-r--r--src/ex.cc33
-rw-r--r--src/id.cc8
-rw-r--r--src/mm.cc64
-rw-r--r--src/wb.cc13
8 files changed, 119 insertions, 39 deletions
diff --git a/gui/gui.h b/gui/gui.h
index fd0eacb..d0b8e47 100644
--- a/gui/gui.h
+++ b/gui/gui.h
@@ -163,13 +163,14 @@ class GUI : public QMainWindow
{Mnemonic::ADDI, "ADDI"}, {Mnemonic::SUBI, "SUBI"},
{Mnemonic::SFTRI, "SFTRI"}, {Mnemonic::SFTLI, "SFTLI"},
{Mnemonic::ANDI, "ANDI"}, {Mnemonic::ORI, "ORI"},
- {Mnemonic::XORI, "XORI"}, {Mnemonic::SRDL, "SRDL"},
- {Mnemonic::SRDS, "SRDS"}, {Mnemonic::JMP, "JMP"},
- {Mnemonic::JRL, "JRL"}, {Mnemonic::JAL, "JAL"},
- {Mnemonic::BEQ, "BEQ"}, {Mnemonic::BGT, "BGT"},
- {Mnemonic::BUF, "BUF"}, {Mnemonic::BOF, "BOF"},
- {Mnemonic::PUSH, "PUSH"}, {Mnemonic::POP, "POP"},
- {Mnemonic::NOP, "NOP"}, {Mnemonic::RET, "RET"},
+ {Mnemonic::XORI, "XORI"}, {Mnemonic::STORE, "STORE"},
+ {Mnemonic::SRDL, "SRDL"}, {Mnemonic::SRDS, "SRDS"},
+ {Mnemonic::JMP, "JMP"}, {Mnemonic::JRL, "JRL"},
+ {Mnemonic::JAL, "JAL"}, {Mnemonic::BEQ, "BEQ"},
+ {Mnemonic::BGT, "BGT"}, {Mnemonic::BUF, "BUF"},
+ {Mnemonic::BOF, "BOF"}, {Mnemonic::PUSH, "PUSH"},
+ {Mnemonic::POP, "POP"}, {Mnemonic::NOP, "NOP"},
+ {Mnemonic::RET, "RET"},
};
QString mnemonicToString(Mnemonic mnemonic)
{
diff --git a/inc/ex.h b/inc/ex.h
index 19b35d4..41195a1 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -78,7 +78,6 @@ class EX : public Stage
* Handles operations involving three vector registers.
* @param slot 1, and later, the result of the mnemonic operation.
* @param slot 2
- * @param slot 3
* @param the mnemonic
* @param the vector length register
*/
@@ -89,14 +88,18 @@ class EX : public Stage
unsigned int v_len);
/**
- * Handles operations involving a single vector register.
+ * Handles operations involving a vector result and a scalar.
* Currently, this is SRDL and SRDS
* @param slot 1, and later, the result of the mnemonic operation.
* @param slot 2
* @param the mnemonic
* @param the vector length register
*/
- void handle_s_vector_operations(signed int &s1, signed int s2, Mnemonic m);
+ void handle_s_vector_operations(
+ std::array<signed int, V_R_LIMIT> &s1,
+ signed int s2,
+ Mnemonic m,
+ unsigned int v_len);
/**
* Wrapper for division functions, which detects HALT instructinos (division
* by 0).
diff --git a/inc/mm.h b/inc/mm.h
index 230b258..d54d6ad 100644
--- a/inc/mm.h
+++ b/inc/mm.h
@@ -29,6 +29,19 @@ class MM : public Stage
private:
void advance_helper() override;
+ /**
+ * Helpers for `advance_helper'. Sets the `this->status' to OK
+ * If the current memory IO returned OK, and all vector elements
+ * have been processed. Otherwise, sets `this->status' to STALLED
+ * @param the response from the storage devices.
+ */
+ void try_start();
+ void try_finish(int response);
+ /**
+ * The index element currently being loaded or stored.
+ * Used for strided load/store.
+ */
+ int curr_element = 0;
};
#endif /* MM_H_INCLUDED */
diff --git a/inc/wb.h b/inc/wb.h
index 35c9240..bbba5bf 100644
--- a/inc/wb.h
+++ b/inc/wb.h
@@ -51,7 +51,8 @@ class WB : public Stage
* @return the vector register to be stored, obtained by copying the
* unfilled elements in the destination register to the source. This is
* required to ensure what is written back only changes VECTOR_LENGTH number
- * of elements.
+ * of elements. Correctly handles zeroing out ALU operations if the VECTOR
+ * LENGTH number is zero.
*/
std::array<signed int, V_R_LIMIT> copy_extra_vector_elements();
};
diff --git a/src/ex.cc b/src/ex.cc
index cd00254..22cd092 100644
--- a/src/ex.cc
+++ b/src/ex.cc
@@ -240,13 +240,25 @@ void EX::handle_vector_operations(
this->set_condition(UF, underflow);
}
-void EX::handle_s_vector_operations(signed int &s1, signed int s2, Mnemonic m)
+void EX::handle_s_vector_operations(
+ std::array<signed int, V_R_LIMIT> &s1,
+ signed int s2,
+ Mnemonic m,
+ unsigned int v_len)
{
+ unsigned int i, inc1, inc2;
+
switch (m) {
- // case SRDL:
- // case SRDS:
- // s1 = s1 + s2;
- // break;
+ case SRDL:
+ case SRDS:
+ inc1 = s1[0];
+ s1[0] = s2;
+ for (i = 1; i < v_len; ++i) {
+ inc2 = s1[i];
+ s1[i] = s1[i - 1] + inc1;
+ inc1 = inc2;
+ }
+ break;
default:
throw std::invalid_argument("handle_s_vector_operations did not "
@@ -270,11 +282,12 @@ void EX::advance_helper()
handle_vector_operations(
this->curr_instr->operands.vector.slot_one,
this->curr_instr->operands.vector.slot_two, m, v_len_or_pc);
- }// else {
- // handle_s_vector_operations(
- // this->curr_instr->operands.s_vector.slot_one,
- // this->curr_instr->operands.s_vector.slot_two, m);
- // }
+ } else {
+ handle_s_vector_operations(
+ this->curr_instr->operands.s_vector.slot_one,
+ this->curr_instr->operands.s_vector.slot_two, m, v_len_or_pc);
+ printArray(this->curr_instr->operands.s_vector.slot_three);
+ }
this->status = OK;
}
diff --git a/src/id.cc b/src/id.cc
index 12f509f..9547486 100644
--- a/src/id.cc
+++ b/src/id.cc
@@ -135,10 +135,16 @@ void ID::decode_R_type(signed int &s1)
this->write_guard<std::array<signed int, V_R_LIMIT>>(s3);
break;
case SRDL:
- case SRDS:
this->curr_instr->operands.s_vector.slot_three =
this->write_guard<std::array<signed int, V_R_LIMIT>>(s3);
break;
+ case SRDS:
+ r1 = this->read_guard<std::array<signed int, V_R_LIMIT>>(
+ s3, this->curr_instr->operands.s_vector.slot_three);
+ if (r1 != OK) {
+ this->status = STALLED;
+ }
+ break;
default:
this->curr_instr->operands.integer.slot_three =
this->write_guard<signed int>(s3);
diff --git a/src/mm.cc b/src/mm.cc
index ac77433..63ee16a 100644
--- a/src/mm.cc
+++ b/src/mm.cc
@@ -25,15 +25,30 @@ void MM::advance_helper()
signed int data;
int i;
+ this->try_start();
+ if (this->status == OK) {
+ return;
+ }
+
switch (this->curr_instr->mnemonic) {
case LOAD:
i = this->storage->read_word(
this, this->curr_instr->operands.integer.slot_one, data);
- this->status = i ? OK : STALLED;
- if (this->status == OK) {
+ if (i) {
this->curr_instr->operands.integer.slot_one = data;
- } else
- this->status = STALLED;
+ }
+ this->try_finish(i);
+ break;
+ case SRDL:
+ i = this->storage->read_word(
+ this,
+ this->curr_instr->operands.s_vector.slot_one[this->curr_element],
+ data);
+ if (i) {
+ this->curr_instr->operands.s_vector.slot_one[this->curr_element] =
+ data;
+ }
+ this->try_finish(i);
break;
case PUSH:
@@ -41,22 +56,47 @@ void MM::advance_helper()
i = this->storage->write_word(
this, this->curr_instr->operands.integer.slot_two,
this->curr_instr->operands.integer.slot_one);
- this->status = i ? OK : STALLED;
- if (this->status != OK) {
- this->status = STALLED;
- }
+ this->try_finish(i);
+ break;
+ case SRDS:
+ i = this->storage->write_word(
+ this,
+ this->curr_instr->operands.s_vector.slot_three[this->curr_element],
+ this->curr_instr->operands.s_vector.slot_one[this->curr_element]);
+ this->try_finish(i);
break;
case POP:
- i = this->storage->read_word(this, this->curr_instr->operands.integer.slot_three, data);
+ i = this->storage->read_word(
+ this, this->curr_instr->operands.integer.slot_three, data);
this->status = i ? OK : STALLED;
- if (this->status == OK) {
+ if (i) {
this->curr_instr->operands.integer.slot_three = data;
- } else
- this->status = STALLED;
+ }
break;
default:
this->status = OK;
}
}
+
+void MM::try_start()
+{
+ if (this->curr_instr->type != SI_INT) {
+ this->status =
+ (this->curr_element >= this->curr_instr->slot_B) ? OK : STALLED;
+ }
+ if (this->status == OK)
+ this->curr_element = 0;
+}
+
+void MM::try_finish(int response)
+{
+ if (this->curr_instr->type == SI_INT) {
+ this->status = response ? OK : STALLED;
+ } else {
+ if (response) {
+ ++this->curr_element;
+ }
+ }
+}
diff --git a/src/wb.cc b/src/wb.cc
index fc714ad..89ee298 100644
--- a/src/wb.cc
+++ b/src/wb.cc
@@ -58,15 +58,11 @@ void WB::write_handler()
this->store_register<signed int>(
reg, this->curr_instr->operands.integer.slot_one);
break;
+ case S_VECT:
case R_VECT:
this->store_register<std::array<signed int, V_R_LIMIT>>(
reg, this->copy_extra_vector_elements());
break;
- // case S_VECT:
- // this->store_register<std::array<signed int, V_R_LIMIT>>(
- // reg, this->curr_instr->operands.s_vector.slot_three);
- // // todo, use copy_extra_vector_elements
- // break;
}
}
@@ -97,6 +93,13 @@ std::array<signed int, V_R_LIMIT> WB::copy_extra_vector_elements()
int i;
std::array<signed int, V_R_LIMIT> v;
+ if (this->curr_instr->type == S_VECT) {
+ if (this->curr_instr->slot_B == 0) {
+ v = {0};
+ return 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];