aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2018-02-22 15:19:26 -0800
committerAndrew Waterman <aswaterman@gmail.com>2018-03-03 13:47:54 -0600
commit4299874ad4b07ef457776513a64e5b2397a6a75e (patch)
tree66e952f79375892d256a0f9c0d985f2f109da496 /riscv
parente91d3a441e9391054eecd371922649b7f540cc52 (diff)
downloadspike-4299874ad4b07ef457776513a64e5b2397a6a75e.zip
spike-4299874ad4b07ef457776513a64e5b2397a6a75e.tar.gz
spike-4299874ad4b07ef457776513a64e5b2397a6a75e.tar.bz2
Implement clearing-misa.C-while-PC-is-misaligned proposal
See https://github.com/riscv/riscv-isa-manual/pull/139 Not adopted yet, but I'm putting the implementation here for reference.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/decode.h6
-rw-r--r--riscv/execute.cc1
-rw-r--r--riscv/insns/csrrc.h1
-rw-r--r--riscv/insns/csrrci.h1
-rw-r--r--riscv/insns/csrrs.h1
-rw-r--r--riscv/insns/csrrsi.h1
-rw-r--r--riscv/insns/csrrw.h1
-rw-r--r--riscv/insns/csrrwi.h1
-rw-r--r--riscv/processor.h5
9 files changed, 15 insertions, 3 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 7f5effc..596a2ad 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -201,18 +201,18 @@ private:
#define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen))
#define set_pc(x) \
- do { if (unlikely(((x) & 2)) && !p->supports_extension('C')) \
- throw trap_instruction_address_misaligned(x); \
+ do { p->check_pc_alignment(x); \
npc = sext_xlen(x); \
} while(0)
#define set_pc_and_serialize(x) \
do { reg_t __npc = (x); \
- set_pc(__npc); /* check alignment */ \
npc = PC_SERIALIZE_AFTER; \
STATE.pc = __npc; \
} while(0)
+#define serialize() set_pc_and_serialize(npc)
+
/* Sentinel PC values to serialize simulator pipeline */
#define PC_SERIALIZE_BEFORE 3
#define PC_SERIALIZE_AFTER 5
diff --git a/riscv/execute.cc b/riscv/execute.cc
index e60ffd1..c5cafc2 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -114,6 +114,7 @@ void processor_t::step(size_t n)
default: abort(); \
} \
pc = state.pc; \
+ check_pc_alignment(pc); \
break; \
} else { \
state.pc = pc; \
diff --git a/riscv/insns/csrrc.h b/riscv/insns/csrrc.h
index eae91fe..0472d80 100644
--- a/riscv/insns/csrrc.h
+++ b/riscv/insns/csrrc.h
@@ -5,3 +5,4 @@ if (write) {
p->set_csr(csr, old & ~RS1);
}
WRITE_RD(sext_xlen(old));
+serialize();
diff --git a/riscv/insns/csrrci.h b/riscv/insns/csrrci.h
index 986d601..4d83cc0 100644
--- a/riscv/insns/csrrci.h
+++ b/riscv/insns/csrrci.h
@@ -5,3 +5,4 @@ if (write) {
p->set_csr(csr, old & ~(reg_t)insn.rs1());
}
WRITE_RD(sext_xlen(old));
+serialize();
diff --git a/riscv/insns/csrrs.h b/riscv/insns/csrrs.h
index ec61b42..4e8bde9 100644
--- a/riscv/insns/csrrs.h
+++ b/riscv/insns/csrrs.h
@@ -5,3 +5,4 @@ if (write) {
p->set_csr(csr, old | RS1);
}
WRITE_RD(sext_xlen(old));
+serialize();
diff --git a/riscv/insns/csrrsi.h b/riscv/insns/csrrsi.h
index aa44dcc..b673725 100644
--- a/riscv/insns/csrrsi.h
+++ b/riscv/insns/csrrsi.h
@@ -5,3 +5,4 @@ if (write) {
p->set_csr(csr, old | insn.rs1());
}
WRITE_RD(sext_xlen(old));
+serialize();
diff --git a/riscv/insns/csrrw.h b/riscv/insns/csrrw.h
index 9f2324f..e45420b 100644
--- a/riscv/insns/csrrw.h
+++ b/riscv/insns/csrrw.h
@@ -2,3 +2,4 @@ int csr = validate_csr(insn.csr(), true);
reg_t old = p->get_csr(csr);
p->set_csr(csr, RS1);
WRITE_RD(sext_xlen(old));
+serialize();
diff --git a/riscv/insns/csrrwi.h b/riscv/insns/csrrwi.h
index cf0710f..decadf4 100644
--- a/riscv/insns/csrrwi.h
+++ b/riscv/insns/csrrwi.h
@@ -2,3 +2,4 @@ int csr = validate_csr(insn.csr(), true);
reg_t old = p->get_csr(csr);
p->set_csr(csr, insn.rs1());
WRITE_RD(sext_xlen(old));
+serialize();
diff --git a/riscv/processor.h b/riscv/processor.h
index 1b94b1f..070fccf 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -5,6 +5,7 @@
#include "decode.h"
#include "config.h"
#include "devices.h"
+#include "trap.h"
#include <string>
#include <vector>
#include <map>
@@ -184,6 +185,10 @@ public:
if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a';
return ext >= 'A' && ext <= 'Z' && ((isa >> (ext - 'A')) & 1);
}
+ void check_pc_alignment(reg_t pc) {
+ if (unlikely(pc & 2) && !supports_extension('C'))
+ throw trap_instruction_address_misaligned(pc);
+ }
reg_t legalize_privilege(reg_t);
void set_privilege(reg_t);
void yield_load_reservation() { state.load_reservation = (reg_t)-1; }