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
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <fmt/core.h>
#include <iostream>
#include <memory>
#include <optional>
#include <utility>
#include "aisa/aisa.h"
#include "aisa/async.h"
#include "aisa/simple-models.h"
#include "fib/fib.h"
#include "git-tag.h"
const bool show_mem_fetch = false;
const bool show_mem_store = true;
const bool show_regs = false;
const bool show_steps = true;
const bool show_tasks = false;
int main(int argc, const char *argv[])
{
std::cout << "Version " << GIT_TAG << "\n";
fib::Fib<3> fib;
struct Eval : public aisa::AsyncEval<Eval>, aisa::PagedMem<>, aisa::TaskStack, aisa::VectorRF {
bool fetch_mem(aisa::byte_t *bytes, aisa::addr_t addr, aisa::addr_t size)
{
if (aisa::PagedMem<>::fetch_mem(bytes, addr, size)) {
if (show_mem_fetch) {
fmt::print("\t\t\t");
for (; size; --size)
fmt::print("{:02x} ", *bytes++);
fmt::print("= [{:x}]\n", addr);
}
return true;
}
return false;
}
bool store_mem(aisa::addr_t addr, const aisa::byte_t *bytes, aisa::addr_t size)
{
if (aisa::PagedMem<>::store_mem(addr, bytes, size)) {
if (show_mem_store) {
fmt::print("\t\t\t[{:x}] =", addr);
for (; size; --size)
fmt::print(" {:02x}", *bytes++);
fmt::print("\n");
}
return true;
}
return false;
}
bool store_reg(aisa::regnum_t rn, aisa::regval_t rv)
{
if (aisa::VectorRF::store_reg(rn, rv)) {
if (show_regs)
fmt::print(".{} = {}\n", fib::Reg::disasm(rn), rv);
return true;
}
return false;
}
bool push_task(std::unique_ptr<const aisa::Task> &&task)
{
auto d = task->disasm();
if (aisa::TaskStack::push_task(std::move(task))) {
if (show_tasks)
fmt::print("\t\t*** ENTER {} ***\n", d);
return true;
}
return false;
}
bool pop_task()
{
if (aisa::TaskStack::pop_task()) {
if (show_tasks)
fmt::print("\t\t *** LEAVE ***\n");
return true;
}
return false;
}
} eval;
if (!eval.async_setup_initial_task(fib)()) {
fmt::print("Failed to complete initial setup.\n");
return 1;
}
while (true) {
auto res = eval.async_fetch_and_run_step()();
if (res.has_value()) {
auto &es = *res;
if (es.first) {
auto &step = *es.first;
auto &w = es.second;
if (show_steps)
fmt::print("\t{}\n", step.disasm(&w));
} else {
break;
}
} else {
fmt::print("Failed to complete step.\n");
return 2;
}
}
fmt::print("Functional model exited.\n");
return 0;
}
|