aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <aswaterman@gmail.com>2015-01-02 17:29:05 -0800
committerAndrew Waterman <aswaterman@gmail.com>2015-01-02 17:29:05 -0800
commitec297672b0c9d58d1ee6c2ac976ccf28863bd3c2 (patch)
tree3ddc58262ddca8b2f610cff9e53bf4390a989d8c
parent3fd738af16ef977f1aa507e2525bb4c16fff9026 (diff)
downloadriscv-isa-sim-ec297672b0c9d58d1ee6c2ac976ccf28863bd3c2.zip
riscv-isa-sim-ec297672b0c9d58d1ee6c2ac976ccf28863bd3c2.tar.gz
riscv-isa-sim-ec297672b0c9d58d1ee6c2ac976ccf28863bd3c2.tar.bz2
On misaligned fetch, set EPC to target, not branch itself
-rw-r--r--riscv/decode.h6
-rw-r--r--riscv/insns/jal.h3
-rw-r--r--riscv/insns/jalr.h6
-rw-r--r--riscv/mmu.h4
4 files changed, 9 insertions, 10 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index b325c59..6d1ffbe 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -155,11 +155,7 @@ private:
((x) & 0x3f) < 0x3f ? 6 : \
8)
-#define set_pc(x) \
- do { if ((x) & 3 /* For now... */) \
- throw trap_instruction_address_misaligned(x); \
- npc = sext_xprlen(x); \
- } while(0)
+#define set_pc(x) (npc = sext_xprlen(x))
#define validate_csr(which, write) ({ \
unsigned my_priv = (STATE.sr & SR_S) ? 1 : 0; \
diff --git a/riscv/insns/jal.h b/riscv/insns/jal.h
index 2694dee..cd59964 100644
--- a/riscv/insns/jal.h
+++ b/riscv/insns/jal.h
@@ -1,2 +1,3 @@
-WRITE_RD(npc);
+reg_t tmp = npc;
set_pc(JUMP_TARGET);
+WRITE_RD(tmp);
diff --git a/riscv/insns/jalr.h b/riscv/insns/jalr.h
index 3924aa4..386e8db 100644
--- a/riscv/insns/jalr.h
+++ b/riscv/insns/jalr.h
@@ -1,3 +1,3 @@
-reg_t temp = RS1;
-WRITE_RD(npc);
-set_pc((temp + insn.i_imm()) & ~1);
+reg_t tmp = npc;
+set_pc((RS1 + insn.i_imm()) & ~reg_t(1));
+WRITE_RD(tmp);
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 08d41be..d24ed18 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -167,7 +167,9 @@ private:
void* data = tlb_data[idx] + addr;
if (unlikely(addr & (bytes-1)))
- store ? throw trap_store_address_misaligned(addr) : throw trap_load_address_misaligned(addr);
+ store ? throw trap_store_address_misaligned(addr) :
+ fetch ? throw trap_instruction_address_misaligned(addr) :
+ throw trap_load_address_misaligned(addr);
if (likely(tag == expected_tag))
return data;