summaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--main.cpp135
1 files changed, 79 insertions, 56 deletions
diff --git a/main.cpp b/main.cpp
index e88d740..f172226 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,89 +1,112 @@
1#include <initializer_list> 1#include <fmt/core.h>
2#include <iostream> 2#include <iostream>
3#include <map>
4#include <memory> 3#include <memory>
5#include <optional> 4#include <optional>
6#include <string> 5#include <string>
7#include <type_traits>
8#include <utility> 6#include <utility>
9#include <vector>
10 7
11#include "aisa/aisa.h" 8#include "aisa/aisa.h"
12#include "aisa/eval.h" 9#include "aisa/async.h"
10#include "aisa/simple-models.h"
13#include "git-tag.h" 11#include "git-tag.h"
12#include "isa/fib/fib.h"
13
14const bool show_mem_fetch = false;
15const bool show_mem_store = true;
16const bool show_regs = false;
17const bool show_steps = true;
18const bool show_tasks = false;
14 19
15int main(int argc, const char *argv[]) 20int main(int argc, const char *argv[])
16{ 21{
17 std::cout << "Version " << GIT_TAG << "\n"; 22 std::cout << "Version " << GIT_TAG << "\n";
18 23
19 struct CopyStep : public aisa::Step { 24 isa::fib::Fib<2> fib;
20 CopyStep(std::pair<aisa::regnum_t, aisa::regval_t> pred, const std::initializer_list<std::pair<aisa::regnum_t, aisa::regnum_t>> &regs) 25
26 struct Eval : public aisa::AsyncEval<Eval>, aisa::PagedMem<>, aisa::TaskStack, aisa::VectorRF {
27 bool fetch_mem(aisa::byte_t *bytes, aisa::addr_t addr, aisa::addr_t size)
21 { 28 {
22 predicate = std::move(pred); 29 if (aisa::PagedMem<>::fetch_mem(bytes, addr, size)) {
23 source_regs.reserve(regs.size()); 30 if (show_mem_fetch) {
24 destination_regs.reserve(regs.size()); 31 fmt::print("\t\t\t");
25 for (const auto &rp : regs) { 32 for (; size; --size)
26 source_regs.emplace_back(rp.first); 33 fmt::print("{:02x} ", *bytes++);
27 destination_regs.emplace_back(rp.second); 34 fmt::print("= [{:x}]\n", addr);
35 }
36 return true;
28 } 37 }
38 return false;
29 } 39 }
30 40 bool store_mem(aisa::addr_t addr, const aisa::byte_t *bytes, aisa::addr_t size)
31 std::vector<aisa::regval_t> compute_destinations(const std::vector<aisa::regval_t> &source_vals) const override
32 { 41 {
33 return source_vals; 42 if (aisa::PagedMem<>::store_mem(addr, bytes, size)) {
43 if (show_mem_store) {
44 fmt::print("\t\t\t[{:x}] =", addr);
45 for (; size; --size)
46 fmt::print(" {:02x}", *bytes++);
47 fmt::print("\n");
48 }
49 return true;
50 }
51 return false;
34 } 52 }
35 } step{{123, 456}, {{1, 2}, {3, 4}, {5, 6}}};
36 53
37 struct State : public aisa::EvalState<State> { 54 bool store_reg(aisa::regnum_t rn, aisa::regval_t rv)
38 std::map<aisa::regnum_t, aisa::regval_t> regs; 55 {
56 if (aisa::VectorRF::store_reg(rn, rv)) {
57 if (show_regs)
58 fmt::print(".{} = {}\n", isa::fib::Reg::disasm(rn), rv);
59 return true;
60 }
61 return false;
62 }
39 63
40 std::optional<aisa::regval_t> load_reg(aisa::regnum_t rn) 64 bool push_task(std::unique_ptr<const aisa::Task> &&task)
41 { 65 {
42 std::cout << "state.load_reg(" << rn << ") = "; 66 auto d = task->disasm();
43 if (auto x = regs.find(rn); x != regs.end()) { 67 if (aisa::TaskStack::push_task(std::move(task))) {
44 std::cout << x->second << "\n"; 68 if (show_tasks)
45 return x->second; 69 fmt::print("\t\t*** ENTER {} ***\n", d);
70 return true;
46 } 71 }
47 std::cout << "(not available)\n"; 72 return false;
48 return {};
49 } 73 }
50 74
51 bool store_reg(aisa::regnum_t rn, aisa::regval_t rv) 75 bool pop_task()
52 { 76 {
53 std::cout << "state.store_reg(" << rn << " <- " << rv << ")\n"; 77 if (aisa::TaskStack::pop_task()) {
54 regs[rn] = rv; 78 if (show_tasks)
55 return true; 79 fmt::print("\t\t *** LEAVE ***\n");
80 return true;
81 }
82 return false;
56 } 83 }
57 } state; 84 } eval;
58 85
59 auto t = state.async_load_reg(999); 86 if (!eval.async_setup_initial_task(fib)()) {
60 std::cout << "run\n"; t(); 87 fmt::print("Failed to complete initial setup.\n");
61 std::cout << "run\n"; t(); 88 return 1;
62 std::cout << "run\n"; t();
63 std::cout << "set regs[999] = 54321\n"; state.store_reg(999, 54321);
64 std::optional<aisa::regval_t> result;
65 while (!result.has_value()) {
66 std::cout << "run\n";
67 result = t();
68 } 89 }
69 std::cout << "result = " << *result << "\n";
70 90
71 std::cout << "\n\n\n"; 91 while (true) {
92 auto res = eval.async_fetch_and_run_step()();
93 if (res.has_value()) {
94 auto &es = *res;
95 if (es.first) {
96 auto &step = *es.first;
97 auto &w = es.second;
98 if (show_steps)
99 fmt::print("\t{}\n", step.disasm(&w));
100 } else {
101 break;
102 }
103 } else {
104 fmt::print("Failed to complete step.\n");
105 return 2;
106 }
107 }
72 108
73 auto w = state(step); 109 fmt::print("Functional model exited.\n");
74 std::cout << "run\n"; w->resume();
75 std::cout << "run\n"; w->resume();
76 std::cout << "run\n"; w->resume();
77 std::cout << "set predicate (valid)\n"; state.store_reg(step.predicate->first, step.predicate->second);
78 std::cout << "run\n"; w->resume();
79 std::cout << "run\n"; w->resume();
80 std::cout << "run\n"; w->resume();
81 std::cout << "set regs (all)\n";
82 for (int i = 0; i < 10; ++i)
83 state.store_reg(i, 1000 + i);
84 for (bool done = false; !done; done = w->resume())
85 std::cout << "run\n";
86 std::cout << "huzzah!\n";
87 110
88 return 0; 111 return 0;
89} 112}