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
= ((uint32_t)hi
<< 16) | lo
;
47 reg_t
get_badvaddr() { return badvaddr
; }
54 void check_align(reg_t addr
, int size
, bool fetch
)
60 throw trap_instruction_address_misaligned
;
61 throw trap_data_address_misaligned
;
65 void check_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
67 if(addr
>= memsz
|| addr
+ size
> memsz
)
71 throw trap_instruction_access_fault
;
72 throw store
? trap_store_access_fault
: trap_load_access_fault
;
76 void check_align_and_bounds(reg_t addr
, int size
, bool store
, bool fetch
)
78 check_align(addr
, size
, fetch
);
79 check_bounds(addr
, size
, store
, fetch
);