diff options
author | Karel Kočí <cynerd@email.cz> | 2018-01-01 20:43:42 +0100 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2018-01-01 20:47:36 +0100 |
commit | 128ce1ee2115b54d43db1334e12410b1cc216f10 (patch) | |
tree | 10593231884a85966f38ac1fff9d139ae75e1bbb /qtmips_cli/main.cpp | |
parent | 92b6d05aed7cbfa7ddb0c5dcc61318c69c03bc97 (diff) | |
download | qtmips-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.cpp | 83 |
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(); } |