7 mmu_t(char* _mem
, size_t _memsz
) : mem(_mem
), memsz(_memsz
), badvaddr(0) {}
9 #define load_func(type) \
10 type##_t load_##type(reg_t addr) { \
11 check_align_and_bounds(addr, sizeof(type##_t), false, false); \
12 return *(type##_t*)(mem+addr); \
15 #define store_func(type) \
16 void store_##type(reg_t addr, type##_t val) { \
17 check_align_and_bounds(addr, sizeof(type##_t), true, false); \
18 *(type##_t*)(mem+addr) = val; \
21 insn_t
load_insn(reg_t addr
, bool rvc
)
23 check_align_and_bounds(addr
, rvc
? 2 : 4, false, true);
24 uint16_t lo
= *(uint16_t*)(mem
+addr
);
25 uint16_t hi
= *(uint16_t*)(mem
+addr
+2);
28 insn
.bits
= lo
| ((uint32_t)hi
<< 16);
48 reg_t
get_badvaddr() { return badvaddr
; }
55 void check_align(reg_t addr
, int size
, bool store
, bool fetch
)
61 throw trap_instruction_address_misaligned
;
63 throw trap_store_address_misaligned
;
64 throw trap_load_address_misaligned
;
68 void check_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
70 if(addr
>= memsz
|| addr
+ size
> memsz
)
74 throw trap_instruction_access_fault
;
75 throw store
? trap_store_access_fault
: trap_load_access_fault
;
79 void check_align_and_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
81 check_align(addr
, size
, store
, fetch
);
82 check_bounds(addr
, size
, store
, fetch
);