From c790cfd3b7e87f69b6c43018f1ccdbf188188d49 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 3 Feb 2023 12:40:17 -0800 Subject: Contain C/Zc*-enable logic entirely within misa_csr_t For DRY purposes, processor_t::set_extension_enable checks isa_t::extension_enabled, rather than relying on the caller to do so. --- riscv/csrs.cc | 17 +++++++++-------- riscv/processor.h | 14 +------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index c8c1b0c..4d33a5e 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -619,9 +619,10 @@ reg_t misa_csr_t::dependency(const reg_t val, const char feature, const char dep } bool misa_csr_t::unlogged_write(const reg_t val) noexcept { + const reg_t old_misa = read(); + // the write is ignored if increasing IALIGN would misalign the PC - if (!(val & (1L << ('C' - 'A'))) && (state->pc & 2) && - proc->extension_changeable(EXT_ZCA)) + if (!(val & (1L << ('C' - 'A'))) && (old_misa & (1L << ('C' - 'A'))) && (state->pc & 2)) return false; reg_t adjusted_val = val; @@ -629,16 +630,16 @@ bool misa_csr_t::unlogged_write(const reg_t val) noexcept { adjusted_val = dependency(adjusted_val, 'Q', 'D'); adjusted_val = dependency(adjusted_val, 'V', 'D'); - const reg_t old_misa = read(); const bool prev_h = old_misa & (1L << ('H' - 'A')); const reg_t new_misa = (adjusted_val & write_mask) | (old_misa & ~write_mask); const bool new_h = new_misa & (1L << ('H' - 'A')); - proc->set_extension_enable(EXT_ZCA, (new_misa & (1L << ('C' - 'A')))); - proc->set_extension_enable(EXT_ZCF, (new_misa & (1L << ('F' - 'A'))) && - proc->extension_enabled(EXT_ZCA)); - proc->set_extension_enable(EXT_ZCD, (new_misa & (1L << ('D' - 'A'))) && - proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCA, (new_misa & (1L << ('C' - 'A'))) || !proc->get_isa().extension_enabled('C')); + proc->set_extension_enable(EXT_ZCF, (new_misa & (1L << ('F' - 'A'))) && proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCD, (new_misa & (1L << ('D' - 'A'))) && proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCB, proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCMP, proc->extension_enabled(EXT_ZCA)); + proc->set_extension_enable(EXT_ZCMT, proc->extension_enabled(EXT_ZCA)); // update the hypervisor-only bits in MEDELEG and other CSRs if (!new_h && prev_h) { diff --git a/riscv/processor.h b/riscv/processor.h index 4caea61..ca22d59 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -216,15 +216,6 @@ public: bool any_custom_extensions() const { return !custom_extensions.empty(); } - // Only the extensions supported in isa string can be changeable - bool extension_changeable(unsigned char ext) const { - return isa->extension_enabled(ext) && - (ext == EXT_ZCF || ext == EXT_ZCD || - (ext == EXT_ZCA && isa->extension_enabled('C') && - !(isa->extension_enabled(EXT_ZCB) || - isa->extension_enabled(EXT_ZCMP) || - isa->extension_enabled(EXT_ZCMT)))); - } bool extension_enabled(unsigned char ext) const { return extension_enabled(isa_extension_t(ext)); } @@ -244,14 +235,11 @@ public: if (ext >= 'A' && ext <= 'Z') return state.misa->extension_enabled_const(ext); else { - assert(!extension_changeable(ext)); return isa->extension_enabled(ext); } } - // Only the changeable extensions can be disabled/enabled void set_extension_enable(unsigned char ext, bool enable) { - if (extension_changeable(ext)) - extension_enable_table[ext] = enable; + extension_enable_table[ext] = enable && isa->extension_enabled(ext); } void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; } bool supports_impl(uint8_t impl) const { -- cgit v1.1