summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/wb.h9
-rw-r--r--src/ex.cc1
-rw-r--r--src/wb.cc37
3 files changed, 35 insertions, 12 deletions
diff --git a/inc/wb.h b/inc/wb.h
index d3a1b93..35c9240 100644
--- a/inc/wb.h
+++ b/inc/wb.h
@@ -24,8 +24,8 @@
class WB : public Stage
{
public:
- using Stage::Stage;
using Stage::advance;
+ using Stage::Stage;
private:
void advance_helper() override;
@@ -47,6 +47,13 @@ class WB : public Stage
* STORE.
*/
bool should_jump();
+ /**
+ * @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.
+ */
+ std::array<signed int, V_R_LIMIT> copy_extra_vector_elements();
};
#endif /* WB_H_INCLUDED */
diff --git a/src/ex.cc b/src/ex.cc
index 066f584..56a59d7 100644
--- a/src/ex.cc
+++ b/src/ex.cc
@@ -231,7 +231,6 @@ void EX::handle_vector_operations(
}
this->set_condition(EQ, eq);
break;
-
default:
throw std::invalid_argument(
"handle_vector_operations received an integer operation!");
diff --git a/src/wb.cc b/src/wb.cc
index e174157..bfdbc3a 100644
--- a/src/wb.cc
+++ b/src/wb.cc
@@ -16,9 +16,9 @@
// 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 "instr.h"
#include "stage.h"
#include <algorithm>
#include <array>
@@ -53,14 +53,20 @@ void WB::write_handler()
this->checked_out.pop_front();
reg = this->curr_instr->checked_out;
- if(this->curr_instr->type != SI_INT) {
- 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.slot_three);
- }
- } 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;
}
}
@@ -69,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();
@@ -86,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;
+}