aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'riscv')
-rw-r--r--riscv/csrs.cc13
-rw-r--r--riscv/decode_macros.h1
-rw-r--r--riscv/encoding.h4
-rw-r--r--riscv/extension.h1
-rw-r--r--riscv/insns/mret.h2
-rw-r--r--riscv/log_file.h2
-rw-r--r--riscv/processor.cc6
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);
}