From 1da69b975beeda193d5fa47950be5883ca20ad13 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 21 Mar 2018 17:19:16 -0700 Subject: [PATCH] Implement Hauser misa.C misalignment proposal (#187) See https://github.com/riscv/riscv-isa-manual/commit/0472bcdd166f45712492829a250e228bb45fa5e7 - Reads of xEPC[1] are masked when RVC is disabled - Writes to MISA are suppressed if they would cause a misaligned fetch - Misaligned PCs no longer need to be checked upon fetch --- riscv/decode.h | 2 +- riscv/execute.cc | 1 - riscv/processor.cc | 10 +++++++--- riscv/processor.h | 5 ++++- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index 596a2ad..8fc8ada 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -206,7 +206,7 @@ private: } while(0) #define set_pc_and_serialize(x) \ - do { reg_t __npc = (x); \ + do { reg_t __npc = (x) & p->pc_alignment_mask(); \ npc = PC_SERIALIZE_AFTER; \ STATE.pc = __npc; \ } while(0) diff --git a/riscv/execute.cc b/riscv/execute.cc index b302daa..9d1fb87 100644 --- a/riscv/execute.cc +++ b/riscv/execute.cc @@ -113,7 +113,6 @@ 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/processor.cc b/riscv/processor.cc index 7a5df90..548c649 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -450,6 +450,10 @@ void processor_t::set_csr(int which, reg_t val) case CSR_MCAUSE: state.mcause = val; break; case CSR_MTVAL: state.mtval = val; break; case CSR_MISA: { + // the write is ignored if increasing IALIGN would misalign the PC + if (!(val & (1L << ('C' - 'A'))) && (state.pc & 2)) + break; + if (!(val & (1L << ('F' - 'A')))) val &= ~(1L << ('D' - 'A')); @@ -592,7 +596,7 @@ reg_t processor_t::get_csr(int which) } case CSR_SIP: return state.mip & state.mideleg; case CSR_SIE: return state.mie & state.mideleg; - case CSR_SEPC: return state.sepc; + case CSR_SEPC: return state.sepc & pc_alignment_mask(); case CSR_STVAL: return state.stval; case CSR_STVEC: return state.stvec; case CSR_SCAUSE: @@ -607,7 +611,7 @@ reg_t processor_t::get_csr(int which) case CSR_MSTATUS: return state.mstatus; case CSR_MIP: return state.mip; case CSR_MIE: return state.mie; - case CSR_MEPC: return state.mepc; + case CSR_MEPC: return state.mepc & pc_alignment_mask(); case CSR_MSCRATCH: return state.mscratch; case CSR_MCAUSE: return state.mcause; case CSR_MTVAL: return state.mtval; @@ -668,7 +672,7 @@ reg_t processor_t::get_csr(int which) return v; } case CSR_DPC: - return state.dpc; + return state.dpc & pc_alignment_mask(); case CSR_DSCRATCH: return state.dscratch; } diff --git a/riscv/processor.h b/riscv/processor.h index ace86f9..3e67215 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -188,8 +188,11 @@ public: if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a'; return ext >= 'A' && ext <= 'Z' && ((state.misa >> (ext - 'A')) & 1); } + reg_t pc_alignment_mask() { + return ~(reg_t)(supports_extension('C') ? 0 : 2); + } void check_pc_alignment(reg_t pc) { - if (unlikely(pc & 2) && !supports_extension('C')) + if (unlikely(pc & ~pc_alignment_mask())) throw trap_instruction_address_misaligned(pc); } reg_t legalize_privilege(reg_t); -- 2.30.2