summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/instr.h13
-rw-r--r--inc/instrDTO.h4
-rw-r--r--src/ex.cc28
-rw-r--r--src/id.cc13
-rw-r--r--src/instr.cc20
-rw-r--r--src/wb.cc2
6 files changed, 49 insertions, 31 deletions
diff --git a/inc/instr.h b/inc/instr.h
index c4f5e37..0c49a79 100644
--- a/inc/instr.h
+++ b/inc/instr.h
@@ -61,11 +61,20 @@ enum Mnemonic {
NOP,
};
+enum FieldType {
+ SI_INT,
+ R_VECT,
+ I_VECT,
+};
+
namespace instr
{
extern const std::unordered_map<unsigned int, Mnemonic> mnemonic_map;
-bool is_vector_type(Mnemonic m);
-bool is_logical_type(Mnemonic m);
+/**
+ * @param a mnemonic
+ * @return an enum representing the types of the decoded instruction fields.
+ */
+FieldType get_field_types(Mnemonic m);
} // namespace instr
#endif /* INSTR_H_INCLUDED */
diff --git a/inc/instrDTO.h b/inc/instrDTO.h
index f4ef416..98247a3 100644
--- a/inc/instrDTO.h
+++ b/inc/instrDTO.h
@@ -60,6 +60,10 @@ struct InstrDTO {
* The register this instruction checks out.
*/
signed int checked_out;
+ /**
+ * The currently active union member.
+ */
+ FieldType type;
union {
struct U_INT_TYPE integer;
struct V_TYPE vector;
diff --git a/src/ex.cc b/src/ex.cc
index 73ed615..45a018a 100644
--- a/src/ex.cc
+++ b/src/ex.cc
@@ -36,11 +36,11 @@ void EX::advance_helper()
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 (instr::is_vector_type(m)) {
- if (this->curr_instr->mnemonic != LOADV &&
- this->curr_instr->mnemonic != STOREV) {
+ 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;
@@ -50,7 +50,6 @@ void EX::advance_helper()
v_base_addr =
this->curr_instr->operands.load_store_vector.base_addr;
}
- v_len = this->curr_instr->slot_B;
if (v_len == 0) {
// clear destination vector reg
v1.fill(0);
@@ -61,11 +60,6 @@ void EX::advance_helper()
s3 = this->curr_instr->operands.integer.slot_three;
}
- if (instr::is_logical_type(m)) {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- }
-
switch (m) {
case ADD:
this->set_condition(OF, ADDITION_OF_GUARD(s1, s2));
@@ -102,18 +96,26 @@ void EX::advance_helper()
break;
case AND:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = s1 & s2;
break;
case OR:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = s1 | s2;
break;
case XOR:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = s1 ^ s2;
break;
case NOT:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = ~s1;
break;
@@ -145,14 +147,20 @@ void EX::advance_helper()
break;
case ANDI:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = s1 & s3;
break;
case ORI:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = s1 | s3;
break;
case XORI:
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
s1 = s1 ^ s3;
break;
@@ -236,7 +244,7 @@ void EX::advance_helper()
case NOP:
break;
}
- if (instr::is_vector_type(m)) {
+ 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;
diff --git a/src/id.cc b/src/id.cc
index 490b03a..d24497a 100644
--- a/src/id.cc
+++ b/src/id.cc
@@ -38,6 +38,7 @@ void ID::get_instr_fields(signed int instr_bits)
Mnemonic 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(instr_bits);
@@ -100,17 +101,17 @@ void ID::decode_R_type(signed int &s1)
s2 = GET_MID_BITS(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
- if (instr::is_vector_type(this->curr_instr->mnemonic)) {
+ if (this->curr_instr->type == SI_INT) {
+ r1 = this->read_guard<signed int>(s1, s1);
+ this->curr_instr->operands.integer.slot_one = s1;
+ r2 = this->read_guard<signed int>(s2, s2);
+ this->curr_instr->operands.integer.slot_two = s2;
+ } else {
r1 = this->read_guard<std::array<signed int, V_R_LIMIT>>(
s1, this->curr_instr->operands.vector.slot_one);
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<signed int>(s1, s1);
- this->curr_instr->operands.integer.slot_one = s1;
- r2 = this->read_guard<signed int>(s2, s2);
- this->curr_instr->operands.integer.slot_two = s2;
}
this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED;
diff --git a/src/instr.cc b/src/instr.cc
index 0282be3..ee2d37f 100644
--- a/src/instr.cc
+++ b/src/instr.cc
@@ -38,18 +38,14 @@ const std::unordered_map<unsigned int, Mnemonic> mnemonic_map = {
{0b0100110, POP}, {0b0101010, RET},
};
-bool is_vector_type(Mnemonic m)
+FieldType get_field_types(Mnemonic m)
{
- return (
- m == ADDV || m == SUBV || m == MULV || m == DIVV || m == CEV ||
- m == LOADV || m == STOREV);
+ 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;
+ }
}
-
-bool is_logical_type(Mnemonic m)
-{
- return (
- m == ANDI || m == ORI || m == XORI || m == AND || m == OR || m == XOR ||
- m == NOT);
-}
-
} // namespace instr
diff --git a/src/wb.cc b/src/wb.cc
index 12f4edf..1c364b0 100644
--- a/src/wb.cc
+++ b/src/wb.cc
@@ -53,7 +53,7 @@ void WB::write_handler()
this->checked_out.pop_front();
reg = this->curr_instr->checked_out;
- if(instr::is_vector_type(this->curr_instr->mnemonic)) {
+ 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 {