summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui/worker.cc4
-rw-r--r--inc/ex.h19
-rw-r--r--src/sim/controller.cc7
-rw-r--r--src/sim/ex.cc16
4 files changed, 41 insertions, 5 deletions
diff --git a/gui/worker.cc b/gui/worker.cc
index 08503c9..defec46 100644
--- a/gui/worker.cc
+++ b/gui/worker.cc
@@ -33,6 +33,8 @@ void Worker::doWork()
p.push_back(0b00000000000000000000000110100110);
p.push_back(0b00000000000000000000000111100110);
p.push_back(0b00000000000000000000001000100110);
+ p.push_back(0b00000000000000000000000000101110);
+ p.push_back(0b00000000000000000000000000101110);
p.push_back(0b00000000000000000000000000010000);
// p.push_back(0b00000000000000000010100010001101);
@@ -118,7 +120,7 @@ void Worker::runSteps(int steps)
void Worker::runStep()
{
qDebug() << "Running for 1 step ";
- this->ct->advance(WAIT);
+ this->ct->run_for(1);
emit dram_storage(this->d->view(0, 256));
emit cache_storage(this->c->view(24, 8));
emit register_storage(this->ct->get_gprs());
diff --git a/inc/ex.h b/inc/ex.h
index e4c9d2b..f63539c 100644
--- a/inc/ex.h
+++ b/inc/ex.h
@@ -3,8 +3,16 @@
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
+#include <exception>
#include <unordered_map>
+class HaltException : public std::exception
+{
+ const char *what() const noexcept override {
+ return "";
+ }
+};
+
class EX : public Stage
{
public:
@@ -19,13 +27,22 @@ class EX : public Stage
private:
void advance_helper();
/**
+ * Wrapper for division functions, which detects HALT instructinos (division
+ * by 0).
+ * @param the numerator
+ * @param the denominator
+ * @param if the modulo operator should instead be used
+ */
+ void handle_divide(signed int &s1, signed int s2, bool is_mod);
+ /**
* Maps each mnemonic to a function which carries out the instruction's base
* logic.
* All instructions store the result into s1.
*/
std::unordered_map<
Mnemonic,
- std::function<void(signed int &s1, signed int s2, signed int s3, unsigned int pc)>>
+ std::function<void(
+ signed int &s1, signed int s2, signed int s3, unsigned int pc)>>
instr_map;
};
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;
+ }
+}