diff options
Diffstat (limited to 'main.cpp')
| -rw-r--r-- | main.cpp | 135 |
1 files changed, 79 insertions, 56 deletions
| @@ -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 | |||
| 14 | const bool show_mem_fetch = false; | ||
| 15 | const bool show_mem_store = true; | ||
| 16 | const bool show_regs = false; | ||
| 17 | const bool show_steps = true; | ||
| 18 | const bool show_tasks = false; | ||
| 14 | 19 | ||
| 15 | int main(int argc, const char *argv[]) | 20 | int 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>> ®s) | 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 | } |
