aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2020-11-12 16:21:10 -0800
committerGitHub <noreply@github.com>2020-11-12 16:21:10 -0800
commit828d8553dcf1e2177de92767bf59545076102b76 (patch)
treed039a2a15f560aa83ed17174166a147d73665ed5
parent9380375e2282b64478e9bcb13f129cba7db42321 (diff)
parente91092f21948ba2e77bfbc4629b82b6aa14d5ed6 (diff)
downloadspike-828d8553dcf1e2177de92767bf59545076102b76.zip
spike-828d8553dcf1e2177de92767bf59545076102b76.tar.gz
spike-828d8553dcf1e2177de92767bf59545076102b76.tar.bz2
Merge pull request #592 from scottj97/fix-misaligned-lr
Fix LR missing misaligned exception
-rw-r--r--riscv/insns/lr_d.h2
-rw-r--r--riscv/insns/lr_w.h2
-rw-r--r--riscv/mmu.h12
3 files changed, 8 insertions, 8 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..9943aea 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)) { \
@@ -189,10 +191,8 @@ public:
#define amo_func(type) \
template<typename op> \
type##_t amo_##type(reg_t addr, op f) { \
- 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, true); \
store_##type(addr, f(lhs)); \
return lhs; \
} catch (trap_load_page_fault& t) { \