diff options
author | Scott Johnson <scott.johnson@arilinc.com> | 2020-11-10 22:02:20 -0800 |
---|---|---|
committer | Scott Johnson <scott.johnson@arilinc.com> | 2020-11-11 09:55:12 -0800 |
commit | f019910e120874422220d3c5c6a9711cbf574bad (patch) | |
tree | 5a9e6d6283fed832aded547fd398a1a66baaaf08 | |
parent | 956ef9ac3a66d2d6cda5df33a0e3f1c7d57ed0e0 (diff) | |
download | riscv-isa-sim-f019910e120874422220d3c5c6a9711cbf574bad.zip riscv-isa-sim-f019910e120874422220d3c5c6a9711cbf574bad.tar.gz riscv-isa-sim-f019910e120874422220d3c5c6a9711cbf574bad.tar.bz2 |
Make LR properly take misaligned exception
Fixes https://github.com/riscv/riscv-isa-sim/issues/591
-rw-r--r-- | riscv/insns/lr_d.h | 2 | ||||
-rw-r--r-- | riscv/insns/lr_w.h | 2 | ||||
-rw-r--r-- | riscv/mmu.h | 10 |
3 files changed, 8 insertions, 6 deletions
diff --git a/riscv/insns/lr_d.h b/riscv/insns/lr_d.h index 3f3521b..6dd8d67 100644 --- a/riscv/insns/lr_d.h +++ b/riscv/insns/lr_d.h @@ -1,5 +1,5 @@ require_extension('A'); require_rv64; -auto res = MMU.load_int64(RS1); +auto res = MMU.load_int64(RS1, true); MMU.acquire_load_reservation(RS1); WRITE_RD(res); diff --git a/riscv/insns/lr_w.h b/riscv/insns/lr_w.h index 8605cc5..185be53 100644 --- a/riscv/insns/lr_w.h +++ b/riscv/insns/lr_w.h @@ -1,4 +1,4 @@ require_extension('A'); -auto res = MMU.load_int32(RS1); +auto res = MMU.load_int32(RS1, true); MMU.acquire_load_reservation(RS1); WRITE_RD(res); diff --git a/riscv/mmu.h b/riscv/mmu.h index f39d201..f16aed4 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -92,11 +92,13 @@ public: // template for functions that load an aligned value from memory #define load_func(type, prefix, xlate_flags) \ - inline type##_t prefix##_##type(reg_t addr) { \ + inline type##_t prefix##_##type(reg_t addr, bool require_alignment = false) { \ if (xlate_flags) \ flush_tlb(); \ - if (unlikely(addr & (sizeof(type##_t)-1))) \ - return misaligned_load(addr, sizeof(type##_t)); \ + if (unlikely(addr & (sizeof(type##_t)-1))) { \ + if (require_alignment) throw trap_load_address_misaligned(addr, 0, 0); \ + else return misaligned_load(addr, sizeof(type##_t)); \ + } \ reg_t vpn = addr >> PGSHIFT; \ size_t size = sizeof(type##_t); \ if (likely(tlb_load_tag[vpn % TLB_ENTRIES] == vpn)) { \ @@ -192,7 +194,7 @@ public: if (addr & (sizeof(type##_t)-1)) \ throw trap_store_address_misaligned(addr, 0, 0); \ try { \ - auto lhs = load_##type(addr); \ + auto lhs = load_##type(addr, false); \ store_##type(addr, f(lhs)); \ return lhs; \ } catch (trap_load_page_fault& t) { \ |