summaryrefslogtreecommitdiff
path: root/aisa/eval.h
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-06-25 18:56:44 -0700
committerJulian Blake Kongslie2022-06-25 18:56:44 -0700
commit968414044e87be7399f73a01b718b4894bb65e01 (patch)
treeb4ce807d1645d68589028213d9b08d0b496c1b85 /aisa/eval.h
parentTesting some actual support for destinations and custom steps. (diff)
downloadissim-968414044e87be7399f73a01b718b4894bb65e01.tar.xz
Move EvalState and the eval coroutines to a separate header.
Diffstat (limited to 'aisa/eval.h')
-rw-r--r--aisa/eval.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/aisa/eval.h b/aisa/eval.h
new file mode 100644
index 0000000..f97740c
--- /dev/null
+++ b/aisa/eval.h
@@ -0,0 +1,45 @@
1#pragma once
2
3#include "aisa/aisa.h"
4
5namespace aisa {
6
7 template<typename CRTP> struct EvalState {
8 CRTP & crtp() noexcept { return static_cast<CRTP &>(*this); }
9
10 task<regval_t> async_load_reg(regnum_t rn)
11 {
12 while (true) {
13 if (auto rv = crtp().load_reg(rn); rv.has_value())
14 co_return *rv;
15 co_await suspend();
16 }
17 }
18
19 task<void> async_store_reg(regnum_t rn, regval_t rv)
20 {
21 while (true) {
22 if (crtp().store_reg(rn, rv))
23 co_return;
24 co_await suspend();
25 }
26 }
27
28 task<void> eval(const Step &step)
29 {
30 if (step.predicate.has_value()) {
31 regval_t pval = co_await async_load_reg(step.predicate->first);
32 if (pval != step.predicate->second)
33 co_return;
34 }
35 std::vector<regval_t> source_vals;
36 source_vals.reserve(step.source_regs.size());
37 for (unsigned int i = 0; i < step.source_regs.size(); ++i)
38 source_vals.emplace_back(co_await async_load_reg(step.source_regs[i]));
39 auto destination_vals = step.compute_destinations(source_vals);
40 for (unsigned int i = 0; i < step.destination_regs.size(); ++i)
41 co_await async_store_reg(step.destination_regs[i], destination_vals[i]);
42 }
43 };
44
45}