summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aisa/aisa.h44
-rw-r--r--main.cpp63
2 files changed, 64 insertions, 43 deletions
diff --git a/aisa/aisa.h b/aisa/aisa.h
index 8cb302e..123b12a 100644
--- a/aisa/aisa.h
+++ b/aisa/aisa.h
@@ -2,6 +2,7 @@
2 2
3#include <coroutine> 3#include <coroutine>
4#include <cstdint> 4#include <cstdint>
5#include <initializer_list>
5#include <iostream> 6#include <iostream>
6#include <optional> 7#include <optional>
7#include <utility> 8#include <utility>
@@ -16,6 +17,7 @@ namespace aisa {
16 17
17 template<typename CRTP> struct EvalState { 18 template<typename CRTP> struct EvalState {
18 CRTP & crtp() noexcept { return static_cast<CRTP &>(*this); } 19 CRTP & crtp() noexcept { return static_cast<CRTP &>(*this); }
20
19 task<regval_t> async_load_reg(regnum_t rn) 21 task<regval_t> async_load_reg(regnum_t rn)
20 { 22 {
21 while (true) { 23 while (true) {
@@ -24,12 +26,21 @@ namespace aisa {
24 co_await suspend(); 26 co_await suspend();
25 } 27 }
26 } 28 }
29
30 task<void> async_store_reg(regnum_t rn, regval_t rv)
31 {
32 while (true) {
33 if (crtp().store_reg(rn, rv))
34 co_return;
35 co_await suspend();
36 }
37 }
27 }; 38 };
28 39
29 struct Step { 40 struct Step {
30 const std::optional<std::pair<regnum_t, regval_t>> predicate; 41 std::optional<std::pair<regnum_t, regval_t>> predicate;
31 const std::vector<regnum_t> source_regs; 42 std::vector<regnum_t> source_regs;
32 const std::vector<regnum_t> destination_regs; 43 std::vector<regnum_t> destination_regs;
33 44
34 std::optional<regnum_t> predicate_reg() const 45 std::optional<regnum_t> predicate_reg() const
35 { 46 {
@@ -45,33 +56,22 @@ namespace aisa {
45 return {}; 56 return {};
46 } 57 }
47 58
48 template<typename State> task<void> evaluate(State &state) const 59 virtual std::vector<regval_t> compute_destinations(const std::vector<regval_t> &source_vals) const = 0;
60
61 template<typename State> task<void> eval(State &state) const
49 { 62 {
50 if (predicate.has_value()) { 63 if (predicate.has_value()) {
51 std::cout << "checking predicate...\n";
52 std::cout << "\texpect " << predicate->second << "\n";
53 regval_t pval = co_await state.async_load_reg(predicate->first); 64 regval_t pval = co_await state.async_load_reg(predicate->first);
54 std::cout << "\tgot " << pval << "\n"; 65 if (pval != predicate->second)
55 if (pval != predicate->second) {
56 std::cout << "\tpredicate skipped\n";
57 co_return; 66 co_return;
58 } else {
59 std::cout << "\tpredicate not skipped\n";
60 }
61 } 67 }
62 std::cout << "reading sources...\n";
63 std::vector<regval_t> source_vals; 68 std::vector<regval_t> source_vals;
64 source_vals.reserve(source_regs.size()); 69 source_vals.reserve(source_regs.size());
65 for (unsigned int i = 0; i < source_regs.size(); ++i) {
66 std::cout << "\tgetting source " << i << "...\n";
67 source_vals.emplace_back(co_await state.async_load_reg(source_regs[i]));
68 std::cout << "\t\tgot " << source_vals.back() << "\n";
69 }
70 std::cout << "sources:";
71 for (unsigned int i = 0; i < source_regs.size(); ++i) 70 for (unsigned int i = 0; i < source_regs.size(); ++i)
72 std::cout << " " << source_regs[i] << "=" << source_vals[i]; 71 source_vals.emplace_back(co_await state.async_load_reg(source_regs[i]));
73 std::cout << "\n"; 72 auto destination_vals = compute_destinations(source_vals);
74 std::cout << "done with evaluate\n"; 73 for (unsigned int i = 0; i < destination_regs.size(); ++i)
74 co_await state.async_store_reg(destination_regs[i], destination_vals[i]);
75 } 75 }
76 }; 76 };
77 77
diff --git a/main.cpp b/main.cpp
index 0240bb5..25bd99b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -9,11 +9,23 @@ int main(int argc, const char *argv[])
9{ 9{
10 std::cout << "Version " << GIT_TAG << "\n"; 10 std::cout << "Version " << GIT_TAG << "\n";
11 11
12 aisa::Step step; 12 struct CopyStep : public aisa::Step {
13 const_cast<std::optional<std::pair<aisa::regnum_t, aisa::regval_t>> &>(step.predicate) = std::optional(std::make_pair(123, 456)); 13 CopyStep(std::pair<aisa::regnum_t, aisa::regval_t> pred, const std::initializer_list<std::pair<aisa::regnum_t, aisa::regnum_t>> &regs)
14 const_cast<std::vector<aisa::regnum_t> &>(step.source_regs).emplace_back(12); 14 {
15 const_cast<std::vector<aisa::regnum_t> &>(step.source_regs).emplace_back(34); 15 predicate = std::move(pred);
16 const_cast<std::vector<aisa::regnum_t> &>(step.source_regs).emplace_back(56); 16 source_regs.reserve(regs.size());
17 destination_regs.reserve(regs.size());
18 for (const auto &rp : regs) {
19 source_regs.emplace_back(rp.first);
20 destination_regs.emplace_back(rp.second);
21 }
22 }
23
24 std::vector<aisa::regval_t> compute_destinations(const std::vector<aisa::regval_t> &source_vals) const override
25 {
26 return source_vals;
27 }
28 } step{{123, 456}, {{1, 2}, {3, 4}, {5, 6}}};
17 29
18 struct State : public aisa::EvalState<State> { 30 struct State : public aisa::EvalState<State> {
19 std::map<aisa::regnum_t, aisa::regval_t> regs; 31 std::map<aisa::regnum_t, aisa::regval_t> regs;
@@ -28,33 +40,42 @@ int main(int argc, const char *argv[])
28 std::cout << "(not available)\n"; 40 std::cout << "(not available)\n";
29 return {}; 41 return {};
30 } 42 }
43
44 bool store_reg(aisa::regnum_t rn, aisa::regval_t rv)
45 {
46 std::cout << "state.store_reg(" << rn << " <- " << rv << ")\n";
47 regs[rn] = rv;
48 return true;
49 }
31 } state; 50 } state;
32 51
33 auto t = state.async_load_reg(999); 52 auto t = state.async_load_reg(999);
34 t(); 53 std::cout << "run\n"; t();
35 t(); 54 std::cout << "run\n"; t();
36 t(); 55 std::cout << "run\n"; t();
37 std::cout << "set regs[999] = 54321\n"; state.regs[999] = 54321; 56 std::cout << "set regs[999] = 54321\n"; state.store_reg(999, 54321);
38 std::optional<aisa::regval_t> result; 57 std::optional<aisa::regval_t> result;
39 while (!result.has_value()) 58 while (!result.has_value()) {
59 std::cout << "run\n";
40 result = t(); 60 result = t();
61 }
41 std::cout << "result = " << *result << "\n"; 62 std::cout << "result = " << *result << "\n";
42 63
43 std::cout << "\n\n\n"; 64 std::cout << "\n\n\n";
44 65
45 auto w = step.evaluate(state); 66 auto w = step.eval(state);
46 w(); 67 std::cout << "run\n"; w();
47 w(); 68 std::cout << "run\n"; w();
48 w(); 69 std::cout << "run\n"; w();
49 std::cout << "set predicate (valid)\n"; state.regs[step.predicate->first] = step.predicate->second; 70 std::cout << "set predicate (valid)\n"; state.store_reg(step.predicate->first, step.predicate->second);
50 w(); 71 std::cout << "run\n"; w();
51 w(); 72 std::cout << "run\n"; w();
52 w(); 73 std::cout << "run\n"; w();
53 std::cout << "set regs (all)\n"; 74 std::cout << "set regs (all)\n";
54 for (int i = 10; i < 100; ++i) 75 for (int i = 0; i < 10; ++i)
55 state.regs[i] = 1000 + i; 76 state.store_reg(i, 1000 + i);
56 for (bool done = false; !done; done = w()) 77 for (bool done = false; !done; done = w())
57 ; 78 std::cout << "run\n";
58 std::cout << "huzzah!\n"; 79 std::cout << "huzzah!\n";
59 80
60 return 0; 81 return 0;