Implement clearing-misa.C-while-PC-is-misaligned proposal
authorAndrew Waterman <andrew@sifive.com>
Thu, 22 Feb 2018 23:19:26 +0000 (15:19 -0800)
committerAndrew Waterman <aswaterman@gmail.com>
Sat, 3 Mar 2018 19:47:54 +0000 (13:47 -0600)
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
riscv/execute.cc
riscv/insns/csrrc.h
riscv/insns/csrrci.h
riscv/insns/csrrs.h
riscv/insns/csrrsi.h
riscv/insns/csrrw.h
riscv/insns/csrrwi.h
riscv/processor.h

index 7f5effc741933b9a3b97fba5f54992ce2dac477f..596a2ad9bfea1bfe24b38ed1b733e5a8c91bb688 100644 (file)
@@ -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
index e60ffd117ebeb58a0f8f16c46bb5161ce1d58053..c5cafc2ee5ead5df9b35f2156540f288167a3ec5 100644 (file)
@@ -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; \
index eae91fe661cdab82ec3eac33948fc35f3e4ab41a..0472d80efd5164b885d99d94f7a58d8359a26037 100644 (file)
@@ -5,3 +5,4 @@ if (write) {
   p->set_csr(csr, old & ~RS1);
 }
 WRITE_RD(sext_xlen(old));
+serialize();
index 986d6013aa858bfad336e5c5f71dbd586b26e347..4d83cc0617edd871ebb9ad823d86a4663c310ce9 100644 (file)
@@ -5,3 +5,4 @@ if (write) {
   p->set_csr(csr, old & ~(reg_t)insn.rs1());
 }
 WRITE_RD(sext_xlen(old));
+serialize();
index ec61b420a6b1c3420441f4c58226aefee9131acf..4e8bde96379935755ef87b32903e5aadd81a5227 100644 (file)
@@ -5,3 +5,4 @@ if (write) {
   p->set_csr(csr, old | RS1);
 }
 WRITE_RD(sext_xlen(old));
+serialize();
index aa44dcca8543ac374400450e4cc4326fc24652bc..b673725b54d1cbc8eb0a4e27e4af7d6563eb45b6 100644 (file)
@@ -5,3 +5,4 @@ if (write) {
   p->set_csr(csr, old | insn.rs1());
 }
 WRITE_RD(sext_xlen(old));
+serialize();
index 9f2324ff6f3fc859ffb3ece63495af9e55ed914c..e45420b570bc52c8bd53e2aaaf893eb6db3b3607 100644 (file)
@@ -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();
index cf0710f1d3742447cf3dc19e999da43075de2756..decadf412141076aec92ec58c4a9101e26456c06 100644 (file)
@@ -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();
index 1b94b1f710e0c69d22e276318331a8e004d6e3cf..070fccf8af1d7515c1c46add649a2912b839da29 100644 (file)
@@ -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; }