summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-16 23:35:59 -0400
committerbd <bdunahu@operationnull.com>2025-04-16 23:35:59 -0400
commit796b2691146a3a4eaace4fa155d3c0c2f7379832 (patch)
tree8dd83f646bd9ef29ff3c3c492e4f64485d44c1b7
parent23d3ebb2702e6b08c7f6b997067e1bc76483b813 (diff)
Fix a bug related to parsing immediates in decode
-rw-r--r--inc/pipe_spec.h17
-rw-r--r--src/sim/id.cc13
-rw-r--r--tests/controller.cc2
-rw-r--r--tests/id.cc2
4 files changed, 26 insertions, 8 deletions
diff --git a/inc/pipe_spec.h b/inc/pipe_spec.h
index 772314e..d211b72 100644
--- a/inc/pipe_spec.h
+++ b/inc/pipe_spec.h
@@ -65,4 +65,21 @@
*/
#define GET_MID_BITS(k, m, n) GET_LS_BITS((k) >> (m), ((n) - (m)))
+/**
+ * Return the bits from integer K starting at N and ending at M using a bit
+ * mask, but sign-extends the result. This is required to parse immediates.
+ * @param the integer to be parsed
+ * @param the index of the starting bit to be parsed
+ * @param the index of the ending bit to be parsed
+ * @return a section of bits from K
+ */
+// clang-format off
+#define GET_BITS_SIGN_EXTEND(k, m, n) \
+ ({\
+ int _f = GET_MID_BITS(k, m, n); \
+ int _w = (n) - (m) - (1); \
+ _f = (_f & (1 << (_w - 1))) ? (_f | (-1 << _w)) : _f; \
+ })
+// clang-format on
+
#endif /* DEFINITIONS_H_INCLUDED */
diff --git a/src/sim/id.cc b/src/sim/id.cc
index 46694ad..d4b56d2 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -116,8 +116,8 @@ void ID::decode_I_type(
s0b = REG_SIZE;
s1b = s0b + REG_SIZE;
- s2b = WORD_SPEC;
- s3 = GET_MID_BITS(s1, s1b, s2b);
+ s2b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE;
+ s3 = GET_BITS_SIGN_EXTEND(s1, s1b, s2b);
s2 = GET_MID_BITS(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
@@ -135,19 +135,20 @@ void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
unsigned int s0b, s1b;
s0b = REG_SIZE;
- s1b = WORD_SPEC;
+ s1b = WORD_SPEC - LINE_SPEC - OPCODE_SIZE;
s3 = 0;
- s2 = GET_MID_BITS(s1, s0b, s1b);
+ s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
+ std::cout << "s1: " << s1 << ", s2: " << s2 << ", s3: " << s3 << std::endl;
this->status = this->read_guard(*&s1);
}
-std::vector<int> ID::stage_info() {
+std::vector<int> ID::stage_info() {
std::vector<int> info;
if(this->curr_instr){
info.push_back(this->curr_instr->get_pc());
info.push_back(this->curr_instr->get_instr_bits());
- }
+ }
return info;
}
diff --git a/tests/controller.cc b/tests/controller.cc
index 74284b7..6920933 100644
--- a/tests/controller.cc
+++ b/tests/controller.cc
@@ -311,7 +311,7 @@ TEST_CASE_METHOD(ControllerPipeFixture, "two num adder", "[full pipe]")
CHECK(i->get_time_of(MEM) == 28);
CHECK(i->get_time_of(WRITE) == 29);
CHECK(i->get_s1() == 0x8);
- CHECK(i->get_s2() == 0b111111111111111111001);
+ CHECK(i->get_s2() == 0xfffffff9);
CHECK(this->ct->get_gprs().at(2) == 0x200);
CHECK(this->ct->get_gprs().at(5) == 0x0);
CHECK(this->ct->get_gprs().at(6) == 0x1);
diff --git a/tests/id.cc b/tests/id.cc
index b8d0479..5af15fc 100644
--- a/tests/id.cc
+++ b/tests/id.cc
@@ -185,7 +185,7 @@ TEST_CASE_METHOD(IDFixture, "Parse arbitrary j-type # two", "[id]")
i = this->decode_bits(t);
CHECK(i->get_s1() == 0x00000000); // registers are empty
- CHECK(i->get_s2() == 0xBBCCF);
+ CHECK(i->get_s2() == 0xFFFBBCCF);
CHECK(i->get_mnemonic() == JAL);
delete i;