summaryrefslogtreecommitdiff
path: root/aisa/async.h
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-07-02 13:45:09 -0700
committerJulian Blake Kongslie2022-07-02 13:45:09 -0700
commitc72951a36d6cb9775dc1ecd9bc26bc13e796f10c (patch)
tree5a8fe196beba5c7c674d1b3d627c9a0beac849f5 /aisa/async.h
parentTrivial code reorg. (diff)
downloadissim-c72951a36d6cb9775dc1ecd9bc26bc13e796f10c.tar.xz
Dropping the async interface, and adding some real uarch.
Diffstat (limited to '')
-rw-r--r--aisa/async.h225
1 files changed, 0 insertions, 225 deletions
diff --git a/aisa/async.h b/aisa/async.h
deleted file mode 100644
index 42e99e7..0000000
--- a/aisa/async.h
+++ /dev/null
@@ -1,225 +0,0 @@
1#pragma once
2
3#include <coroutine>
4#include <optional>
5#include <utility>
6#include <memory>
7#include <vector>
8
9#include "aisa/aisa.h"
10#include "aisa/coroutine.h" // IWYU pragma: export
11
12namespace aisa {
13
14 template<typename CRTP> struct AsyncEval {
15 CRTP & crtp() noexcept { return static_cast<CRTP &>(*this); }
16
17 task<regval_t> async_load_reg(regnum_t rn)
18 {
19 while (true) {
20 if (auto rv = crtp().load_reg(rn); rv.has_value())
21 co_return *rv;
22 co_await std::suspend_always{};
23 }
24 }
25
26 task<void> async_store_reg(regnum_t rn, regval_t rv)
27 {
28 while (true) {
29 if (crtp().store_reg(rn, rv))
30 co_return;
31 co_await std::suspend_always{};
32 }
33 }
34
35 task<void> async_fetch_mem(byte_t *bytes, addr_t physical_addr, addr_t size)
36 {
37 while (true) {
38 if (crtp().fetch_mem(bytes, physical_addr, size))
39 co_return;
40 co_await std::suspend_always{};
41 }
42 }
43
44 task<void> async_store_mem(addr_t physical_addr, const byte_t *bytes, addr_t size)
45 {
46 while (true) {
47 if (crtp().store_mem(physical_addr, bytes, size))
48 co_return;
49 co_await std::suspend_always{};
50 }
51 }
52
53 task<bool> async_predicate(const Step &step)
54 {
55 if (step.predicate.has_value()) {
56 regval_t pval = co_await crtp().async_load_reg(step.predicate->first);
57 co_return pval == step.predicate->second;
58 }
59 co_return true;
60 }
61
62 task<void> async_load_source_registers(const Step &step, Wires &w)
63 {
64 w.source_vals.resize(step.source_regs.size());
65 for (unsigned int i = 0; i < step.source_regs.size(); ++i)
66 w.source_vals[i] = co_await crtp().async_load_reg(step.source_regs[i]);
67 }
68
69 task<void> async_load_source_memory(const Step &step, const MemInfo &mi, Wires &w)
70 {
71 w.memory_val.resize(mi.size);
72 co_await crtp().async_fetch_mem(w.memory_val.data(), mi.physical_addr, mi.size);
73 }
74
75 task<void> async_load_sources(const Step &step, Wires &w)
76 {
77 co_await crtp().async_load_source_registers(step, w);
78
79 if (step.mop == MOp::LOAD) {
80 auto mi = step.meminfo(w);
81 co_await crtp().async_load_source_memory(step, mi, w);
82 }
83 }
84
85 task<void> async_write_destination_registers(const Step &step, const Wires &w)
86 {
87 for (unsigned int i = 0; i < step.destination_regs.size(); ++i)
88 co_await crtp().async_store_reg(step.destination_regs[i], w.destination_vals[i]);
89 }
90
91 task<void> async_write_destination_memory(const Step &step, const MemInfo &mi, const Wires &w)
92 {
93 co_await crtp().async_store_mem(mi.physical_addr, w.memory_val.data(), mi.size);
94 }
95
96 task<void> async_write_destinations(const Step &step, const Wires &w)
97 {
98 if (w.aborted)
99 co_return;
100
101 co_await crtp().async_write_destination_registers(step, w);
102
103 if (step.mop == MOp::STORE) {
104 auto mi = step.meminfo(w);
105 co_await crtp().async_write_destination_memory(step, mi, w);
106 }
107 }
108
109 task<void> async_push_task(std::unique_ptr<const Task> &&task)
110 {
111 while (true) {
112 if (crtp().push_task(std::move(task)))
113 co_return;
114 co_await std::suspend_always{};
115 }
116 }
117
118 task<void> async_new_task(std::unique_ptr<const Task> &&task, regval_t environment_val)
119 {
120 auto rn = task->environment;
121 co_await crtp().async_push_task(std::move(task));
122 co_await crtp().async_store_reg(rn, environment_val);
123 }
124
125 task<Wires> async_run_step(const Step &step)
126 {
127 Wires w;
128
129 if (!co_await crtp().async_predicate(step))
130 co_return std::move(w);
131
132 co_await crtp().async_load_sources(step, w);
133
134 step.evaluate(w);
135
136 co_await crtp().async_write_destinations(step, w);
137
138 if (w.new_task.has_value())
139 co_await crtp().async_new_task(std::move(w.new_task->first), w.new_task->second);
140
141 co_return std::move(w);
142 }
143
144 task<const Task *> async_top_task()
145 {
146 while (true) {
147 if (auto rv = crtp().top_task(); rv.has_value())
148 co_return &**rv;
149 co_await std::suspend_always{};
150 }
151 }
152
153 task<void> async_pop_task()
154 {
155 while (true) {
156 if (crtp().pop_task())
157 co_return;
158 co_await std::suspend_always{};
159 }
160 }
161
162 task<std::optional<std::unique_ptr<const Step>>> async_fetch_step()
163 {
164 auto task = co_await crtp().async_top_task();
165
166 auto rn = task->environment;
167 auto rv = co_await crtp().async_load_reg(rn);
168
169 auto step = task->step(rv);
170 if (step.has_value()) {
171 co_await crtp().async_store_reg(rn, step->second);
172 co_return std::move(step->first);
173 } else {
174 co_await crtp().async_pop_task();
175 co_return {};
176 }
177 }
178
179 task<std::pair<std::unique_ptr<const Step>, Wires>> async_fetch_and_run_step()
180 {
181 while (true) {
182 if (auto step = co_await crtp().async_fetch_step(); step.has_value()) {
183 auto wires = co_await crtp().async_run_step(**step);
184 co_return {std::move(*step), std::move(wires)};
185 }
186 }
187 }
188
189 task<void> async_run_subtree()
190 {
191 while (true) {
192 if (auto step = co_await crtp().async_fetch_step(); step.has_value())
193 co_await crtp().async_run_step_and_subtree(**step);
194 else
195 break;
196 }
197 }
198
199 task<Wires> async_run_step_and_subtree(const Step &step)
200 {
201 auto w = co_await crtp().async_run_step(step);
202
203 if (w.new_task.has_value())
204 co_await crtp().async_run_subtree();
205
206 co_return std::move(w);
207 }
208
209 task<void> async_setup_initial_task(const ISA &isa)
210 {
211 auto task = isa.initial_task();
212
213 co_await crtp().async_new_task(std::move(task.first), task.second);
214 }
215
216 task<void> async_run(const ISA &isa)
217 {
218 co_await crtp().async_setup_initial_task(isa);
219
220 co_await crtp().async_run_subtree();
221 }
222
223 };
224
225}