aboutsummaryrefslogtreecommitdiff
path: root/qtmips_cli/main.cpp
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-01-01 20:43:42 +0100
committerKarel Kočí <cynerd@email.cz>2018-01-01 20:47:36 +0100
commit128ce1ee2115b54d43db1334e12410b1cc216f10 (patch)
tree10593231884a85966f38ac1fff9d139ae75e1bbb /qtmips_cli/main.cpp
parent92b6d05aed7cbfa7ddb0c5dcc61318c69c03bc97 (diff)
downloadqtmips-128ce1ee2115b54d43db1334e12410b1cc216f10.tar.gz
qtmips-128ce1ee2115b54d43db1334e12410b1cc216f10.tar.bz2
qtmips-128ce1ee2115b54d43db1334e12410b1cc216f10.zip
cli: extend tracer and implement reporter
Diffstat (limited to 'qtmips_cli/main.cpp')
-rw-r--r--qtmips_cli/main.cpp83
1 files changed, 79 insertions, 4 deletions
diff --git a/qtmips_cli/main.cpp b/qtmips_cli/main.cpp
index 4c4652b..2260ea5 100644
--- a/qtmips_cli/main.cpp
+++ b/qtmips_cli/main.cpp
@@ -1,9 +1,12 @@
#include <QCoreApplication>
#include <QCommandLineParser>
+#include <cctype>
#include <iostream>
#include "tracer.h"
+#include "reporter.h"
using namespace machine;
+using namespace std;
void create_parser(QCommandLineParser &p) {
p.setApplicationDescription("QtMips CLI machine simulator");
@@ -11,6 +14,17 @@ void create_parser(QCommandLineParser &p) {
p.addVersionOption();
p.addPositionalArgument("FILE", "Input ELF executable file");
+
+ p.addOptions({
+ {{"trace-fetch", "tr-fetch"}, "Trace fetched instruction."},
+ {{"trace-pc", "tr-pc"}, "Print program counter register changes."},
+ {{"trace-gp", "tr-gp"}, "Print general purpose register changes. You can use * for all registers.", "REG"},
+ {{"trace-lo", "tr-lo"}, "Print LO register changes."},
+ {{"trace-hi", "tr-hi"}, "Print HI register changes."},
+ {{"dump-registers", "d-regs"}, "Dump registers state at program exit."},
+ {"expect-fail", "Expect that program causes CPU trap and fail if it doesn't."},
+ {"fail-match", "Program should exit with exactly this CPU TRAP. Possible values are I(unsupported Instruction), A(Unsupported ALU operation), O(Overflow/underflow) and J(Unaligned Jump). You can freely combine them. Using this implies expect-fail option.", "TRAP"},
+ });
}
void configure_machine(QCommandLineParser &p, MachineConfig &cc) {
@@ -25,8 +39,68 @@ void configure_machine(QCommandLineParser &p, MachineConfig &cc) {
}
void configure_tracer(QCommandLineParser &p, Tracer &tr) {
+ // TODO trace fetched instruction
+
+ if (p.isSet("trace-pc"))
+ tr.reg_pc();
+
+ QStringList gps = p.values("trace-gp");
+ for (int i = 0; i < gps.size(); i++) {
+ if (gps[i] == "*") {
+ for (int y = 0; y < 32; y++)
+ tr.reg_gp(y);
+ } else {
+ bool res;
+ int num = gps[i].toInt(&res);
+ if (res && num <= 32) {
+ tr.reg_gp(num);
+ } else {
+ cout << "Unknown register number given for trace-gp: " << gps[i].toStdString() << endl;
+ exit(1);
+ }
+ }
+ }
+
+ if (p.isSet("trace-lo"))
+ tr.reg_lo();
+ if (p.isSet("trace-hi"))
+ tr.reg_hi();
+
+ // TODO
+}
+
+void configure_reporter(QCommandLineParser &p, Reporter &r) {
+ if (p.isSet("dump-registers"))
+ r.regs();
+
+ QStringList fail = p.values("fail-match");
+ for (int i = 0; i < fail.size(); i++) {
+ for (int y = 0; y < fail[i].length(); y++) {
+ enum Reporter::FailReason reason;
+ switch (tolower(fail[i].toStdString()[y])) {
+ case 'i':
+ reason = Reporter::FR_I;
+ break;
+ case 'a':
+ reason = Reporter::FR_A;
+ break;
+ case 'o':
+ reason = Reporter::FR_O;
+ break;
+ case 'j':
+ reason = Reporter::FR_J;
+ break;
+ default:
+ cout << "Unknown fail condition: " << fail[i].toStdString()[y] << endl;
+ exit(1);
+ }
+ r.expect_fail(reason);
+ }
+ }
+ if (p.isSet("expect-fail") && !p.isSet("fail-match"))
+ r.expect_fail(Reporter::FailAny);
+
// TODO
- tr.reg_pc();
}
int main(int argc, char *argv[]) {
@@ -42,11 +116,12 @@ int main(int argc, char *argv[]) {
configure_machine(p, cc);
QtMipsMachine machine(cc);
- app.connect(&machine, SIGNAL(program_exit()), &app, SLOT(quit()));
-
Tracer tr(&machine);
configure_tracer(p, tr);
- machine.play(); // Run machine
+ Reporter r(&app, &machine);
+ configure_reporter(p, r);
+
+ machine.play();
return app.exec();
}