diff options
author | Scott Johnson <scott.johnson@arilinc.com> | 2022-12-08 12:29:57 -0800 |
---|---|---|
committer | YenHaoChen <howard25336284@gmail.com> | 2022-12-10 19:44:14 +0800 |
commit | 88cfdf2972635e5b7cfd127fbd5b6ebf48cb1462 (patch) | |
tree | 1fe67baddc738d7212a68626e13dc43bf59a31f9 | |
parent | f94ba5f4234b968c553db75b9dc9db4bb886266a (diff) | |
download | riscv-isa-sim-88cfdf2972635e5b7cfd127fbd5b6ebf48cb1462.zip riscv-isa-sim-88cfdf2972635e5b7cfd127fbd5b6ebf48cb1462.tar.gz riscv-isa-sim-88cfdf2972635e5b7cfd127fbd5b6ebf48cb1462.tar.bz2 |
Interpret mhselect in centralized place
And use that for legalize_mhselect(). Not using the second and third
fields yet.
-rw-r--r-- | riscv/triggers.cc | 14 | ||||
-rw-r--r-- | riscv/triggers.h | 26 |
2 files changed, 28 insertions, 12 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc index 35ba9e6..3dec3e2 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -30,18 +30,8 @@ action_t trigger_t::legalize_action(reg_t val) const noexcept { } unsigned trigger_t::legalize_mhselect(bool h_enabled) const noexcept { - unsigned convert[8] = { - (unsigned) 0 , // 0 - (unsigned)(h_enabled ? 1 : 0), // 1 - (unsigned)(h_enabled ? 2 : 0), // 2 - (unsigned) 0 , // 3 - (unsigned) 4 , // 4 - (unsigned)(h_enabled ? 5 : 4), // 5 - (unsigned)(h_enabled ? 6 : 4), // 6 - (unsigned) 4 // 7 - }; - assert(mhselect < 8); - return convert[mhselect]; + const auto interp = interpret_mhselect(h_enabled); + return interp.mhselect; } mhselect_mode_t trigger_t::mhselect_mode(bool h_enabled) const noexcept { diff --git a/riscv/triggers.h b/riscv/triggers.h index 9ce465a..1bb1855 100644 --- a/riscv/triggers.h +++ b/riscv/triggers.h @@ -91,6 +91,32 @@ protected: private: unsigned legalize_mhselect(bool h_enabled) const noexcept; + + struct mhselect_interpretation { + const unsigned mhselect; + const mhselect_mode_t mode; + const std::optional<bool> shift_mhvalue; + }; + + mhselect_interpretation interpret_mhselect(bool h_enabled) const noexcept { + static unsigned warlize_if_h[8] = { 0, 1, 2, 0, 4, 5, 6, 4 }; // 3,7 downgrade + static unsigned warlize_no_h[8] = { 0, 0, 0, 0, 4, 4, 4, 4 }; // only 0,4 legal + static std::optional<mhselect_interpretation> table[8] = { + mhselect_interpretation{ 0, MHSELECT_MODE_IGNORE, std::nullopt }, + mhselect_interpretation{ 1, MHSELECT_MODE_MCONTEXT, true }, + mhselect_interpretation{ 2, MHSELECT_MODE_VMID, true }, + std::nullopt, + mhselect_interpretation{ 4, MHSELECT_MODE_MCONTEXT, false }, + mhselect_interpretation{ 5, MHSELECT_MODE_MCONTEXT, true }, + mhselect_interpretation{ 6, MHSELECT_MODE_VMID, true }, + std::nullopt + }; + assert(mhselect < 8); + unsigned legal = h_enabled ? warlize_if_h[mhselect] : warlize_no_h[mhselect]; + assert(legal < 8); + return table[legal].value(); + } + mhselect_mode_t mhselect_mode(bool h_enabled) const noexcept; unsigned mhselect_compare(bool h_enabled) const noexcept { return legalize_mhselect(h_enabled) == 4 ? mhvalue : (mhvalue << 1) + (mhselect >> 2); // mhvalue or {mhvalue, mhselect[2]} |