diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-02-05 15:26:57 -0800 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2023-02-06 15:07:13 -0800 |
commit | 9b51c16f30769e63b85b3d0f4765c7e1c124f365 (patch) | |
tree | 976dd385fae7174333f502bdf1268cdbaaadbe75 /riscv/csrs.cc | |
parent | 13f075e7af30425227cb1323980397d513de76a2 (diff) | |
download | riscv-isa-sim-9b51c16f30769e63b85b3d0f4765c7e1c124f365.zip riscv-isa-sim-9b51c16f30769e63b85b3d0f4765c7e1c124f365.tar.gz riscv-isa-sim-9b51c16f30769e63b85b3d0f4765c7e1c124f365.tar.bz2 |
Support dynamically disabling misa.C once again
Now, when misa.C is writable, clearing misa.C also disables any
Zc* extension.
Diffstat (limited to 'riscv/csrs.cc')
-rw-r--r-- | riscv/csrs.cc | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 678a738..a5eec56 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -601,12 +601,13 @@ bool sstatus_csr_t::enabled(const reg_t which) { misa_csr_t::misa_csr_t(processor_t* const proc, const reg_t addr, const reg_t max_isa): basic_csr_t(proc, addr, max_isa), max_isa(max_isa), - write_mask(max_isa & (0 // allow MAFDQHV bits in MISA to be modified + write_mask(max_isa & (0 // allow MAFDQCHV bits in MISA to be modified | (1L << ('M' - 'A')) | (1L << ('A' - 'A')) | (1L << ('F' - 'A')) | (1L << ('D' - 'A')) | (1L << ('Q' - 'A')) + | (1L << ('C' - 'A')) | (1L << ('H' - 'A')) | (1L << ('V' - 'A')) ) @@ -618,16 +619,28 @@ 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'))) && (old_misa & (1L << ('C' - 'A'))) && (state->pc & 2)) + return false; + reg_t adjusted_val = val; adjusted_val = dependency(adjusted_val, 'D', 'F'); 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->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) { reg_t hypervisor_exceptions = 0 |