aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/decode.h14
-rw-r--r--riscv/insns/beq.h2
-rw-r--r--riscv/insns/bge.h2
-rw-r--r--riscv/insns/bgeu.h2
-rw-r--r--riscv/insns/blt.h2
-rw-r--r--riscv/insns/bltu.h2
-rw-r--r--riscv/insns/bne.h2
-rw-r--r--riscv/insns/c_addi.h6
-rw-r--r--riscv/insns/c_beq.h2
-rw-r--r--riscv/insns/c_bne.h2
-rw-r--r--riscv/insns/c_j.h2
-rw-r--r--riscv/insns/eret.h2
-rw-r--r--riscv/insns/j.h2
-rw-r--r--riscv/insns/jal.h2
-rw-r--r--riscv/insns/jalr_c.h6
15 files changed, 32 insertions, 18 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 59ca87a..6dfe6b9 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -212,6 +212,20 @@ private:
#define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen))
#define zext_xprlen(x) ((reg_t(x) << (64-xprlen)) >> (64-xprlen))
+#ifndef RISCV_ENABLE_RVC
+# define set_pc(x) \
+ do { if((x) & (sizeof(insn_t)-1)) \
+ { badvaddr = (x); throw trap_instruction_address_misaligned; } \
+ npc = (x); \
+ } while(0)
+#else
+# define set_pc(x) \
+ do { if((x) & ((sr & SR_EC) ? 1 : 3)) \
+ { badvaddr = (x); throw trap_instruction_address_misaligned; } \
+ npc = (x); \
+ } while(0)
+#endif
+
// RVC stuff
#define INSN_IS_RVC(x) (((x) & 0x3) < 0x3)
diff --git a/riscv/insns/beq.h b/riscv/insns/beq.h
index 072b7b8..7b26488 100644
--- a/riscv/insns/beq.h
+++ b/riscv/insns/beq.h
@@ -1,2 +1,2 @@
if(cmp_trunc(RS1) == cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
diff --git a/riscv/insns/bge.h b/riscv/insns/bge.h
index 45dcc2e..dca544b 100644
--- a/riscv/insns/bge.h
+++ b/riscv/insns/bge.h
@@ -1,2 +1,2 @@
if(sreg_t(cmp_trunc(RS1)) >= sreg_t(cmp_trunc(RS2)))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
diff --git a/riscv/insns/bgeu.h b/riscv/insns/bgeu.h
index 2ba3fa8..6325466 100644
--- a/riscv/insns/bgeu.h
+++ b/riscv/insns/bgeu.h
@@ -1,2 +1,2 @@
if(cmp_trunc(RS1) >= cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
diff --git a/riscv/insns/blt.h b/riscv/insns/blt.h
index 3ffd20e..d84fd7a 100644
--- a/riscv/insns/blt.h
+++ b/riscv/insns/blt.h
@@ -1,2 +1,2 @@
if(sreg_t(cmp_trunc(RS1)) < sreg_t(cmp_trunc(RS2)))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
diff --git a/riscv/insns/bltu.h b/riscv/insns/bltu.h
index 186dcbe..250fd4f 100644
--- a/riscv/insns/bltu.h
+++ b/riscv/insns/bltu.h
@@ -1,2 +1,2 @@
if(cmp_trunc(RS1) < cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
diff --git a/riscv/insns/bne.h b/riscv/insns/bne.h
index 39b0b19..f775721 100644
--- a/riscv/insns/bne.h
+++ b/riscv/insns/bne.h
@@ -1,2 +1,2 @@
if(cmp_trunc(RS1) != cmp_trunc(RS2))
- npc = BRANCH_TARGET;
+ set_pc(BRANCH_TARGET);
diff --git a/riscv/insns/c_addi.h b/riscv/insns/c_addi.h
index c716f69..448e31a 100644
--- a/riscv/insns/c_addi.h
+++ b/riscv/insns/c_addi.h
@@ -1,10 +1,10 @@
require_rvc;
if(CRD_REGNUM == 0)
{
- reg_t temp = npc;
- npc = CRS1;
+ reg_t temp = CRS1;
if(CIMM6 & 0x20)
- RA = temp;
+ RA = npc;
+ set_pc(temp);
}
else
CRD = sext_xprlen(CRS2 + CIMM6);
diff --git a/riscv/insns/c_beq.h b/riscv/insns/c_beq.h
index 4ceaba2..031d96d 100644
--- a/riscv/insns/c_beq.h
+++ b/riscv/insns/c_beq.h
@@ -1,3 +1,3 @@
require_rvc;
if(cmp_trunc(CRS1S) == cmp_trunc(CRS2S))
- npc = CBRANCH_TARGET;
+ set_pc(CBRANCH_TARGET);
diff --git a/riscv/insns/c_bne.h b/riscv/insns/c_bne.h
index 59f257b..caf9229 100644
--- a/riscv/insns/c_bne.h
+++ b/riscv/insns/c_bne.h
@@ -1,3 +1,3 @@
require_rvc;
if(cmp_trunc(CRS1S) != cmp_trunc(CRS2S))
- npc = CBRANCH_TARGET;
+ set_pc(CBRANCH_TARGET);
diff --git a/riscv/insns/c_j.h b/riscv/insns/c_j.h
index 87ee015..5ba9c73 100644
--- a/riscv/insns/c_j.h
+++ b/riscv/insns/c_j.h
@@ -1,2 +1,2 @@
require_rvc;
-npc = CJUMP_TARGET;
+set_pc(CJUMP_TARGET);
diff --git a/riscv/insns/eret.h b/riscv/insns/eret.h
index 37e8588..46d5bed 100644
--- a/riscv/insns/eret.h
+++ b/riscv/insns/eret.h
@@ -2,4 +2,4 @@ require_supervisor;
if(sr & SR_ET)
throw trap_illegal_instruction;
set_sr(((sr & SR_PS) ? sr : (sr & ~SR_S)) | SR_ET);
-npc = epc;
+set_pc(epc);
diff --git a/riscv/insns/j.h b/riscv/insns/j.h
index 8abe0ba..3a4da2a 100644
--- a/riscv/insns/j.h
+++ b/riscv/insns/j.h
@@ -1 +1 @@
-npc = JUMP_TARGET;
+set_pc(JUMP_TARGET);
diff --git a/riscv/insns/jal.h b/riscv/insns/jal.h
index bca7241..41dc403 100644
--- a/riscv/insns/jal.h
+++ b/riscv/insns/jal.h
@@ -1,2 +1,2 @@
RA = npc;
-npc = JUMP_TARGET;
+set_pc(JUMP_TARGET);
diff --git a/riscv/insns/jalr_c.h b/riscv/insns/jalr_c.h
index 536ebbf..91be911 100644
--- a/riscv/insns/jalr_c.h
+++ b/riscv/insns/jalr_c.h
@@ -1,3 +1,3 @@
-reg_t temp = npc;
-npc = RS1 + SIMM;
-RD = temp;
+reg_t temp = RS1;
+RD = npc;
+set_pc(temp + SIMM);