summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSiddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com>2025-04-26 20:21:02 -0400
committerSiddarth-Suresh <65844402+Siddarth-Suresh@users.noreply.github.com>2025-04-26 20:21:02 -0400
commit41f612789f652654b5f2fa8c3fee4e348e2081b1 (patch)
tree386658b4231c6c1daa4f2f9769959d0934b2b44e /src
parent73633535288711de4850b9d9eec6326eb5de06c0 (diff)
Initial vector extension changes
Diffstat (limited to 'src')
-rw-r--r--src/ex.cc587
-rw-r--r--src/id.cc178
-rw-r--r--src/stage.cc37
-rw-r--r--src/vec.cc113
-rw-r--r--src/wb.cc4
5 files changed, 331 insertions, 588 deletions
diff --git a/src/ex.cc b/src/ex.cc
index eac24ff..2ad2d7f 100644
--- a/src/ex.cc
+++ b/src/ex.cc
@@ -22,415 +22,204 @@
#include "stage.h"
#include <unordered_map>
-// clang-format off
-#define INIT_INSTRUCTION(mnemonic, body) \
- {mnemonic, [this](signed int &s1, signed int s2, signed int s3, unsigned int pc) { \
- body; \
- }}
-// clang-format on
-
-EX::EX(Stage *stage) : Stage(stage)
-{
- instr_map = {
-
- /* R type instructions */
- INIT_INSTRUCTION(
- ADD,
- {
- this->set_condition(OF, ADDITION_OF_GUARD(s1, s2));
- this->set_condition(UF, ADDITION_UF_GUARD(s1, s2));
- s1 = s1 + s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SUB,
- {
- this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2));
- this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2));
- s1 = s1 - s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- MUL,
- {
- this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2));
- this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2));
- s1 = s1 * s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- QUOT,
- {
- this->handle_divide(s1, s2, false);
- (void)pc;
- (void)s3;
- }),
-
- INIT_INSTRUCTION(
- REM,
- {
- this->handle_divide(s1, s2, true);
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SFTR,
- {
- s1 = s1 >> s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SFTL,
- {
- s1 = s1 << s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- AND,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = s1 & s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- OR,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = s1 | s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- NOT,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = ~s1;
- (void)pc;
- (void)s3;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- XOR,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = s1 ^ s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- ADDV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SUBV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- MULV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- DIVV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- CMP,
- {
- (s1 > s2) ? this->set_condition(GT, true)
- : this->set_condition(GT, false);
- (s1 == s2) ? this->set_condition(EQ, true)
- : this->set_condition(EQ, false);
- (void)pc;
- (void)s3;
- }),
-
- INIT_INSTRUCTION(
- CEV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- /* I type instructions */
- INIT_INSTRUCTION(
- LOAD,
- {
- s1 = s1 + s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- LOADV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- ADDI,
- {
- this->set_condition(OF, ADDITION_OF_GUARD(s1, s3));
- this->set_condition(UF, ADDITION_UF_GUARD(s1, s3));
- s1 = s1 + s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SUBI,
- {
- this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3));
- this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3));
- s1 = s1 - s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SFTRI,
- {
- s1 = s1 >> s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- SFTLI,
- {
- s1 = s1 << s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- ANDI,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = s1 & s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- ORI,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = s1 | s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- XORI,
- {
- this->set_condition(OF, false);
- this->set_condition(UF, false);
- s1 = s1 ^ s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- STORE,
- {
- s1 = s1 + s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- STOREV,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- /* J type instructions */
- INIT_INSTRUCTION(
- JMP,
- {
- s1 = s1 + s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- JRL,
- {
- s1 = pc + s2;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- JAL,
- {
- s1 = s1 + s2;
- (void)pc;
- (void)s3;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- BEQ,
- {
- (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1;
- (void)s3;
- }),
-
- INIT_INSTRUCTION(
- BGT,
- {
- (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1;
- (void)s3;
- }),
-
- INIT_INSTRUCTION(
- BUF,
- {
- (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1;
- (void)s3;
- }),
-
- INIT_INSTRUCTION(
- BOF,
- {
- (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1;
- (void)s3;
- }),
-
- INIT_INSTRUCTION(
- PUSH,
- {
- s1 = s1 + s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- POP,
- {
- s1 = s1 + s3;
- (void)pc;
- (void)s2;
- (void)this;
- }),
-
- INIT_INSTRUCTION(
- RET,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
-
- /* NOP */
- INIT_INSTRUCTION(
- NOP,
- {
- (void)pc;
- (void)s3;
- (void)s2;
- (void)s1;
- (void)this;
- }),
- };
-}
+// Switch statements for each instruction
void EX::advance_helper()
{
signed int s1, s2, s3;
+ std::array<signed int, V_R_LIMIT> v1, v2, v3;
+ signed int v_len;
unsigned int pc;
Mnemonic m;
m = this->curr_instr->mnemonic;
- s1 = this->curr_instr->operands.integer.slot_one;
- s2 = this->curr_instr->operands.integer.slot_two;
- s3 = this->curr_instr->operands.integer.slot_three;
- pc = this->curr_instr->slot_B;
- this->instr_map[m](s1, s2, s3, pc);
+ if(this->is_vector_type(m)) {
+ v1 = this->curr_instr->operands.vector.slot_one;
+ v2 = this->curr_instr->operands.vector.slot_two;
+ v3 = this->curr_instr->operands.vector.slot_three;
+ v_len = this->curr_instr->slot_A;
+ /*if(v_len == 0){
+ //clear vector reg
+ v1.fill(0);
+ v2.fill(0);
+ v3.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;
+ pc = this->curr_instr->slot_B;
+ }
- this->curr_instr->operands.integer.slot_one = s1;
+ if(this->is_logical(m)) {
+ this->set_condition(OF, false);
+ this->set_condition(UF, false);
+ }
+
+ switch(m) {
+ case ADD:
+ this->set_condition(OF, ADDITION_OF_GUARD(s1, s2));
+ this->set_condition(UF, ADDITION_UF_GUARD(s1, s2));
+ s1 = s1 + s2;
+ break;
+
+ case SUB:
+ this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2));
+ this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2));
+ s1 = s1 - s2;
+ break;
+
+ case MUL:
+ this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2));
+ this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2));
+ s1 = s1 * s2;
+ break;
+
+ case QUOT:
+ this->handle_divide(s1, s2, false);
+ break;
+
+ case REM:
+ this->handle_divide(s1, s2, true);
+ break;
+
+ case SFTR:
+ s1 = s1 >> s2;
+ break;
+
+ case SFTL:
+ s1 = s1 << s2;
+ break;
+
+ case AND:
+ s1 = s1 & s2;
+ break;
+
+ case OR:
+ s1 = s1 | s2;
+ break;
+
+ case XOR:
+ s1 = s1 ^ s2;
+ break;
+
+ case NOT:
+ s1 = ~s1;
+ break;
+
+ case CMP:
+ (s1 > s2) ? this->set_condition(GT, true)
+ : this->set_condition(GT, false);
+ (s1 == s2) ? this->set_condition(EQ, true)
+ : this->set_condition(EQ, false);
+ break;
+
+ case ADDI:
+ this->set_condition(OF, ADDITION_OF_GUARD(s1, s3));
+ this->set_condition(UF, ADDITION_UF_GUARD(s1, s3));
+ s1 = s1 + s3;
+ break;
+
+ case SUBI:
+ this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3));
+ this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3));
+ s1 = s1 - s3;
+ break;
+
+ case SFTRI:
+ s1 = s1 >> s3;
+ break;
+
+ case SFTLI:
+ s1 = s1 << s3;
+ break;
+
+ case ANDI:
+ s1 = s1 & s3;
+ break;
+
+ case ORI:
+ s1 = s1 | s3;
+ break;
+
+ case XORI:
+ s1 = s1 ^ s3;
+ break;
+
+ case LOAD:
+ case STORE:
+ case PUSH:
+ case POP:
+ s1 = s1 + s3;
+ break;
+
+ case JMP:
+ case JAL:
+ s1 = s1 + s2;
+ break;
+
+ case JRL:
+ s1 = pc + s2;
+ break;
+
+ case BEQ:
+ (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1;
+ break;
+
+ case BGT:
+ (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1;
+ break;
+
+ case BUF:
+ (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1;
+ break;
+
+ case BOF:
+ (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1;
+ break;
+
+ case ADDV:
+ if(v_len ==0){
+
+ } else {
+ 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];
+ }
+ }
+ 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];
+ }
+ 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];
+ }
+ break;
+ case DIVV:
+ for(int i=0;i<v_len;i++){
+ this->handle_divide(v1[i],v2[i],false);
+ }
+ break;
+ case CEV:
+ case LOADV:
+ case STOREV:
+ break;
+
+ case RET:
+ case NOP:
+ break;
+
+ }
+
this->status = OK;
}
diff --git a/src/id.cc b/src/id.cc
index 0135c21..b976ef0 100644
--- a/src/id.cc
+++ b/src/id.cc
@@ -22,30 +22,26 @@
#include "response.h"
#include "stage.h"
-void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m)
+Response ID::read_guard(signed int &v)
{
- unsigned int opcode, opcode_size;
-
- type = GET_LS_BITS(raw, TYPE_SIZE);
- opcode_size = (type == 0b0) ? R_OPCODE_SIZE : OPCODE_SIZE;
- opcode = GET_MID_BITS(raw, TYPE_SIZE, TYPE_SIZE + opcode_size);
- try {
- m = instr::mnemonic_map.at((opcode << TYPE_SIZE) + type);
- } catch (std::out_of_range const &) {
- m = NOP;
+ Response r;
+ if (this->is_checked_out(v))
+ r = STALLED;
+ else {
+ r = OK;
+ v = this->dereference_register<signed int>(v);
}
-
- raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size);
+ return r;
}
-Response ID::read_guard(signed int &v)
+Response ID::read_vec_guard(signed int v, std::array<signed int, V_R_LIMIT> &vrs)
{
Response r;
if (this->is_checked_out(v))
r = STALLED;
else {
r = OK;
- v = this->dereference_register(v);
+ vrs = this->dereference_register<std::array<signed int, V_R_LIMIT>>(v);
}
return r;
}
@@ -59,54 +55,95 @@ void ID::write_guard(signed int &v)
this->checked_out.push_back(v);
this->curr_instr->checked_out = v;
}
- v = this->dereference_register(v);
+ v = this->dereference_register<signed int>(v);
+}
+
+void ID::write_vec_guard(signed int v, std::array<signed int, V_R_LIMIT> &vrs){
+
+ // zero register shouldn't be written.
+ if (v != 0) {
+ // 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;
+ }
+ vrs = this->dereference_register<std::array<signed int, V_R_LIMIT>>(v);
}
void ID::advance_helper()
{
- signed int s1, s2, s3;
- Mnemonic m;
+ signed int s1;
- if (curr_instr->mnemonic == NOP)
+ if (this->curr_instr->mnemonic == NOP)
this->status = OK;
else {
- s1 = curr_instr->slot_A;
- get_instr_fields(s1, s2, s3, m);
- if (this->status == OK) {
- curr_instr->operands.integer.slot_one = s1;
- curr_instr->operands.integer.slot_two = s2;
- curr_instr->operands.integer.slot_three = s3;
- curr_instr->mnemonic = m;
- }
+ // instuction in bits in s1
+ s1 = this->curr_instr->slot_A;
+ get_instr_fields(s1);
}
}
-void ID::get_instr_fields(
- signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
+void ID::get_instr_fields(signed int &s1)
{
unsigned int type;
+ Mnemonic m;
this->split_instr(s1, type, m);
-
+ this->curr_instr->mnemonic = m;
switch (type) {
case 0b00:
- this->decode_R_type(s1, s2, s3, m);
+ this->decode_R_type(s1);
break;
case 0b01:
- this->decode_I_type(s1, s2, s3, m);
+ this->decode_I_type(s1);
break;
case 0b10:
- this->decode_J_type(s1, s2, s3, m);
+ this->decode_J_type(s1);
break;
case 0b11:
+ // not defined, m = NOP
this->status = OK;
}
}
-void ID::decode_R_type(
- signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
+void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m)
+{
+ unsigned int opcode, opcode_size;
+
+ type = GET_LS_BITS(raw, TYPE_SIZE);
+ opcode_size = (type == 0b0) ? R_OPCODE_SIZE : OPCODE_SIZE;
+ opcode = GET_MID_BITS(raw, TYPE_SIZE, TYPE_SIZE + opcode_size);
+ try {
+ m = instr::mnemonic_map.at((opcode << TYPE_SIZE) + type);
+ } catch (std::out_of_range const &) {
+ m = NOP;
+ }
+
+ raw = (unsigned int)raw >> (TYPE_SIZE + opcode_size);
+}
+
+Response ID::set_vlen(){
+ signed int vlen_reg = 4;
+ Response r;
+ r = this->read_guard(vlen_reg);
+ vlen_reg = vlen_reg & 0xf;
+ if (r == OK){
+ if (vlen_reg > V_R_LIMIT){
+ this->curr_instr->slot_A = V_R_LIMIT;
+ } else {
+ this->curr_instr->slot_A = vlen_reg;
+ }
+ }
+ return r;
+}
+
+
+
+void ID::decode_R_type(signed int &s1)
{
unsigned int s0b, s1b, s2b;
+ signed int s2, s3;
Response r1, r2;
+ Response r3 = OK;
s0b = REG_SIZE;
s1b = s0b + REG_SIZE;
@@ -115,46 +152,85 @@ void ID::decode_R_type(
s2 = GET_MID_BITS(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
- r1 = this->read_guard(s1);
- r2 = this->read_guard(s2);
- this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
+ if(this->is_vector_type(this->curr_instr->mnemonic)){
+ r1 = this->read_vec_guard(s1, this->curr_instr->operands.vector.slot_one);
+ r2 = this->read_vec_guard(s2, this->curr_instr->operands.vector.slot_two);
+ r3 = this->set_vlen();
+ } else {
+ r1 = this->read_guard(s1);
+ this->curr_instr->operands.integer.slot_one = s1;
+ r2 = this->read_guard(s2);
+ this->curr_instr->operands.integer.slot_two = s2;
+ }
- switch (m) {
+ this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED;
+
+ switch (this->curr_instr->mnemonic) {
case CMP:
case CEV:
break;
+ case ADDV:
+ case SUBV:
+ case MULV:
+ case DIVV:
+ if(this->status == OK){
+ this->write_vec_guard(s3, this->curr_instr->operands.vector.slot_three);
+ }
+ break;
default:
if (this->status == OK)
this->write_guard(s3);
+ this->curr_instr->operands.integer.slot_three = s3;
}
}
-void ID::decode_I_type(
- signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
+void ID::decode_I_type(signed int &s1)
{
unsigned int s0b, s1b, s2b;
+ signed int s2, s3;
Response r1, r2;
+ Response r3 = OK;
s0b = REG_SIZE;
s1b = s0b + REG_SIZE;
s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE;
s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b);
- switch (m) {
+ switch (this->curr_instr->mnemonic) {
case STORE:
- case STOREV:
s2 = GET_MID_BITS(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
// both operands are read values
r1 = this->read_guard(s1);
+ this->curr_instr->operands.integer.slot_one = s1;
r2 = this->read_guard(s2);
+ this->curr_instr->operands.integer.slot_two = s2;
this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
return;
- case LOAD:
+ case STOREV:
+ s2 = GET_MID_BITS(s1, s0b, s1b);
+ s1 = GET_LS_BITS(s1, s0b);
+
+ // both operands are read values
+ r1 = this->read_vec_guard(s1,this->curr_instr->operands.vector.slot_one);
+ r2 = this->read_vec_guard(s2,this->curr_instr->operands.vector.slot_two);
+ r3 = this->set_vlen();
+
+ this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED;
+ return;
case LOADV:
s2 = GET_LS_BITS(s1, s0b);
s1 = GET_MID_BITS(s1, s0b, s1b);
+ r1 = this->read_vec_guard(s1, this->curr_instr->operands.vector.slot_one);
+ r3 = this->set_vlen();
+ if (r1 == OK && r3 == OK)
+ this->write_vec_guard(s2, this->curr_instr->operands.vector.slot_two);
+ this->status = (r1 == OK && r3 == OK) ? OK : STALLED;
+ return;
+ case LOAD:
+ s2 = GET_LS_BITS(s1, s0b);
+ s1 = GET_MID_BITS(s1, s0b, s1b);
break;
default:
s2 = GET_MID_BITS(s1, s0b, s1b);
@@ -162,15 +238,18 @@ void ID::decode_I_type(
}
r1 = this->read_guard(s1);
- if (r1 == OK)
+ this->curr_instr->operands.integer.slot_one = s1;
+ if (r1 == OK){
this->write_guard(s2);
+ this->curr_instr->operands.integer.slot_two = s2;
+ }
this->status = r1;
}
-void ID::decode_J_type(
- signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
+void ID::decode_J_type(signed int &s1)
{
Response r1, r2;
+ signed int s2,s3;
unsigned int s0b, s1b;
s0b = REG_SIZE;
@@ -179,15 +258,17 @@ void ID::decode_J_type(
s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
- switch (m) {
+ switch (this->curr_instr->mnemonic) {
case PUSH:
s2 = s1; // source
s3 = 2; // stack pointer
s1 = -1; // increment amount
r1 = this->read_guard(s2);
+ this->curr_instr->operands.integer.slot_two = s2;
r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer
if (r1 == OK && r2 == OK) {
this->write_guard(s3); // we write the stack pointer
+ this->curr_instr->operands.integer.slot_three = s3;
}
this->status = (r1 == OK && r2 == OK) ? OK : STALLED;
break;
@@ -198,7 +279,9 @@ void ID::decode_J_type(
r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer
if (r1 == OK) {
this->write_guard(s2);
+ this->curr_instr->operands.integer.slot_two = s2;
this->write_guard(s3); // we write the stack pointer
+ this->curr_instr->operands.integer.slot_three = s3;
}
this->status = r1;
break;
@@ -207,6 +290,7 @@ void ID::decode_J_type(
[[fallthrough]];
default:
this->status = this->read_guard(s1);
+ this->curr_instr->operands.integer.slot_one = s1;
}
}
diff --git a/src/stage.cc b/src/stage.cc
index 55756b6..47e7e32 100644
--- a/src/stage.cc
+++ b/src/stage.cc
@@ -16,6 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "stage.h"
+#include "pipe_spec.h"
#include <array>
#include <deque>
@@ -29,7 +30,7 @@ Stage::Stage(Stage *next)
Stage::~Stage() { delete this->next; };
std::array<int, GPR_NUM> Stage::gprs;
-std::array<int, V_NUM> Stage::vrs;
+std::array<std::array<signed int, V_R_LIMIT>, V_NUM> Stage::vrs;
std::deque<signed int> Stage::checked_out;
unsigned int Stage::pc;
Storage *Stage::storage;
@@ -65,6 +66,14 @@ InstrDTO *Stage::advance(Response p)
return r;
}
+bool Stage::is_vector_type(Mnemonic m){
+ return (m == ADDV || m == SUBV || m == MULV || m == DIVV || m == CEV || m == LOADV || m == STOREV);
+}
+
+bool Stage::is_logical(Mnemonic m){
+ return (m == ANDI || m == ORI || m == XORI || m == AND || m == OR || m == XOR || m== NOT);
+}
+
std::vector<int> Stage::stage_info()
{
std::vector<int> info;
@@ -86,32 +95,6 @@ void Stage::set_condition(CC c, bool v)
this->gprs[3] = this->gprs[3] & ~(1 << c);
}
-signed int Stage::dereference_register(signed int v)
-{
- signed int r;
-
- if (v < 0 || v >= GPR_NUM + V_NUM) {
- throw std::out_of_range(
- "instruction tried to access register which does not exist");
- }
-
- r = (v >= GPR_NUM) ? this->vrs[v % GPR_NUM] : this->gprs[v];
- return r;
-}
-
-void Stage::store_register(signed int v, signed int d)
-{
- if (v < 0 || v >= GPR_NUM + V_NUM) {
- throw std::out_of_range(
- "instruction tried to access register which does not exist");
- }
-
- if (v >= GPR_NUM)
- this->vrs[v % GPR_NUM] = d;
- else
- this->gprs[v] = d;
-}
-
bool Stage::is_checked_out(signed int r)
{
return std::find(this->checked_out.begin(), this->checked_out.end(), r) !=
diff --git a/src/vec.cc b/src/vec.cc
deleted file mode 100644
index e3e0a6c..0000000
--- a/src/vec.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-#include "vec.h"
-
-template<typename T>
-Vec<T> Vec<T>::operator+(const Vec<T>& other) const {
- if (data.size() != other.data.size()) throw std::invalid_argument("Size mismatch");
- Vec<T> result;
- for (size_t i = 0; i < data.size(); ++i)
- result.data.push_back(data[i] + other.data[i]);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator-(const Vec<T>& other) const {
- if (data.size() != other.data.size()) throw std::invalid_argument("Size mismatch");
- Vec<T> result;
- for (size_t i = 0; i < data.size(); ++i)
- result.data.push_back(data[i] - other.data[i]);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator*(const Vec<T>& other) const {
- if (data.size() != other.data.size()) throw std::invalid_argument("Size mismatch");
- Vec<T> result;
- for (size_t i = 0; i < data.size(); ++i)
- result.data.push_back(data[i] * other.data[i]);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator/(const Vec<T>& other) const {
- if (data.size() != other.data.size()) throw std::invalid_argument("Size mismatch");
- Vec<T> result;
- for (size_t i = 0; i < data.size(); ++i)
- result.data.push_back(other.data[i] == 0 ? 0 : data[i] / other.data[i]);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator%(const Vec<T>& other) const {
- if (data.size() != other.data.size()) throw std::invalid_argument("Size mismatch");
- Vec<T> result;
- for (size_t i = 0; i < data.size(); ++i)
- result.data.push_back(other.data[i] == 0 ? 0 : data[i] % other.data[i]);
- return result;
-}
-
-// Scalar versions
-template<typename T>
-Vec<T> Vec<T>::operator+(T scalar) const {
- Vec<T> result;
- for (const auto& val : data) result.data.push_back(val + scalar);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator-(T scalar) const {
- Vec<T> result;
- for (const auto& val : data) result.data.push_back(val - scalar);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator*(T scalar) const {
- Vec<T> result;
- for (const auto& val : data) result.data.push_back(val * scalar);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator/(T scalar) const {
- Vec<T> result;
- for (const auto& val : data) result.data.push_back(scalar == 0 ? 0 : val / scalar);
- return result;
-}
-
-template<typename T>
-Vec<T> Vec<T>::operator%(T scalar) const {
- Vec<T> result;
- for (const auto& val : data) result.data.push_back(scalar == 0 ? 0 : val % scalar);
- return result;
-}
-
-// Scalar - Vector versions
-template<typename T>
-Vec<T> operator-(T scalar, const Vec<T>& vec) {
- Vec<T> result;
- for (size_t i = 0; i < vec.size(); ++i)
- result = result + (scalar - vec.data[i]);
- return result;
-}
-
-template<typename T>
-Vec<T> operator/(T scalar, const Vec<T>& vec) {
- Vec<T> result;
- for (auto val : vec.data)
- result = result + (val == 0 ? 0 : scalar / val);
- return result;
-}
-
-template<typename T>
-Vec<T> operator%(T scalar, const Vec<T>& vec) {
- Vec<T> result;
- for (auto val : vec.data)
- result = result + (val == 0 ? 0 : scalar % val);
- return result;
-}
-
-template<typename T>
-void Vec<T>::print() const {
- for (auto val : data) std::cout << val << " ";
- std::cout << std::endl;
-}
diff --git a/src/wb.cc b/src/wb.cc
index cd24c6a..79efe44 100644
--- a/src/wb.cc
+++ b/src/wb.cc
@@ -45,13 +45,13 @@ void WB::write_handler()
// POP performs a second register write
reg = this->checked_out.front();
this->checked_out.pop_front();
- this->store_register(
+ this->store_register<signed int>(
reg, this->curr_instr->operands.integer.slot_three);
}
this->checked_out.pop_front();
reg = this->curr_instr->checked_out;
- this->store_register(reg, this->curr_instr->operands.integer.slot_one);
+ this->store_register<signed int>(reg, this->curr_instr->operands.integer.slot_one);
}
void WB::jump_handler()