aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-02-03 12:40:17 -0800
committerAndrew Waterman <andrew@sifive.com>2023-02-04 15:20:08 -0800
commitc790cfd3b7e87f69b6c43018f1ccdbf188188d49 (patch)
tree506594666880f04091dd97dd0d957b020957a155
parent4eaaf47c3a55b5439c87857be5501f7c3414035a (diff)
downloadspike-plctlab-plct-zce-fix2.zip
spike-plctlab-plct-zce-fix2.tar.gz
spike-plctlab-plct-zce-fix2.tar.bz2
Contain C/Zc*-enable logic entirely within misa_csr_tplctlab-plct-zce-fix2
For DRY purposes, processor_t::set_extension_enable checks isa_t::extension_enabled, rather than relying on the caller to do so.
-rw-r--r--riscv/csrs.cc17
-rw-r--r--riscv/processor.h14
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 {