diff options
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/csrs.cc | 39 | ||||
-rw-r--r-- | riscv/csrs.h | 6 | ||||
-rw-r--r-- | riscv/processor.cc | 2 |
3 files changed, 16 insertions, 31 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index d02212b..4ec404b 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1198,6 +1198,21 @@ void float_csr_t::verify_permissions(insn_t insn, bool write) const { require_fp; if (!proc->extension_enabled('F')) throw trap_illegal_instruction(insn.bits()); + + if (proc->extension_enabled(EXT_SMSTATEEN) && proc->extension_enabled(EXT_ZFINX)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_FCSR)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_FCSR)) + throw trap_virtual_instruction(insn.bits()); + + if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_FCSR)) { + if (state->v) + throw trap_virtual_instruction(insn.bits()); + else + throw trap_illegal_instruction(insn.bits()); + } + } } bool float_csr_t::unlogged_write(const reg_t val) noexcept { @@ -1350,30 +1365,6 @@ void sstateen_csr_t::verify_permissions(insn_t insn, bool write) const { throw trap_virtual_instruction(insn.bits()); } -// implement class fcsr_csr_t -fcsr_csr_t::fcsr_csr_t(processor_t* const proc, const reg_t addr, csr_t_p upper_csr, csr_t_p lower_csr, const unsigned upper_lsb): - composite_csr_t(proc, addr, upper_csr, lower_csr, upper_lsb) { -} - -void fcsr_csr_t::verify_permissions(insn_t insn, bool write) const { - composite_csr_t::verify_permissions(insn, write); - - if (proc->extension_enabled(EXT_SMSTATEEN) && proc->extension_enabled(EXT_ZFINX)) { - if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_FCSR)) - throw trap_illegal_instruction(insn.bits()); - - if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_FCSR)) - throw trap_virtual_instruction(insn.bits()); - - if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_FCSR)) { - if (state->v) - throw trap_virtual_instruction(insn.bits()); - else - throw trap_illegal_instruction(insn.bits()); - } - } -} - // implement class senvcfg_csr_t senvcfg_csr_t::senvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): diff --git a/riscv/csrs.h b/riscv/csrs.h index c979942..5fc3a49 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -717,12 +717,6 @@ class sstateen_csr_t: public hstateen_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; -class fcsr_csr_t: public composite_csr_t { - public: - fcsr_csr_t(processor_t* const proc, const reg_t addr, csr_t_p upper_csr, csr_t_p lower_csr, const unsigned upper_lsb); - virtual void verify_permissions(insn_t insn, bool write) const override; -}; - class senvcfg_csr_t final: public masked_csr_t { public: senvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); diff --git a/riscv/processor.cc b/riscv/processor.cc index 6d0d349..ddb0344 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -393,7 +393,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_FFLAGS] = fflags = std::make_shared<float_csr_t>(proc, CSR_FFLAGS, FSR_AEXC >> FSR_AEXC_SHIFT, 0); csrmap[CSR_FRM] = frm = std::make_shared<float_csr_t>(proc, CSR_FRM, FSR_RD >> FSR_RD_SHIFT, 0); assert(FSR_AEXC_SHIFT == 0); // composite_csr_t assumes fflags begins at bit 0 - csrmap[CSR_FCSR] = std::make_shared<fcsr_csr_t>(proc, CSR_FCSR, frm, fflags, FSR_RD_SHIFT); + csrmap[CSR_FCSR] = std::make_shared<composite_csr_t>(proc, CSR_FCSR, frm, fflags, FSR_RD_SHIFT); csrmap[CSR_SEED] = std::make_shared<seed_csr_t>(proc, CSR_SEED); |