diff options
author | Weiwei Li <liweiwei@iscas.ac.cn> | 2023-02-02 10:06:53 +0800 |
---|---|---|
committer | Weiwei Li <liweiwei@iscas.ac.cn> | 2023-02-03 10:34:24 +0800 |
commit | 1d7d5cf3e06cffe4a2a24326d476f50cd96961c6 (patch) | |
tree | 8eddc7ab68dabb18f965b7c0c43d76fe963bd2bb | |
parent | 01155b930eb14242ad329b31771082587f900fb0 (diff) | |
download | spike-1d7d5cf3e06cffe4a2a24326d476f50cd96961c6.zip spike-1d7d5cf3e06cffe4a2a24326d476f50cd96961c6.tar.gz spike-1d7d5cf3e06cffe4a2a24326d476f50cd96961c6.tar.bz2 |
Maintain a changeable list for multi-letter extensions in extension_changeable
function (Only the extensions supported in isa string can be truly changeable)
Add Zcf/Zcd to the changeable list: disable them when misa.F/D is cleared or
Zca is disabled, enable them when misa.F/D is set and Zca is enabled
-rw-r--r-- | riscv/csrs.cc | 5 | ||||
-rw-r--r-- | riscv/processor.h | 15 |
2 files changed, 18 insertions, 2 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index de9381c..b194eb2 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -628,6 +628,11 @@ bool misa_csr_t::unlogged_write(const reg_t val) noexcept { 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_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)); + // update the hypervisor-only bits in MEDELEG and other CSRs if (!new_h && prev_h) { reg_t hypervisor_exceptions = 0 diff --git a/riscv/processor.h b/riscv/processor.h index f09560f..ef0bfb0 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -216,6 +216,10 @@ 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); + } bool extension_enabled(unsigned char ext) const { return extension_enabled(isa_extension_t(ext)); } @@ -234,8 +238,15 @@ public: bool extension_enabled_const(isa_extension_t ext) const { if (ext >= 'A' && ext <= 'Z') return state.misa->extension_enabled_const(ext); - else - return isa->extension_enabled(ext); // assume this can't change + 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; } void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; } bool supports_impl(uint8_t impl) const { |