summaryrefslogtreecommitdiff
path: root/aisa/simple-models.h
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-06-26 16:24:13 -0700
committerJulian Blake Kongslie2022-06-26 16:24:13 -0700
commitbbaf58c9fd0f485266d86868dc35f1d2be3589cd (patch)
tree4ae2b78bad51e3aa10776707ed9048804f378487 /aisa/simple-models.h
parentUse a separate EvalContext structure for holding some state. (diff)
downloadissim-bbaf58c9fd0f485266d86868dc35f1d2be3589cd.tar.xz
Significant changes, and a working "ISA" that just computes fib(n).
Diffstat (limited to '')
-rw-r--r--aisa/simple-models.h95
1 files changed, 95 insertions, 0 deletions
diff --git a/aisa/simple-models.h b/aisa/simple-models.h
new file mode 100644
index 0000000..89e8752
--- /dev/null
+++ b/aisa/simple-models.h
@@ -0,0 +1,95 @@
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <cstring>
6#include <deque>
7#include <map>
8#include <memory>
9#include <optional>
10#include <utility>
11#include <vector>
12
13#include "aisa/aisa.h"
14
15namespace aisa {
16
17 template<unsigned int PAGE_BITS=10> struct PagedMem {
18 using page_t = std::array<byte_t, 1 << PAGE_BITS>;
19
20 static const addr_t PAGE_SIZE = 1 << PAGE_BITS;
21 static const addr_t PAGE_MASK = PAGE_SIZE - 1;
22
23 std::map<addr_t, page_t> pages;
24
25 bool fetch_mem(byte_t *bytes, addr_t addr, addr_t size)
26 {
27 if (size == 0)
28 return true;
29 auto page_base = addr >> PAGE_BITS;
30 auto page_offset = addr & PAGE_MASK;
31 auto size_here = std::min(size, PAGE_SIZE - page_offset);
32 if (auto page = pages.find(page_base); page != pages.end())
33 std::memcpy(bytes, page->second.data() + page_offset, size_here);
34 else
35 std::memset(bytes, 0, size_here);
36 return fetch_mem(bytes + size_here, addr + size_here, size - size_here);
37 }
38
39 bool store_mem(addr_t addr, const byte_t *bytes, addr_t size)
40 {
41 if (size == 0)
42 return true;
43 auto page_base = addr >> PAGE_BITS;
44 auto page_offset = addr & PAGE_MASK;
45 auto size_here = std::min(size, PAGE_SIZE - page_offset);
46 std::memcpy(pages[page_base].data() + page_offset, bytes, size_here);
47 return store_mem(addr + size_here, bytes + size_here, size - size_here);
48 }
49 };
50
51 struct TaskStack {
52 std::deque<std::unique_ptr<const Task>> tasks;
53
54 bool pop_task()
55 {
56 if (tasks.empty())
57 return false;
58 tasks.pop_back();
59 return true;
60 }
61
62 bool push_task(std::unique_ptr<const Task> &&task)
63 {
64 tasks.emplace_back(std::move(task));
65 return true;
66 }
67
68 std::optional<const Task *> top_task()
69 {
70 if (tasks.empty())
71 return {};
72 return tasks.back().get();
73 }
74 };
75
76 struct VectorRF {
77 std::vector<std::optional<regval_t>> rf;
78
79 std::optional<regval_t> load_reg(regnum_t rn) const
80 {
81 if (rf.size() <= rn)
82 return {};
83 return rf[rn];
84 }
85
86 bool store_reg(regnum_t rn, regval_t rv)
87 {
88 if (rf.size() <= rn)
89 rf.resize(rn + 1);
90 rf[rn] = rv;
91 return true;
92 }
93 };
94
95}