aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2020-11-10 22:02:20 -0800
committerScott Johnson <scott.johnson@arilinc.com>2020-11-11 09:55:12 -0800
commitf019910e120874422220d3c5c6a9711cbf574bad (patch)
tree5a9e6d6283fed832aded547fd398a1a66baaaf08
parent956ef9ac3a66d2d6cda5df33a0e3f1c7d57ed0e0 (diff)
downloadriscv-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.h2
-rw-r--r--riscv/insns/lr_w.h2
-rw-r--r--riscv/mmu.h10
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) { \