#pragma once #include #include #include #include #include #include #include #include #include "aisa/aisa.h" namespace aisa { template struct PagedMem { using page_t = std::array; static const addr_t PAGE_SIZE = 1 << PAGE_BITS; static const addr_t PAGE_MASK = PAGE_SIZE - 1; std::map pages; bool fetch_mem(byte_t *bytes, addr_t addr, addr_t size) { if (size == 0) return true; auto page_base = addr >> PAGE_BITS; auto page_offset = addr & PAGE_MASK; auto size_here = std::min(size, PAGE_SIZE - page_offset); if (auto page = pages.find(page_base); page != pages.end()) std::memcpy(bytes, page->second.data() + page_offset, size_here); else std::memset(bytes, 0, size_here); return fetch_mem(bytes + size_here, addr + size_here, size - size_here); } bool store_mem(addr_t addr, const byte_t *bytes, addr_t size) { if (size == 0) return true; auto page_base = addr >> PAGE_BITS; auto page_offset = addr & PAGE_MASK; auto size_here = std::min(size, PAGE_SIZE - page_offset); std::memcpy(pages[page_base].data() + page_offset, bytes, size_here); return store_mem(addr + size_here, bytes + size_here, size - size_here); } }; struct TaskStack { std::deque> tasks; bool pop_task(); bool push_task(std::unique_ptr &&task); std::optional top_task(); }; struct VectorRF { std::vector> rf; std::optional load_reg(regnum_t rn) const; bool store_reg(regnum_t rn, regval_t rv); }; }