1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include <arpa/inet.h>
#include <cstdint>
#include <fmt/format.h>
#include <fstream>
#include <iostream>
#include <optional>
#include <utility>
#include "infra/sim.h"
#include "isa/checker.h"
#include "programs/programs.h"
#include "uarch/core.h"
int load_program(core &core, const std::uint8_t *program) {
bool seen_non_leader = false;
bool comment = false;
unsigned int field = 0;
unsigned int address = 0;
std::optional<std::pair<unsigned int, unsigned int>> data;
while (true) {
auto b1 = *program++;
if (comment) {
if (b1 == 0377)
comment = false;
} else {
if (b1 == 0377) {
comment = true;
} else if (b1 == 0200) {
if (seen_non_leader)
break;
} else if ((b1 & 0300) == 0100) {
seen_non_leader = true;
address = ((b1 & 0077) << 6) | *program++;
} else if ((b1 & 0300) == 0000) {
seen_non_leader = true;
if (data.has_value()) {
core.checker.mem.store(data->first, data->second);
core.mem.store(data->first, data->second);
}
auto a = field | address++;
auto d = ((b1 & 0077) << 6) | *program++;
data = std::make_pair(a, d);
} else if ((b1 & 0307) == 0300) {
seen_non_leader = true;
field = (b1 & 0070) << 3;
} else {
std::cerr << "Invalid program BIN\n";
return 2;
}
}
}
return 0;
}
int main(int argc, const char *argv[]) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " program [program ...]\n";
std::cerr << "Programs:\n";
for (const auto &p : programs)
std::cerr << "\t" << p.first << "\n";
return 1;
}
init_disasm_tables();
iomodel system;
core core(system);
for (--argc, ++argv; argc; --argc, ++argv) {
if (auto program = programs.find(*argv); program != programs.end()) {
if (auto err = load_program(core, program->second))
return err;
} else {
std::ifstream fh(*argv);
system.load_evt(fh);
}
}
std::ofstream pt("bug.pt");
infra::pt::ptfile = &pt;
for (unsigned int cycles = 0; !core.checker.done() && cycles < 500000; ++cycles) {
// if (!checker.ctlregs[HALTED]) {
// if (checker.inst.final_address.has_value())
// std::cout << fmt::format("{:05o} {:01o} {:04o} {:04o} {:005o}\n", checker.pc, checker.link, checker.acc, checker.mq, *checker.inst.final_address);
// else
// std::cout << fmt::format("{:05o} {:01o} {:04o} {:04o} \n", checker.pc, checker.link, checker.acc, checker.mq);
// }
infra::sim::advance();
}
pt << fmt::format("# icount={} cycles={} ipc={:.04}\n", core.checker.icount, infra::sim::now, (float)core.checker.icount / (float)infra::sim::now);
// std::ofstream fh("trace.evt");
// system.write_evt(fh);
return 0;
}
|