summaryrefslogtreecommitdiff
path: root/aisa/aisa.h
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-06-25 10:16:12 -0700
committerJulian Blake Kongslie2022-06-25 10:16:12 -0700
commitd80e0dbd20bb8597afe92f770e39d20440557d1f (patch)
tree3a2a89d3e8b0a7dd8f9a26f166825cef7c62795d /aisa/aisa.h
parentMove get-git-tag to a tools subdirectory. (diff)
downloadissim-d80e0dbd20bb8597afe92f770e39d20440557d1f.tar.xz
Demo for a coroutine-based step evaluator.
Diffstat (limited to '')
-rw-r--r--aisa/aisa.h73
1 files changed, 72 insertions, 1 deletions
diff --git a/aisa/aisa.h b/aisa/aisa.h
index b570d6b..8cb302e 100644
--- a/aisa/aisa.h
+++ b/aisa/aisa.h
@@ -1,7 +1,78 @@
1#pragma once 1#pragma once
2 2
3#include <coroutine>
4#include <cstdint>
5#include <iostream>
6#include <optional>
7#include <utility>
8#include <vector>
9
10#include "aisa/coroutine.h"
11
3namespace aisa { 12namespace aisa {
4 13
5 void do_something(); 14 using regnum_t = std::uint_fast64_t;
15 using regval_t = std::uint64_t;
16
17 template<typename CRTP> struct EvalState {
18 CRTP & crtp() noexcept { return static_cast<CRTP &>(*this); }
19 task<regval_t> async_load_reg(regnum_t rn)
20 {
21 while (true) {
22 if (auto rv = crtp().load_reg(rn); rv.has_value())
23 co_return *rv;
24 co_await suspend();
25 }
26 }
27 };
28
29 struct Step {
30 const std::optional<std::pair<regnum_t, regval_t>> predicate;
31 const std::vector<regnum_t> source_regs;
32 const std::vector<regnum_t> destination_regs;
33
34 std::optional<regnum_t> predicate_reg() const
35 {
36 if (predicate.has_value())
37 return predicate->first;
38 return {};
39 }
40
41 std::optional<regnum_t> expected_predicate_val() const
42 {
43 if (predicate.has_value())
44 return predicate->second;
45 return {};
46 }
47
48 template<typename State> task<void> evaluate(State &state) const
49 {
50 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);
54 std::cout << "\tgot " << pval << "\n";
55 if (pval != predicate->second) {
56 std::cout << "\tpredicate skipped\n";
57 co_return;
58 } else {
59 std::cout << "\tpredicate not skipped\n";
60 }
61 }
62 std::cout << "reading sources...\n";
63 std::vector<regval_t> source_vals;
64 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)
72 std::cout << " " << source_regs[i] << "=" << source_vals[i];
73 std::cout << "\n";
74 std::cout << "done with evaluate\n";
75 }
76 };
6 77
7} 78}