From f4a5db14436ddbb2820c0abefcb34e5482105a12 Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 8 May 2025 19:44:23 -0400 Subject: Move is_logical_type and is_vector_type to instr.h --- src/id.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/id.cc') diff --git a/src/id.cc b/src/id.cc index e4790ef..a853602 100644 --- a/src/id.cc +++ b/src/id.cc @@ -153,7 +153,7 @@ void ID::decode_R_type(signed int &s1) s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); - if (this->is_vector_type(this->curr_instr->mnemonic)) { + if (instr::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( -- cgit v1.2.3 From 2aabad6ed432831d6686700118cd189cb157e5cc Mon Sep 17 00:00:00 2001 From: bd Date: Thu, 8 May 2025 20:00:14 -0400 Subject: Use templates rather than two write guard methods --- inc/id.h | 33 +++++++++++++++++++++------------ src/id.cc | 46 ++++++++++------------------------------------ 2 files changed, 31 insertions(+), 48 deletions(-) (limited to 'src/id.cc') diff --git a/inc/id.h b/inc/id.h index e8e9c36..ccce961 100644 --- a/inc/id.h +++ b/inc/id.h @@ -25,8 +25,8 @@ 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. @@ -42,18 +42,7 @@ class ID : public Stage * @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 &v); - - void write_vec_guard(signed int r, std::array &v); - Response set_vlen(); private: @@ -95,6 +84,26 @@ 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 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(v); + return r; + } }; #endif /* ID_H_INCLUDED */ diff --git a/src/id.cc b/src/id.cc index a853602..e0e16c4 100644 --- a/src/id.cc +++ b/src/id.cc @@ -47,31 +47,6 @@ ID::read_vec_guard(signed int v, std::array &vrs) return r; } -void ID::write_guard(signed int &v) -{ - // 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; - } - v = this->dereference_register(v); -} - -void ID::write_vec_guard(signed int v, std::array &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>(v); -} - void ID::advance_helper() { signed int s1; @@ -177,13 +152,13 @@ void ID::decode_R_type(signed int &s1) case MULV: case DIVV: if (this->status == OK) { - this->write_vec_guard( - s3, this->curr_instr->operands.vector.slot_three); + this->curr_instr->operands.vector.slot_three = + this->write_guard>(s3); } break; default: if (this->status == OK) { - this->write_guard(s3); + this->write_guard(s3); this->curr_instr->operands.integer.slot_three = s3; } } @@ -242,9 +217,8 @@ void ID::decode_I_type(signed int &s1) r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->write_vec_guard( - s2, - this->curr_instr->operands.load_store_vector.vector_register); + this->curr_instr->operands.load_store_vector.vector_register = + this->write_guard>(s2); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; case LOAD: @@ -261,7 +235,7 @@ void ID::decode_I_type(signed int &s1) r1 = this->read_guard(s1); this->curr_instr->operands.integer.slot_one = s1; if (r1 == OK) { - this->write_guard(s2); + this->write_guard(s2); this->curr_instr->operands.integer.slot_two = s2; } this->status = r1; @@ -290,7 +264,7 @@ void ID::decode_J_type(signed int &s1) 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->write_guard(s3); // we write the stack pointer this->curr_instr->operands.integer.slot_three = s3; } this->status = (r1 == OK && r2 == OK) ? OK : STALLED; @@ -303,9 +277,9 @@ void ID::decode_J_type(signed int &s1) r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK) { - this->write_guard(s2); + this->write_guard(s2); this->curr_instr->operands.integer.slot_two = s2; - this->write_guard(s3); // we write the stack pointer + this->write_guard(s3); // we write the stack pointer this->curr_instr->operands.integer.slot_three = s3; } this->status = r1; @@ -315,7 +289,7 @@ void ID::decode_J_type(signed int &s1) [[fallthrough]]; default: this->status = this->read_guard(s1); - if(this->status == OK){ + if (this->status == OK) { this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; this->curr_instr->operands.integer.slot_three = s3; -- cgit v1.2.3 From b384a584f5feaa05b77d7979cce9dad500bd1e2e Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 14:59:22 -0400 Subject: Fix new bug where s3 was not assigned with r type --- src/id.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/id.cc') diff --git a/src/id.cc b/src/id.cc index e0e16c4..ebf6db6 100644 --- a/src/id.cc +++ b/src/id.cc @@ -158,8 +158,8 @@ void ID::decode_R_type(signed int &s1) break; default: if (this->status == OK) { - this->write_guard(s3); - this->curr_instr->operands.integer.slot_three = s3; + this->curr_instr->operands.integer.slot_three = + this->write_guard(s3); } } } -- cgit v1.2.3 From a29d974ac8cec5803dd9c9ea66f3ac5d06a1fe2b Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 15:00:40 -0400 Subject: Fix other instances of the same bug --- src/id.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/id.cc') diff --git a/src/id.cc b/src/id.cc index ebf6db6..430bf09 100644 --- a/src/id.cc +++ b/src/id.cc @@ -235,8 +235,8 @@ void ID::decode_I_type(signed int &s1) r1 = this->read_guard(s1); this->curr_instr->operands.integer.slot_one = s1; if (r1 == OK) { - this->write_guard(s2); - this->curr_instr->operands.integer.slot_two = s2; + this->curr_instr->operands.integer.slot_two = + this->write_guard(s2); } this->status = r1; } @@ -264,8 +264,9 @@ void ID::decode_J_type(signed int &s1) 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; + // we write the stack pointer + this->curr_instr->operands.integer.slot_three = + this->write_guard(s3); } this->status = (r1 == OK && r2 == OK) ? OK : STALLED; break; @@ -277,10 +278,11 @@ void ID::decode_J_type(signed int &s1) 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->curr_instr->operands.integer.slot_two = + this->write_guard(s2); + // we write the stack pointer + this->curr_instr->operands.integer.slot_three = + this->write_guard(s3); } this->status = r1; break; -- cgit v1.2.3 From d0bb0aaf39bb61736e72b30e4d8f1a4a39536a0c Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 15:17:40 -0400 Subject: Combine read_vec_guard and read_guard using templates --- inc/id.h | 31 ++++++++++++++++++++----------- src/id.cc | 51 +++++++++++++-------------------------------------- tests/id.cc | 15 --------------- 3 files changed, 33 insertions(+), 64 deletions(-) (limited to 'src/id.cc') diff --git a/inc/id.h b/inc/id.h index ccce961..c1928ed 100644 --- a/inc/id.h +++ b/inc/id.h @@ -32,17 +32,6 @@ class ID : public Stage * 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); - Response read_vec_guard(signed int r, std::array &v); Response set_vlen(); private: @@ -104,6 +93,26 @@ class ID : public Stage r = this->dereference_register(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 replaces reg with the value of the register and + * returns OK. If false, returns STALLED. + * + * @param the registers number, to be dereferenced. + * @return OK if `reg` is not checked out, STALLED otherwise. + */ + template Response read_guard(int reg, T &result) + { + Response response; + if (this->is_checked_out(reg)) + response = STALLED; + else { + response = OK; + result = this->dereference_register(reg); + } + return response; + } }; #endif /* ID_H_INCLUDED */ diff --git a/src/id.cc b/src/id.cc index 430bf09..bc6b873 100644 --- a/src/id.cc +++ b/src/id.cc @@ -22,31 +22,6 @@ #include "response.h" #include "stage.h" -Response ID::read_guard(signed int &v) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - v = this->dereference_register(v); - } - return r; -} - -Response -ID::read_vec_guard(signed int v, std::array &vrs) -{ - Response r; - if (this->is_checked_out(v)) - r = STALLED; - else { - r = OK; - vrs = this->dereference_register>(v); - } - return r; -} - void ID::advance_helper() { signed int s1; @@ -102,7 +77,7 @@ Response ID::set_vlen() { signed int vlen_reg = 4; Response r; - r = this->read_guard(vlen_reg); + r = this->read_guard(vlen_reg, vlen_reg); vlen_reg = vlen_reg & 0xf; if (r == OK) { if (vlen_reg > V_R_LIMIT) { @@ -129,15 +104,15 @@ void ID::decode_R_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); if (instr::is_vector_type(this->curr_instr->mnemonic)) { - r1 = this->read_vec_guard( + r1 = this->read_guard>( s1, this->curr_instr->operands.vector.slot_one); - r2 = this->read_vec_guard( + r2 = this->read_guard>( s2, this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); } else { - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.integer.slot_one = s1; - r2 = this->read_guard(s2); + r2 = this->read_guard(s2, s2); this->curr_instr->operands.integer.slot_two = s2; } @@ -185,10 +160,10 @@ void ID::decode_I_type(signed int &s1) // both operands are read values // s1 is base address - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.integer.slot_one = s1; // s2 is value to be stored - r2 = this->read_guard(s2); + r2 = this->read_guard(s2, s2); this->curr_instr->operands.integer.slot_two = s2; this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; @@ -198,10 +173,10 @@ void ID::decode_I_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); // base address - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.load_store_vector.base_addr = s1; // vector value to be stored - r2 = this->read_vec_guard( + r2 = this->read_guard>( s2, this->curr_instr->operands.load_store_vector.vector_register); r3 = this->set_vlen(); @@ -212,7 +187,7 @@ void ID::decode_I_type(signed int &s1) s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.load_store_vector.base_addr = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) @@ -232,7 +207,7 @@ void ID::decode_I_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); } - r1 = this->read_guard(s1); + r1 = this->read_guard(s1, s1); this->curr_instr->operands.integer.slot_one = s1; if (r1 == OK) { this->curr_instr->operands.integer.slot_two = @@ -258,7 +233,7 @@ void ID::decode_J_type(signed int &s1) s2 = s1; // source s3 = 2; // stack pointer s1 = -1; // increment amount - r1 = this->read_guard(s2); + r1 = this->read_guard(s2, s2); this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; r2 = (this->is_checked_out(s3)) ? STALLED @@ -290,7 +265,7 @@ void ID::decode_J_type(signed int &s1) s1 = 1; // link register [[fallthrough]]; default: - this->status = this->read_guard(s1); + this->status = this->read_guard(s1, s1); if (this->status == OK) { this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; diff --git a/tests/id.cc b/tests/id.cc index ca10677..0e7de3b 100644 --- a/tests/id.cc +++ b/tests/id.cc @@ -191,18 +191,3 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]") delete i; } - -TEST_CASE_METHOD(IDFixture, "read does not conflict with read", "[id]") -{ - signed int v; - Response r; - - v = 0b1; - r = this->d->read_guard(v); - CHECK(v == 0b0); - REQUIRE(r == OK); - - v = 0b1; - this->d->read_guard(v); - REQUIRE(v == 0b0); -} -- cgit v1.2.3 From 5beea0c476101ec7b122f3b2181d92ce096492fb Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 15:30:29 -0400 Subject: Further small simplifications --- inc/id.h | 9 +++++---- src/id.cc | 27 +++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/id.cc') diff --git a/inc/id.h b/inc/id.h index c1928ed..5fda2b4 100644 --- a/inc/id.h +++ b/inc/id.h @@ -60,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); @@ -96,10 +96,11 @@ class ID : public Stage /** * 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 reg with the value of the register and - * returns OK. If false, returns STALLED. + * checked out. If true, then sets `result' with the value of the register + * and returns OK. If false, returns STALLED. * - * @param the registers number, to be dereferenced. + * @param the registers number + * @param the dereferenced register value * @return OK if `reg` is not checked out, STALLED otherwise. */ template Response read_guard(int reg, T &result) diff --git a/src/id.cc b/src/id.cc index bc6b873..43975fb 100644 --- a/src/id.cc +++ b/src/id.cc @@ -24,37 +24,35 @@ void ID::advance_helper() { - signed int s1; - if (this->curr_instr->mnemonic == NOP) this->status = OK; else { // instuction in bits in s1 - s1 = this->curr_instr->slot_A; - get_instr_fields(s1); + get_instr_fields(this->curr_instr->slot_A); } } -void ID::get_instr_fields(signed int &s1) +void ID::get_instr_fields(signed int instr_bits) { unsigned int type; Mnemonic m; - this->split_instr(s1, type, m); + this->split_instr(instr_bits, type, m); this->curr_instr->mnemonic = m; switch (type) { case 0b00: - this->decode_R_type(s1); + this->decode_R_type(instr_bits); break; case 0b01: - this->decode_I_type(s1); + this->decode_I_type(instr_bits); break; case 0b10: - this->decode_J_type(s1); + this->decode_J_type(instr_bits); break; case 0b11: - // not defined, m = NOP + this->curr_instr->mnemonic = NOP; this->status = OK; } + } void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) @@ -233,9 +231,10 @@ void ID::decode_J_type(signed int &s1) s2 = s1; // source s3 = 2; // stack pointer s1 = -1; // increment amount - r1 = this->read_guard(s2, s2); + this->curr_instr->operands.integer.slot_one = s1; - this->curr_instr->operands.integer.slot_two = s2; + r1 = this->read_guard( + s2, this->curr_instr->operands.integer.slot_two); r2 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer if (r1 == OK && r2 == OK) { @@ -265,9 +264,9 @@ void ID::decode_J_type(signed int &s1) s1 = 1; // link register [[fallthrough]]; default: - this->status = this->read_guard(s1, s1); + this->status = this->read_guard( + s1, this->curr_instr->operands.integer.slot_one); if (this->status == OK) { - this->curr_instr->operands.integer.slot_one = s1; this->curr_instr->operands.integer.slot_two = s2; this->curr_instr->operands.integer.slot_three = s3; } -- cgit v1.2.3 From f0f773a1f2acc3030c89fc5aa6335f667987aa2a Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 17:02:27 -0400 Subject: Fix issue where decode would overwrite raw bits while in use --- inc/instrDTO.h | 4 ++-- src/controller.cc | 1 + src/ex.cc | 2 +- src/id.cc | 5 ++--- tests/id.cc | 16 ++++++++++++++++ 5 files changed, 22 insertions(+), 6 deletions(-) (limited to 'src/id.cc') diff --git a/inc/instrDTO.h b/inc/instrDTO.h index f3d4597..f4ef416 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -19,7 +19,7 @@ #define INSTRDTO_H #include "instr.h" #include "pipe_spec.h" -#include +#include struct U_INT_TYPE { signed int slot_one; @@ -33,7 +33,7 @@ struct V_TYPE { std::array slot_three; }; -struct LOAD_STORE_V_TYPE{ +struct LOAD_STORE_V_TYPE { signed int base_addr; signed int immediate; std::array vector_register; diff --git a/src/controller.cc b/src/controller.cc index e439b30..190d3e2 100644 --- a/src/controller.cc +++ b/src/controller.cc @@ -32,6 +32,7 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined) this->checked_out = {}; this->gprs = {0}; this->vrs.fill({0}); + this->vrs.at(0).fill(1); // constant 1 vector register this->gprs.at(2) = MEM_WORDS; // set the stack pointer } diff --git a/src/ex.cc b/src/ex.cc index f0ca5b5..73ed615 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -50,7 +50,7 @@ void EX::advance_helper() v_base_addr = this->curr_instr->operands.load_store_vector.base_addr; } - v_len = this->curr_instr->slot_A; + v_len = this->curr_instr->slot_B; if (v_len == 0) { // clear destination vector reg v1.fill(0); diff --git a/src/id.cc b/src/id.cc index 43975fb..490b03a 100644 --- a/src/id.cc +++ b/src/id.cc @@ -49,7 +49,6 @@ void ID::get_instr_fields(signed int instr_bits) this->decode_J_type(instr_bits); break; case 0b11: - this->curr_instr->mnemonic = NOP; this->status = OK; } @@ -79,9 +78,9 @@ Response ID::set_vlen() vlen_reg = vlen_reg & 0xf; if (r == OK) { if (vlen_reg > V_R_LIMIT) { - this->curr_instr->slot_A = V_R_LIMIT; + this->curr_instr->slot_B = V_R_LIMIT; } else { - this->curr_instr->slot_A = vlen_reg; + this->curr_instr->slot_B = vlen_reg; } } return r; diff --git a/tests/id.cc b/tests/id.cc index 0e7de3b..b52ad9c 100644 --- a/tests/id.cc +++ b/tests/id.cc @@ -129,6 +129,22 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # two", "[id]") delete i; } +TEST_CASE_METHOD(IDFixture, "Parse arbitrary r-type # three", "[id]") +{ + signed int t; + InstrDTO *i; + + t = this->encode_R_type(0b10000, 0b10001, 0b10101, 0b1110, 0b0); + i = this->decode_bits(t); + + CHECK(i->operands.integer.slot_one == 0x00000000); // registers are empty + CHECK(i->operands.integer.slot_two == 0x00000000); + CHECK(i->operands.integer.slot_three == 0x00000000); + CHECK(i->mnemonic == MULV); + + delete i; +} + TEST_CASE_METHOD(IDFixture, "Parse arbitrary i-type # one", "[id]") { signed int t; -- cgit v1.2.3 From ebb2a3d33d4536bcace34e9ba95198067ae19522 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 18:25:23 -0400 Subject: Add type field to InstrDTO, required for next refactor --- inc/instr.h | 13 +++++++++++-- inc/instrDTO.h | 4 ++++ src/ex.cc | 28 ++++++++++++++++++---------- src/id.cc | 13 +++++++------ src/instr.cc | 20 ++++++++------------ src/wb.cc | 2 +- 6 files changed, 49 insertions(+), 31 deletions(-) (limited to 'src/id.cc') 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 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(s1, s1); + this->curr_instr->operands.integer.slot_one = s1; + r2 = this->read_guard(s2, s2); + this->curr_instr->operands.integer.slot_two = s2; + } else { r1 = this->read_guard>( s1, this->curr_instr->operands.vector.slot_one); r2 = this->read_guard>( s2, this->curr_instr->operands.vector.slot_two); r3 = this->set_vlen(); - } else { - r1 = this->read_guard(s1, s1); - this->curr_instr->operands.integer.slot_one = s1; - r2 = this->read_guard(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 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>(reg, this->curr_instr->operands.vector.slot_one); } else { -- cgit v1.2.3 From c5e989bbf1adf6cb0ea63f5d215db7c90518c607 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 18:52:04 -0400 Subject: Rename load/store vector to i_vector --- inc/instrDTO.h | 4 ++-- src/ex.cc | 8 ++++---- src/id.cc | 12 ++++++------ src/wb.cc | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/id.cc') diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 98247a3..12c72d9 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -33,7 +33,7 @@ struct V_TYPE { std::array slot_three; }; -struct LOAD_STORE_V_TYPE { +struct VI_TYPE { signed int base_addr; signed int immediate; std::array vector_register; @@ -67,7 +67,7 @@ struct InstrDTO { 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/src/ex.cc b/src/ex.cc index 45a018a..3c9632b 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -16,11 +16,11 @@ // along with this program. If not, see . #include "ex.h" +#include "instr.h" #include "instrDTO.h" #include "pipe_spec.h" #include "response.h" #include "stage.h" -#include "instr.h" #include // Switch statements for each instruction @@ -46,9 +46,9 @@ void EX::advance_helper() v3 = this->curr_instr->operands.vector.slot_three; } else { v_immediate = - this->curr_instr->operands.load_store_vector.immediate; + this->curr_instr->operands.i_vector.immediate; v_base_addr = - this->curr_instr->operands.load_store_vector.base_addr; + this->curr_instr->operands.i_vector.base_addr; } if (v_len == 0) { // clear destination vector reg @@ -249,7 +249,7 @@ void EX::advance_helper() this->curr_instr->mnemonic != STOREV) { this->curr_instr->operands.vector.slot_one = v1; } else { - this->curr_instr->operands.load_store_vector.base_addr = + this->curr_instr->operands.i_vector.base_addr = v_base_addr; } } else { diff --git a/src/id.cc b/src/id.cc index d24497a..81527db 100644 --- a/src/id.cc +++ b/src/id.cc @@ -166,31 +166,31 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: - this->curr_instr->operands.load_store_vector.immediate = s3; + this->curr_instr->operands.i_vector.immediate = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.load_store_vector.base_addr = s1; + this->curr_instr->operands.i_vector.base_addr = s1; // vector value to be stored r2 = this->read_guard>( - s2, this->curr_instr->operands.load_store_vector.vector_register); + s2, this->curr_instr->operands.i_vector.vector_register); r3 = this->set_vlen(); this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; return; case LOADV: - this->curr_instr->operands.load_store_vector.immediate = s3; + this->curr_instr->operands.i_vector.immediate = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.load_store_vector.base_addr = s1; + this->curr_instr->operands.i_vector.base_addr = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->curr_instr->operands.load_store_vector.vector_register = + this->curr_instr->operands.i_vector.vector_register = this->write_guard>(s2); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; diff --git a/src/wb.cc b/src/wb.cc index 1c364b0..455c7ad 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -57,7 +57,7 @@ void WB::write_handler() if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { this->store_register>(reg, this->curr_instr->operands.vector.slot_one); } else { - this->store_register>(reg, this->curr_instr->operands.load_store_vector.vector_register); + this->store_register>(reg, this->curr_instr->operands.i_vector.vector_register); } } else{ this->store_register(reg, this->curr_instr->operands.integer.slot_one); -- cgit v1.2.3 From 727afe4ffac0f193696c99234a2ade3a02f73157 Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 20:35:18 -0400 Subject: Separate ex advance into methods handling different field types --- inc/ex.h | 73 +++++++++++++++++++++--------- inc/instrDTO.h | 7 +-- src/ex.cc | 137 +++++++++++++++++++++++++++++++-------------------------- src/id.cc | 14 +++--- src/mm.cc | 52 ---------------------- src/wb.cc | 2 +- 6 files changed, 138 insertions(+), 147 deletions(-) (limited to 'src/id.cc') diff --git a/inc/ex.h b/inc/ex.h index 5a5c046..0e235cb 100644 --- a/inc/ex.h +++ b/inc/ex.h @@ -23,36 +23,28 @@ #include #include -#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,11 +55,48 @@ 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 &s1, + std::array 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). diff --git a/inc/instrDTO.h b/inc/instrDTO.h index 12c72d9..ccc6ed9 100644 --- a/inc/instrDTO.h +++ b/inc/instrDTO.h @@ -21,6 +21,7 @@ #include "pipe_spec.h" #include + struct U_INT_TYPE { signed int slot_one; signed int slot_two; @@ -34,9 +35,9 @@ struct V_TYPE { }; struct VI_TYPE { - signed int base_addr; - signed int immediate; - std::array vector_register; + signed int slot_one; + signed int slot_two; + std::array slot_three; }; struct InstrDTO { diff --git a/src/ex.cc b/src/ex.cc index 3c9632b..810461f 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -21,45 +21,12 @@ #include "pipe_spec.h" #include "response.h" #include "stage.h" +#include #include -// Switch statements for each instruction -void EX::advance_helper() +void EX::handle_int_operations( + signed int &s1, signed int s2, signed int s3, Mnemonic m, unsigned int pc) { - signed int s1, s2, s3; - std::array v1, v2, v3; - signed int v_len, v_immediate, v_base_addr; - unsigned int pc; - Mnemonic m; - - s1 = 0, s2 = 0, s3 = 0; - 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 (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; - } else { - v_immediate = - this->curr_instr->operands.i_vector.immediate; - v_base_addr = - this->curr_instr->operands.i_vector.base_addr; - } - if (v_len == 0) { - // clear destination vector reg - v1.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; - } - switch (m) { case ADD: this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); @@ -196,36 +163,55 @@ void EX::advance_helper() (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; break; + case RET: + case NOP: + break; + + default: + throw std::invalid_argument( + "handle_int_operations received a vector operation!"); + } +} + +void EX::handle_vector_operations( + std::array &s1, + std::array s2, + Mnemonic m, + unsigned int v_len) +{ + unsigned int i; + + switch (m) { case ADDV: - 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]; + for (i = 0; i < v_len; i++) { + this->set_condition(OF, ADDITION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, ADDITION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] + s2[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]; + for (i = 0; i < v_len; i++) { + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] - s2[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]; + for (i = 0; i < v_len; i++) { + this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1[i], s2[i])); + this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1[i], s2[i])); + s1[i] = s1[i] * s2[i]; } break; case DIVV: - for (int i = 0; i < v_len; i++) { - this->handle_divide(v1[i], v2[i], false); + for (i = 0; i < v_len; i++) { + this->handle_divide(s1[i], s2[i], false); } break; case CEV: - int i; + for (i = 0; i < v_len; i++) { - if (v1[i] != v2[i]) { + if (s1[i] != s2[i]) { break; } } @@ -235,26 +221,53 @@ void EX::advance_helper() this->set_condition(EQ, false); } break; + + default: + throw std::invalid_argument( + "handle_vector_operations received an integer operation!"); + } +} + +void EX::handle_i_vector_operations(signed int &s1, signed int s2, Mnemonic m) +{ + switch (m) { case LOADV: case STOREV: - v_base_addr = v_base_addr + v_immediate; + s1 = s1 + s2; break; case RET: case NOP: break; + + default: + throw std::invalid_argument("handle_i_vector_operations did not " + "receive a LOADV or STOREV operation!"); } - 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; - } else { - this->curr_instr->operands.i_vector.base_addr = - v_base_addr; - } +} + +void EX::advance_helper() +{ + unsigned int v_len_or_pc; + Mnemonic m; + m = this->curr_instr->mnemonic; + v_len_or_pc = this->curr_instr->slot_B; + + if (this->curr_instr->type == FieldType::SI_INT) { + handle_int_operations( + this->curr_instr->operands.integer.slot_one, + this->curr_instr->operands.integer.slot_two, + this->curr_instr->operands.integer.slot_three, m, v_len_or_pc); + } else if (this->curr_instr->type == FieldType::R_VECT) { + handle_vector_operations( + this->curr_instr->operands.vector.slot_one, + this->curr_instr->operands.vector.slot_two, m, v_len_or_pc); } else { - this->curr_instr->operands.integer.slot_one = s1; + handle_i_vector_operations( + this->curr_instr->operands.i_vector.slot_one, + this->curr_instr->operands.i_vector.slot_two, m); } + this->status = OK; } diff --git a/src/id.cc b/src/id.cc index 81527db..2645aeb 100644 --- a/src/id.cc +++ b/src/id.cc @@ -147,7 +147,7 @@ void ID::decode_I_type(signed int &s1) s0b = REG_SIZE; s1b = s0b + REG_SIZE; s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE; - // s3 is immediate + // s3 is slot_two s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b); switch (this->curr_instr->mnemonic) { @@ -166,31 +166,31 @@ void ID::decode_I_type(signed int &s1) this->status = (r1 == OK && r2 == OK) ? OK : STALLED; return; case STOREV: - this->curr_instr->operands.i_vector.immediate = s3; + this->curr_instr->operands.i_vector.slot_two = s3; s2 = GET_MID_BITS(s1, s0b, s1b); s1 = GET_LS_BITS(s1, s0b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.i_vector.base_addr = s1; + this->curr_instr->operands.i_vector.slot_one = s1; // vector value to be stored r2 = this->read_guard>( - s2, this->curr_instr->operands.i_vector.vector_register); + s2, this->curr_instr->operands.i_vector.slot_three); r3 = this->set_vlen(); this->status = (r1 == OK && r2 == OK && r3 == OK) ? OK : STALLED; return; case LOADV: - this->curr_instr->operands.i_vector.immediate = s3; + this->curr_instr->operands.i_vector.slot_two = s3; s2 = GET_LS_BITS(s1, s0b); s1 = GET_MID_BITS(s1, s0b, s1b); // base address r1 = this->read_guard(s1, s1); - this->curr_instr->operands.i_vector.base_addr = s1; + this->curr_instr->operands.i_vector.slot_one = s1; r3 = this->set_vlen(); if (r1 == OK && r3 == OK) // vector destination - this->curr_instr->operands.i_vector.vector_register = + this->curr_instr->operands.i_vector.slot_three = this->write_guard>(s2); this->status = (r1 == OK && r3 == OK) ? OK : STALLED; return; diff --git a/src/mm.cc b/src/mm.cc index 8134cf5..ac77433 100644 --- a/src/mm.cc +++ b/src/mm.cc @@ -24,7 +24,6 @@ void MM::advance_helper() { signed int data; int i; - int vector_delay = VECTOR_MEM_DELAY; switch (this->curr_instr->mnemonic) { case LOAD: @@ -36,32 +35,6 @@ void MM::advance_helper() } else this->status = STALLED; break; - case LOADV: - if (vector_delay == 0){ - signed int word_address = this->curr_instr->operands.load_store_vector.base_addr; - int j = 0; - while(j < this->curr_instr->slot_A){ - i = this->storage->read_word(this, word_address, data); - this->status = i ? OK : STALLED; - if (this->status == OK) { - this->curr_instr->operands.load_store_vector.vector_register[j] = data; - // +1 or +4? - word_address += 1; - j++; - } else { - break; - } - } - if(this->status == OK){ - // if vector is loaded, reset delay - vector_delay = VECTOR_MEM_DELAY; - } else { - this->status = STALLED; - } - } else { - vector_delay--; - } - break; case PUSH: case STORE: @@ -73,31 +46,6 @@ void MM::advance_helper() this->status = STALLED; } break; - case STOREV: - if (vector_delay == 0){ - signed int word_address = this->curr_instr->operands.load_store_vector.base_addr; - int j = 0; - while(j < this->curr_instr->slot_A){ - this->storage->write_word( - this, this->curr_instr->operands.load_store_vector.vector_register[j], word_address); - this->status = i ? OK : STALLED; - if (this->status != OK) { - break; - } else { - word_address += 1; - j++; - } - } - if(this->status == OK){ - // if vector is stored , reset delay - vector_delay = VECTOR_MEM_DELAY; - } else { - this->status = STALLED; - } - } else { - vector_delay--; - } - break; case POP: i = this->storage->read_word(this, this->curr_instr->operands.integer.slot_three, data); diff --git a/src/wb.cc b/src/wb.cc index 455c7ad..e174157 100644 --- a/src/wb.cc +++ b/src/wb.cc @@ -57,7 +57,7 @@ void WB::write_handler() if(this->curr_instr->mnemonic != STOREV && this->curr_instr->mnemonic != LOADV) { this->store_register>(reg, this->curr_instr->operands.vector.slot_one); } else { - this->store_register>(reg, this->curr_instr->operands.i_vector.vector_register); + this->store_register>(reg, this->curr_instr->operands.i_vector.slot_three); } } else{ this->store_register(reg, this->curr_instr->operands.integer.slot_one); -- cgit v1.2.3 From 2269a338f9e5ad7a29bef5ff73bbb4d72489a92e Mon Sep 17 00:00:00 2001 From: bd Date: Sat, 10 May 2025 21:24:41 -0400 Subject: Fix off-by-one in CEV equal --- src/ex.cc | 10 ++++------ src/id.cc | 13 ++++++------- 2 files changed, 10 insertions(+), 13 deletions(-) (limited to 'src/id.cc') diff --git a/src/ex.cc b/src/ex.cc index 4fcda0a..066f584 100644 --- a/src/ex.cc +++ b/src/ex.cc @@ -221,17 +221,15 @@ void EX::handle_vector_operations( } break; case CEV: - + bool eq; + eq = true; for (i = 0; i < v_len; i++) { if (s1[i] != s2[i]) { + eq = false; break; } } - if (i == v_len) { - this->set_condition(EQ, true); - } else { - this->set_condition(EQ, false); - } + this->set_condition(EQ, eq); break; default: diff --git a/src/id.cc b/src/id.cc index 2645aeb..85637a6 100644 --- a/src/id.cc +++ b/src/id.cc @@ -52,7 +52,6 @@ void ID::get_instr_fields(signed int instr_bits) case 0b11: this->status = OK; } - } void ID::split_instr(signed int &raw, unsigned int &type, Mnemonic &m) @@ -91,8 +90,7 @@ void ID::decode_R_type(signed int &s1) { unsigned int s0b, s1b, s2b; signed int s2, s3; - Response r1, r2; - Response r3 = OK; + Response r1, r2, r3; s0b = REG_SIZE; s1b = s0b + REG_SIZE; @@ -102,10 +100,11 @@ void ID::decode_R_type(signed int &s1) s1 = GET_LS_BITS(s1, s0b); if (this->curr_instr->type == SI_INT) { - r1 = this->read_guard(s1, s1); - this->curr_instr->operands.integer.slot_one = s1; - r2 = this->read_guard(s2, s2); - this->curr_instr->operands.integer.slot_two = s2; + r1 = this->read_guard( + s1, this->curr_instr->operands.integer.slot_one); + r2 = this->read_guard( + s2, this->curr_instr->operands.integer.slot_two); + r3 = OK; } else { r1 = this->read_guard>( s1, this->curr_instr->operands.vector.slot_one); -- cgit v1.2.3