summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-04-17 17:20:48 -0400
committerbd <bdunahu@operationnull.com>2025-04-17 17:20:48 -0400
commitc7c531ce16fe66bf9f3bcb04ea9294d50a41e348 (patch)
tree4bc2b191f65352d951741d1deffa88492371609b /src
parentf6f2f32b6dbd1b1e60052cb67f40864c3b5bd74b (diff)
HALT instruction... but it voids future stages' instructions
Diffstat (limited to 'src')
-rw-r--r--src/sim/controller.cc7
-rw-r--r--src/sim/ex.cc16
2 files changed, 20 insertions, 3 deletions
diff --git a/src/sim/controller.cc b/src/sim/controller.cc
index 9256151..9ae6d16 100644
--- a/src/sim/controller.cc
+++ b/src/sim/controller.cc
@@ -1,4 +1,5 @@
#include "controller.h"
+#include "ex.h"
#include "response.h"
#include "storage.h"
@@ -20,7 +21,11 @@ void Controller::run_for(int number)
{
int i;
for (i = 0; i < number; ++i) {
- this->advance(WAIT);
+ try {
+ this->advance(WAIT);
+ } catch (HaltException &e) {
+ break;
+ }
}
}
diff --git a/src/sim/ex.cc b/src/sim/ex.cc
index a32105f..762e847 100644
--- a/src/sim/ex.cc
+++ b/src/sim/ex.cc
@@ -49,15 +49,15 @@ EX::EX(Stage *stage) : Stage(stage)
INIT_INSTRUCTION(
QUOT,
{
- s1 = s1 / s2;
+ this->handle_divide(s1, s2, false);
(void)pc;
(void)s3;
- (void)this;
}),
INIT_INSTRUCTION(
REM,
{
+ this->handle_divide(s1, s2, true);
s1 = s1 % s2;
(void)pc;
(void)s3;
@@ -385,3 +385,15 @@ void EX::advance_helper()
this->curr_instr->set_s1(s1);
this->status = OK;
}
+
+void EX::handle_divide(signed int &s1, signed int s2, bool is_mod)
+{
+ if (s2 == 0) {
+ // handle everything here
+ this->curr_instr->set_s1(MAX_INT);
+ this->status = OK;
+ throw HaltException();
+ } else {
+ s1 = (is_mod) ? s1 / s2 : s1 % s2;
+ }
+}