summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorSiddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com>2025-05-11 11:51:15 -0400
committerGitHub <noreply@github.com>2025-05-11 11:51:15 -0400
commita35eb451889f0efa99ff7fe1c0a3a76afd5e7ad5 (patch)
tree44205b454c11a2d98711cd3226b4828e12a8479a /inc
parentc7132dbc9c38ff766053bd9a0b72c68b23cd08d2 (diff)
parent6f4e9e0b914c3e68691a5d884cbad0b5813fcf18 (diff)
Merge pull request #78 from bdunahu/bdunahu
cleanup/fix existing vector extension
Diffstat (limited to 'inc')
-rw-r--r--inc/ex.h76
-rw-r--r--inc/id.h67
-rw-r--r--inc/instr.h11
-rw-r--r--inc/instrDTO.h17
-rw-r--r--inc/stage.h6
-rw-r--r--inc/wb.h9
6 files changed, 127 insertions, 59 deletions
diff --git a/inc/ex.h b/inc/ex.h
index 5a5c046..ff4041b 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -23,36 +23,28 @@
#include <exception>
#include <unordered_map>
-#define ADDITION_OF_GUARD(a, b) \
- (b >= 0) && (a > MAX_INT - b)
+#define ADDITION_OF_GUARD(a, b) (b >= 0) && (a > MAX_INT - b)
-#define ADDITION_UF_GUARD(a, b) \
- (b < 0) && (a < (-(MAX_INT)-1) - b)
+#define ADDITION_UF_GUARD(a, b) (b < 0) && (a < (-(MAX_INT)-1) - b)
-#define SUBTRACTION_OF_GUARD(a, b) \
- (b < 0) && (a > MAX_INT + b)
+#define SUBTRACTION_OF_GUARD(a, b) (b < 0) && (a > MAX_INT + b)
-#define SUBTRACTION_UF_GUARD(a, b) \
- (b >= 0) && (a < (-(MAX_INT)-1) + b)
+#define SUBTRACTION_UF_GUARD(a, b) (b >= 0) && (a < (-(MAX_INT)-1) + b)
-#define MULTIPLICATION_OF_GUARD(a, b) \
- (b != 0) && \
- (((b > 0) && (a > 0) && (a > MAX_INT / b)) || \
- ((b < 0) && (a < 0) && (a < MAX_INT / b)))
+#define MULTIPLICATION_OF_GUARD(a, b) \
+ (b != 0) && (((b > 0) && (a > 0) && (a > MAX_INT / b)) || \
+ ((b < 0) && (a < 0) && (a < MAX_INT / b)))
-#define MULTIPLICATION_UF_GUARD(a, b) \
- (b != 0) && (b != -1) && \
- (((b > 0) && (a < 0) && (a < (-(MAX_INT)-1) / b)) || \
- ((b < 0) && (a > 0) && (a > (-(MAX_INT)-1) / b)))
+#define MULTIPLICATION_UF_GUARD(a, b) \
+ (b != 0) && (b != -1) && \
+ (((b > 0) && (a < 0) && (a < (-(MAX_INT)-1) / b)) || \
+ ((b < 0) && (a > 0) && (a > (-(MAX_INT)-1) / b)))
-#define DIVISION_OF_GUARD(a, b) \
- ((a == -(MAX_INT) - 1) && (b == -1)) || (b == 0)
+#define DIVISION_OF_GUARD(a, b) ((a == -(MAX_INT)-1) && (b == -1)) || (b == 0)
class HaltException : public std::exception
{
- const char *what() const noexcept override {
- return "";
- }
+ const char *what() const noexcept override { return ""; }
};
class EX : public Stage
@@ -63,19 +55,57 @@ class EX : public Stage
* @param The next stage in the pipeline.
* @return A newly allocated EX object.
*/
- using Stage::Stage;
using Stage::advance;
+ using Stage::Stage;
private:
void advance_helper();
/**
+ * Handles operations involving three ints.
+ * @param slot 1, and later, the result of the mnemonic operation.
+ * @param slot 2
+ * @param slot 3
+ * @param the mnemonic
+ * @param the program counter
+ */
+ void handle_int_operations(
+ signed int &s1,
+ signed int s2,
+ signed int s3,
+ Mnemonic m,
+ unsigned int pc);
+ /**
+ * 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
+ */
+ void 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);
+
+ /**
+ * Handles operations involving a single vector register.
+ * Currently, this is LOADV and STOREV
+ * @param slot 1, and later, the result of the mnemonic operation.
+ * @param slot 2
+ * @param the mnemonic
+ * @param the vector length register
+ */
+ void handle_i_vector_operations(signed int &s1, signed int s2, Mnemonic m);
+ /**
* Wrapper for division functions, which detects HALT instructinos (division
* by 0).
* @param the numerator
* @param the denominator
* @param if the modulo operator should instead be used
+ * @return if the operation overflowed
*/
- void handle_divide(signed int &s1, signed int s2, bool is_mod);
+ bool handle_divide(signed int &s1, signed int s2, bool is_mod);
};
#endif /* EX_H_INCLUDED */
diff --git a/inc/id.h b/inc/id.h
index e8e9c36..5fda2b4 100644
--- a/inc/id.h
+++ b/inc/id.h
@@ -25,35 +25,13 @@
class ID : public Stage
{
public:
- using Stage::Stage;
using Stage::advance;
+ using Stage::Stage;
/* The following methods are made public so that they may be tested, and are
* not to be called from outside classes during standard execution.
*/
- /**
- * Facilitates register checkout and data hazard management.
- * It does this by checking that the register passed in is not currently
- * checked out. If true, then replaces r with the value of the register and
- * returns OK. If false, returns STALLED.
- *
- * @param the registers number, to be dereferenced.
- * @return OK if `r` is not checked out, STALLED otherwise.
- */
- Response read_guard(signed int &r);
- /**
- * Facilitates register checkout and data hazard management.
- * Checks out a register and returns it.
- *
- * @param the registers number, to be dereferenced and checked out.
- */
- void write_guard(signed int &r);
-
- Response read_vec_guard(signed int r, std::array<signed int, V_R_LIMIT> &v);
-
- void write_vec_guard(signed int r, std::array<signed int, V_R_LIMIT> &v);
-
Response set_vlen();
private:
@@ -82,7 +60,7 @@ class ID : public Stage
* @param the resulting third field, which varies per type.
* @param the resulting mnemonic.
*/
- void get_instr_fields(signed int &s1);
+ void get_instr_fields(signed int instr_bits);
void decode_R_type(signed int &s1);
void decode_I_type(signed int &s1);
void decode_J_type(signed int &s1);
@@ -95,6 +73,47 @@ class ID : public Stage
* @param the resulting type.
*/
void split_instr(signed int &raw, unsigned int &type, Mnemonic &m);
+ /**
+ * Facilitates register checkout and data hazard management.
+ * Checks out a register and returns it.
+ *
+ * @param the registers number, to be dereferenced and checked out.
+ */
+ template <typename T> T write_guard(int v)
+ {
+ T r;
+ // these registers shouldn't be written.
+ if (v != 0 && v != 16) {
+ // keep track in the instrDTO for displaying to user and writeback
+ // keep track in checked_out so we can still access this
+ // information!
+ this->checked_out.push_back(v);
+ this->curr_instr->checked_out = v;
+ }
+ r = this->dereference_register<T>(v);
+ return r;
+ }
+ /**
+ * Facilitates register checkout and data hazard management.
+ * It does this by checking that the register passed in is not currently
+ * checked out. If true, then sets `result' with the value of the register
+ * and returns OK. If false, returns STALLED.
+ *
+ * @param the registers number
+ * @param the dereferenced register value
+ * @return OK if `reg` is not checked out, STALLED otherwise.
+ */
+ template <typename T> Response read_guard(int reg, T &result)
+ {
+ Response response;
+ if (this->is_checked_out(reg))
+ response = STALLED;
+ else {
+ response = OK;
+ result = this->dereference_register<T>(reg);
+ }
+ return response;
+ }
};
#endif /* ID_H_INCLUDED */
diff --git a/inc/instr.h b/inc/instr.h
index 98a1f0e..0c49a79 100644
--- a/inc/instr.h
+++ b/inc/instr.h
@@ -61,9 +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;
+/**
+ * @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 f3d4597..ccc6ed9 100644
--- a/inc/instrDTO.h
+++ b/inc/instrDTO.h
@@ -19,7 +19,8 @@
#define INSTRDTO_H
#include "instr.h"
#include "pipe_spec.h"
-#include<array>
+#include <array>
+
struct U_INT_TYPE {
signed int slot_one;
@@ -33,10 +34,10 @@ struct V_TYPE {
std::array<signed int, V_R_LIMIT> slot_three;
};
-struct LOAD_STORE_V_TYPE{
- signed int base_addr;
- signed int immediate;
- std::array<signed int, V_R_LIMIT> vector_register;
+struct VI_TYPE {
+ signed int slot_one;
+ signed int slot_two;
+ std::array<signed int, V_R_LIMIT> slot_three;
};
struct InstrDTO {
@@ -60,10 +61,14 @@ 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;
- struct LOAD_STORE_V_TYPE load_store_vector;
+ struct VI_TYPE i_vector;
} operands;
};
diff --git a/inc/stage.h b/inc/stage.h
index 4e0c252..834b941 100644
--- a/inc/stage.h
+++ b/inc/stage.h
@@ -83,10 +83,6 @@ class Stage
*/
static std::deque<signed int> checked_out;
- bool is_vector_type(Mnemonic m);
-
- bool is_logical(Mnemonic m);
-
protected:
/**
* The function expected to do the majority of the work.
@@ -140,7 +136,7 @@ class Stage
}
else if constexpr (std::is_same_v<T, std::array<signed int, V_R_LIMIT>>) {
if (v < GPR_NUM || v >= GPR_NUM + V_NUM) {
- throw std::out_of_range("Invalid vector register index");
+ throw std::out_of_range("Invalid VRS index");
}
return vrs[v % GPR_NUM];
}
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 */