From 4299874ad4b07ef457776513a64e5b2397a6a75e Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 22 Feb 2018 15:19:26 -0800 Subject: [PATCH] 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. --- riscv/decode.h | 6 +++--- riscv/execute.cc | 1 + riscv/insns/csrrc.h | 1 + riscv/insns/csrrci.h | 1 + riscv/insns/csrrs.h | 1 + riscv/insns/csrrsi.h | 1 + riscv/insns/csrrw.h | 1 + riscv/insns/csrrwi.h | 1 + riscv/processor.h | 5 +++++ 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 #include #include @@ -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; } -- 2.30.2