aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeiwei Li <liweiwei@iscas.ac.cn>2023-02-02 10:06:53 +0800
committerWeiwei Li <liweiwei@iscas.ac.cn>2023-02-03 10:34:24 +0800
commit1d7d5cf3e06cffe4a2a24326d476f50cd96961c6 (patch)
tree8eddc7ab68dabb18f965b7c0c43d76fe963bd2bb
parent01155b930eb14242ad329b31771082587f900fb0 (diff)
downloadspike-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.cc5
-rw-r--r--riscv/processor.h15
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 {