summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/controller.cc1
-rw-r--r--src/sim/ex.cc8
-rw-r--r--src/sim/id.cc36
-rw-r--r--src/sim/mm.cc11
-rw-r--r--src/sim/wb.cc7
5 files changed, 55 insertions, 8 deletions
diff --git a/src/sim/controller.cc b/src/sim/controller.cc
index 65e5676..9256151 100644
--- a/src/sim/controller.cc
+++ b/src/sim/controller.cc
@@ -11,6 +11,7 @@ Controller::Controller(Stage *stage, Storage *storage, bool is_pipelined)
this->pc = 0x0;
this->checked_out = {};
this->gprs = {0};
+ this->gprs.at(2) = MEM_WORDS; // set the stack pointer
// grant side-door access
this->id = SIDE;
}
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index d20d15f..c676781 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -340,20 +340,20 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
PUSH,
{
+ std::cout << "adding " << s1 << " and " << s3;
+ s1 = s1 + s3;
+ std::cout << " for " << s1 << std::endl;
(void)pc;
- (void)s3;
(void)s2;
- (void)s1;
(void)this;
}),
INIT_INSTRUCTION(
POP,
{
+ s1 = s1 + s3;
(void)pc;
- (void)s3;
(void)s2;
- (void)s1;
(void)this;
}),
diff --git a/src/sim/id.cc b/src/sim/id.cc
index 37c6773..de412d4 100644
--- a/src/sim/id.cc
+++ b/src/sim/id.cc
@@ -86,7 +86,7 @@ void ID::get_instr_fields(
break;
case 0b10:
t = J;
- this->decode_J_type(s1, s2, s3);
+ this->decode_J_type(s1, s2, s3, m);
break;
case 0b11:
t = INV;
@@ -159,8 +159,10 @@ void ID::decode_I_type(
this->status = r1;
}
-void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
+void ID::decode_J_type(
+ signed int &s1, signed int &s2, signed int &s3, Mnemonic &m)
{
+ Response r1, r2;
unsigned int s0b, s1b;
s0b = REG_SIZE;
@@ -169,7 +171,35 @@ void ID::decode_J_type(signed int &s1, signed int &s2, signed int &s3)
s2 = GET_BITS_SIGN_EXTEND(s1, s0b, s1b);
s1 = GET_LS_BITS(s1, s0b);
- this->status = this->read_guard(*&s1);
+ switch (m) {
+ case PUSH:
+ s2 = s1; // source
+ s3 = 2; // stack pointer
+ s1 = -1; // increment amount
+ r1 = this->read_guard(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->status = (r1 == OK && r2 == OK) ? OK : STALLED;
+ break;
+ case POP:
+ s2 = s1; // destination
+ s3 = 2; // stack pointer
+ s1 = 1; // increment amount
+ r1 = (this->is_checked_out(s3)) ? STALLED : OK; // we read the stack pointer
+ if (r1 == OK) {
+ this->write_guard(s2);
+ this->write_guard(s3); // we write the stack pointer
+ }
+ this->status = r1;
+ break;
+ default:
+ this->status = this->read_guard(*&s1);
+ }
+
+ std::cout << m << ":" << this->status << std::endl;
+
}
std::vector<int> ID::stage_info()
diff --git a/src/sim/mm.cc b/src/sim/mm.cc
index a9a60c2..a02ca83 100644
--- a/src/sim/mm.cc
+++ b/src/sim/mm.cc
@@ -21,8 +21,8 @@ void MM::advance_helper()
this->status = STALLED;
break;
+ case PUSH:
case STORE:
- // TODO signed issues, we aren't wrapping addresses
i = this->storage->write_word(
this, this->curr_instr->get_s2(), this->curr_instr->get_s1());
this->status = i ? OK : STALLED;
@@ -31,6 +31,15 @@ void MM::advance_helper()
}
break;
+ case POP:
+ i = this->storage->read_word(this, this->curr_instr->get_s3(), data);
+ this->status = i ? OK : STALLED;
+ if (this->status == OK) {
+ this->curr_instr->set_s3(data);
+ } else
+ this->status = STALLED;
+ break;
+
default:
this->status = OK;
}
diff --git a/src/sim/wb.cc b/src/sim/wb.cc
index 4e6b2b0..08e5ed3 100644
--- a/src/sim/wb.cc
+++ b/src/sim/wb.cc
@@ -31,6 +31,13 @@ void WB::write_handler()
this->checked_out.pop_front();
reg = this->curr_instr->get_checked_out();
this->store_register(reg, this->curr_instr->get_s1());
+
+ if (this->curr_instr->get_mnemonic() == POP) {
+ // POP performs a second register write
+ reg = this->checked_out.front();
+ this->checked_out.pop_front();
+ this->store_register(reg, this->curr_instr->get_s3());
+ }
}
void WB::jump_handler()