diff options
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/csrs.cc | 13 | ||||
-rw-r--r-- | riscv/decode_macros.h | 1 | ||||
-rw-r--r-- | riscv/encoding.h | 4 | ||||
-rw-r--r-- | riscv/extension.h | 1 | ||||
-rw-r--r-- | riscv/insns/mret.h | 2 | ||||
-rw-r--r-- | riscv/log_file.h | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 6 |
7 files changed, 16 insertions, 13 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index f2511e7..a62f63a 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -556,9 +556,8 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { const reg_t requested_mpp = proc->legalize_privilege(get_field(val, MSTATUS_MPP)); const reg_t adjusted_val = set_field(val, MSTATUS_MPP, requested_mpp); reg_t new_mstatus = (read() & ~mask) | (adjusted_val & mask); - if (new_mstatus & MSTATUS_MDT) { - new_mstatus = new_mstatus & ~MSTATUS_MIE; - } + new_mstatus = (new_mstatus & MSTATUS_MDT) ? (new_mstatus & ~MSTATUS_MIE) : new_mstatus; + new_mstatus = (new_mstatus & MSTATUS_SDT) ? (new_mstatus & ~MSTATUS_SIE) : new_mstatus; maybe_flush_tlb(new_mstatus); this->val = adjust_sd(new_mstatus); return true; @@ -1411,8 +1410,9 @@ float_csr_t::float_csr_t(processor_t* const proc, const reg_t addr, const reg_t void float_csr_t::verify_permissions(insn_t insn, bool write) const { masked_csr_t::verify_permissions(insn, write); - require_fs; - if (!proc->extension_enabled('F') && !proc->extension_enabled(EXT_ZFINX)) + + if (!((proc->extension_enabled('F') && STATE.sstatus->enabled(SSTATUS_FS)) + || proc->extension_enabled(EXT_ZFINX))) throw trap_illegal_instruction(insn.bits()); if (proc->extension_enabled(EXT_SMSTATEEN) && proc->extension_enabled(EXT_ZFINX)) { @@ -1432,7 +1432,8 @@ void float_csr_t::verify_permissions(insn_t insn, bool write) const { } bool float_csr_t::unlogged_write(const reg_t val) noexcept { - dirty_fp_state; + if (!proc->extension_enabled(EXT_ZFINX)) + dirty_fp_state; return masked_csr_t::unlogged_write(val); } diff --git a/riscv/decode_macros.h b/riscv/decode_macros.h index b343121..807ad98 100644 --- a/riscv/decode_macros.h +++ b/riscv/decode_macros.h @@ -165,7 +165,6 @@ static inline bool is_aligned(const unsigned val, const unsigned pos) #define require_extension(s) require(p->extension_enabled(s)) #define require_either_extension(A,B) require(p->extension_enabled(A) || p->extension_enabled(B)); #define require_impl(s) require(p->supports_impl(s)) -#define require_fs require(STATE.sstatus->enabled(SSTATUS_FS)) #define require_fp STATE.fflags->verify_permissions(insn, false) #define require_accelerator require(STATE.sstatus->enabled(SSTATUS_XS)) #define require_vector_vs require(p->any_vector_extensions() && STATE.sstatus->enabled(SSTATUS_VS)) diff --git a/riscv/encoding.h b/riscv/encoding.h index dff34ae..dcd4e24 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -4,7 +4,7 @@ /* * This file is auto-generated by running 'make' in - * https://github.com/riscv/riscv-opcodes (6a1be96) + * https://github.com/riscv/riscv-opcodes (47862ce) */ #ifndef RISCV_CSR_ENCODING_H @@ -3019,7 +3019,7 @@ #define INSN_FIELD_MOP_RR_T_30 0x40000000 #define INSN_FIELD_MOP_RR_T_27_26 0xc000000 #define INSN_FIELD_C_MOP_T 0x700 -#define INSN_FIELD_RS2=RS1 0x1f00000 +#define INSN_FIELD_RS2_EQ_RS1 0x1f00000 #endif #ifdef DECLARE_INSN DECLARE_INSN(add, MATCH_ADD, MASK_ADD) diff --git a/riscv/extension.h b/riscv/extension.h index de6ece3..991da7e 100644 --- a/riscv/extension.h +++ b/riscv/extension.h @@ -13,6 +13,7 @@ class extension_t public: virtual std::vector<insn_desc_t> get_instructions() = 0; virtual std::vector<disasm_insn_t*> get_disasms() = 0; + virtual std::vector<csr_t_p> get_csrs ([[maybe_unused]] processor_t &proc) const { return {}; }; virtual const char* name() = 0; virtual void reset() {}; virtual void set_debug(bool UNUSED value) {} diff --git a/riscv/insns/mret.h b/riscv/insns/mret.h index 71e488d..479bfca 100644 --- a/riscv/insns/mret.h +++ b/riscv/insns/mret.h @@ -14,7 +14,7 @@ if (ZICFILP_xLPE(prev_virt, prev_prv)) { } s = set_field(s, MSTATUS_MPELP, elp_t::NO_LP_EXPECTED); s = set_field(s, MSTATUS_MDT, 0); -if (prev_prv == PRV_U || prev_virt) +if (prev_prv == PRV_U || (prev_virt && prev_prv != PRV_M)) s = set_field(s, MSTATUS_SDT, 0); if (prev_virt && prev_prv == PRV_U) STATE.vsstatus->write(STATE.vsstatus->read() & ~SSTATUS_SDT); diff --git a/riscv/log_file.h b/riscv/log_file.h index d039859..9e210bb 100644 --- a/riscv/log_file.h +++ b/riscv/log_file.h @@ -31,7 +31,7 @@ public: FILE *get() { return wrapped_file ? wrapped_file.get() : stderr; } private: - std::unique_ptr<FILE, decltype(&fclose)> wrapped_file; + std::unique_ptr<FILE, int(*)(FILE*)> wrapped_file; }; #endif diff --git a/riscv/processor.cc b/riscv/processor.cc index 9260045..ecdf392 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -304,8 +304,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) const bool nmie = !(state.mnstatus && !get_field(state.mnstatus->read(), MNSTATUS_NMIE)); if (!state.debug_mode && nmie && enabled_interrupts) { // nonstandard interrupts have highest priority - if (enabled_interrupts >> (IRQ_M_EXT + 1)) - enabled_interrupts = enabled_interrupts >> (IRQ_M_EXT + 1) << (IRQ_M_EXT + 1); + if (enabled_interrupts >> (IRQ_LCOF + 1)) + enabled_interrupts = enabled_interrupts >> (IRQ_LCOF + 1) << (IRQ_LCOF + 1); // standard interrupt priority is MEI, MSI, MTI, SEI, SSI, STI else if (enabled_interrupts & MIP_MEIP) enabled_interrupts = MIP_MEIP; @@ -711,6 +711,8 @@ void processor_t::register_extension(extension_t *x) { fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name()); abort(); } + for (auto &csr: x->get_csrs(*this)) + state.add_csr(csr->address, csr); x->set_processor(this); } |