diff options
author | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-08-01 22:57:11 -0700 |
---|---|---|
committer | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-08-02 00:05:49 -0700 |
commit | bd5dcc15383d002088a9e0b8b827660a4869cdaf (patch) | |
tree | f2b28089537fba0a338cdf4e322ffa312302f79a /riscv/mmu.h | |
parent | 2d4b6dad64c42c34f75f6ef0f0dd82a4ac5d3f7a (diff) | |
download | spike-bd5dcc15383d002088a9e0b8b827660a4869cdaf.zip spike-bd5dcc15383d002088a9e0b8b827660a4869cdaf.tar.gz spike-bd5dcc15383d002088a9e0b8b827660a4869cdaf.tar.bz2 |
rvv: add mistrap to mmu load/store interface
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Diffstat (limited to 'riscv/mmu.h')
-rw-r--r-- | riscv/mmu.h | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h index 5fa93ff..c14a5ef 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -56,23 +56,32 @@ public: mmu_t(simif_t* sim, processor_t* proc); ~mmu_t(); - inline reg_t misaligned_load(reg_t addr, size_t size) + inline reg_t misaligned_load(reg_t addr, size_t size, bool mistrap) { #ifdef RISCV_ENABLE_MISALIGNED - reg_t res = 0; - for (size_t i = 0; i < size; i++) - res += (reg_t)load_uint8(addr + i) << (i * 8); - return res; + if (mistrap) { + throw trap_load_address_misaligned(addr); + } else { + reg_t res = 0; + for (size_t i = 0; i < size; i++) + res += (reg_t)load_uint8(addr + i) << (i * 8); + return res; + } #else throw trap_load_address_misaligned(addr); #endif } - inline void misaligned_store(reg_t addr, reg_t data, size_t size) + inline void misaligned_store(reg_t addr, reg_t data, size_t size, + bool mistrap) { #ifdef RISCV_ENABLE_MISALIGNED - for (size_t i = 0; i < size; i++) - store_uint8(addr + i, data >> (i * 8)); + if (mistrap) { + throw trap_store_address_misaligned(addr); + } else { + for (size_t i = 0; i < size; i++) + store_uint8(addr + i, data >> (i * 8)); + } #else throw trap_store_address_misaligned(addr); #endif @@ -80,9 +89,9 @@ public: // template for functions that load an aligned value from memory #define load_func(type) \ - inline type##_t load_##type(reg_t addr) { \ + inline type##_t load_##type(reg_t addr, bool mistrap = false) { \ if (unlikely(addr & (sizeof(type##_t)-1))) \ - return misaligned_load(addr, sizeof(type##_t)); \ + return misaligned_load(addr, sizeof(type##_t), mistrap); \ reg_t vpn = addr >> PGSHIFT; \ if (likely(tlb_load_tag[vpn % TLB_ENTRIES] == vpn)) \ return *(type##_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr); \ @@ -114,9 +123,9 @@ public: // template for functions that store an aligned value to memory #define store_func(type) \ - void store_##type(reg_t addr, type##_t val) { \ + void store_##type(reg_t addr, type##_t val, bool mistrap = false) { \ if (unlikely(addr & (sizeof(type##_t)-1))) \ - return misaligned_store(addr, val, sizeof(type##_t)); \ + return misaligned_store(addr, val, sizeof(type##_t), mistrap); \ reg_t vpn = addr >> PGSHIFT; \ if (likely(tlb_store_tag[vpn % TLB_ENTRIES] == vpn)) \ *(type##_t*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr) = val; \ |