aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <aswaterman@gmail.com>2018-03-21 17:19:16 -0700
committerGitHub <noreply@github.com>2018-03-21 17:19:16 -0700
commit1da69b975beeda193d5fa47950be5883ca20ad13 (patch)
tree520abe609d8e2401afc140910bb2b417b8a415c5
parentec79312862ebdd597cc0f63e002e14f31c36deb0 (diff)
downloadspike-1da69b975beeda193d5fa47950be5883ca20ad13.zip
spike-1da69b975beeda193d5fa47950be5883ca20ad13.tar.gz
spike-1da69b975beeda193d5fa47950be5883ca20ad13.tar.bz2
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
-rw-r--r--riscv/decode.h2
-rw-r--r--riscv/execute.cc1
-rw-r--r--riscv/processor.cc10
-rw-r--r--riscv/processor.h5
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);