aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2014-07-08 13:25:04 -0700
committerAndrew Waterman <waterman@eecs.berkeley.edu>2014-07-08 13:25:04 -0700
commit752a7e8060714fff531493c8d4d8a710d547a8bf (patch)
tree0f9f57830d2eb726f1c393a4a1e8c627e8729572
parent43615c60e7d493d7a9656268dab552eb2246f99f (diff)
downloadriscv-isa-sim-752a7e8060714fff531493c8d4d8a710d547a8bf.zip
riscv-isa-sim-752a7e8060714fff531493c8d4d8a710d547a8bf.tar.gz
riscv-isa-sim-752a7e8060714fff531493c8d4d8a710d547a8bf.tar.bz2
Disallow access to FCSR when FP is disabled
-rw-r--r--riscv/decode.h35
-rw-r--r--riscv/processor.cc6
2 files changed, 24 insertions, 17 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index ce57c77..d647b2c 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -94,30 +94,31 @@ private:
// helpful macros, etc
#define MMU (*p->get_mmu())
-#define RS1 p->get_state()->XPR[insn.rs1()]
-#define RS2 p->get_state()->XPR[insn.rs2()]
-#define WRITE_RD(value) p->get_state()->XPR.write(insn.rd(), value)
+#define STATE (*p->get_state())
+#define RS1 STATE.XPR[insn.rs1()]
+#define RS2 STATE.XPR[insn.rs2()]
+#define WRITE_RD(value) STATE.XPR.write(insn.rd(), value)
#ifdef RISCV_ENABLE_COMMITLOG
#undef WRITE_RD
#define WRITE_RD(value) ({ \
reg_t wdata = value; /* value is a func with side-effects */ \
- p->get_state()->log_reg_write = (commit_log_reg_t){insn.rd() << 1, wdata}; \
- p->get_state()->XPR.write(insn.rd(), wdata); \
+ STATE.log_reg_write = (commit_log_reg_t){insn.rd() << 1, wdata}; \
+ STATE.XPR.write(insn.rd(), wdata); \
})
#endif
-#define FRS1 p->get_state()->FPR[insn.rs1()]
-#define FRS2 p->get_state()->FPR[insn.rs2()]
-#define FRS3 p->get_state()->FPR[insn.rs3()]
-#define WRITE_FRD(value) p->get_state()->FPR.write(insn.rd(), value)
+#define FRS1 STATE.FPR[insn.rs1()]
+#define FRS2 STATE.FPR[insn.rs2()]
+#define FRS3 STATE.FPR[insn.rs3()]
+#define WRITE_FRD(value) STATE.FPR.write(insn.rd(), value)
#ifdef RISCV_ENABLE_COMMITLOG
#undef WRITE_FRD
#define WRITE_FRD(value) ({ \
freg_t wdata = value; /* value is a func with side-effects */ \
- p->get_state()->log_reg_write = (commit_log_reg_t){(insn.rd() << 1) | 1, wdata}; \
- p->get_state()->FPR.write(insn.rd(), wdata); \
+ STATE.log_reg_write = (commit_log_reg_t){(insn.rd() << 1) | 1, wdata}; \
+ STATE.FPR.write(insn.rd(), wdata); \
})
#endif
@@ -127,24 +128,24 @@ private:
#define BRANCH_TARGET (pc + insn.sb_imm())
#define JUMP_TARGET (pc + insn.uj_imm())
#define RM ({ int rm = insn.rm(); \
- if(rm == 7) rm = p->get_state()->frm; \
+ if(rm == 7) rm = STATE.frm; \
if(rm > 4) throw trap_illegal_instruction(); \
rm; })
#define xpr64 (xprlen == 64)
-#define require_supervisor if(unlikely(!(p->get_state()->sr & SR_S))) throw trap_privileged_instruction()
+#define require_supervisor if(unlikely(!(STATE.sr & SR_S))) throw trap_privileged_instruction()
#define require_xpr64 if(unlikely(!xpr64)) throw trap_illegal_instruction()
#define require_xpr32 if(unlikely(xpr64)) throw trap_illegal_instruction()
#ifndef RISCV_ENABLE_FPU
# define require_fp throw trap_illegal_instruction()
#else
-# define require_fp if(unlikely(!(p->get_state()->sr & SR_EF))) throw trap_fp_disabled()
+# define require_fp if(unlikely(!(STATE.sr & SR_EF))) throw trap_fp_disabled()
#endif
-#define require_accelerator if(unlikely(!(p->get_state()->sr & SR_EA))) throw trap_accelerator_disabled()
+#define require_accelerator if(unlikely(!(STATE.sr & SR_EA))) throw trap_accelerator_disabled()
#define cmp_trunc(reg) (reg_t(reg) << (64-xprlen))
-#define set_fp_exceptions ({ p->get_state()->fflags |= softfloat_exceptionFlags; \
+#define set_fp_exceptions ({ STATE.fflags |= softfloat_exceptionFlags; \
softfloat_exceptionFlags = 0; })
#define sext32(x) ((sreg_t)(int32_t)(x))
@@ -165,7 +166,7 @@ private:
} while(0)
#define validate_csr(which, write) ({ \
- unsigned my_priv = (p->get_state()->sr & SR_S) ? 1 : 0; \
+ unsigned my_priv = (STATE.sr & SR_S) ? 1 : 0; \
unsigned read_priv = ((which) >> 10) & 3; \
unsigned write_priv = (((which) >> 8) & 3); \
if (read_priv == 3) read_priv = write_priv, write_priv = -1; \
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 284f281..8ba87ed 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -17,6 +17,9 @@
#include <stdexcept>
#include <algorithm>
+#undef STATE
+#define STATE state
+
processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id)
: sim(_sim), mmu(_mmu), ext(NULL), disassembler(new disassembler_t),
id(_id), run(false), debug(false)
@@ -294,10 +297,13 @@ reg_t processor_t::get_pcr(int which)
switch (which)
{
case CSR_FFLAGS:
+ require_fp;
return state.fflags;
case CSR_FRM:
+ require_fp;
return state.frm;
case CSR_FCSR:
+ require_fp;
return (state.fflags << FSR_AEXC_SHIFT) | (state.frm << FSR_RD_SHIFT);
case CSR_STATUS:
return state.sr;