diff --git a/riscv/triggers.cc b/riscv/triggers.cc index 9eac9684e..5e877d173 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -146,7 +146,7 @@ reg_t mcontrol_t::tdata1_read(const processor_t * const proc) const noexcept { auto xlen = proc->get_xlen(); v = set_field(v, MCONTROL_TYPE(xlen), CSR_TDATA1_TYPE_MCONTROL); v = set_field(v, CSR_MCONTROL_DMODE(xlen), dmode); - v = set_field(v, MCONTROL_MASKMAX(xlen), 0); + v = set_field(v, MCONTROL_MASKMAX(xlen), maskmax); v = set_field(v, CSR_MCONTROL_HIT, hit); v = set_field(v, MCONTROL_SELECT, select); v = set_field(v, MCONTROL_TIMING, timing); @@ -171,7 +171,7 @@ void mcontrol_t::tdata1_write(processor_t * const proc, const reg_t val, const b timing = legalize_timing(val, MCONTROL_TIMING, MCONTROL_SELECT, MCONTROL_EXECUTE, MCONTROL_LOAD); action = legalize_action(val, MCONTROL_ACTION, CSR_MCONTROL_DMODE(xlen)); chain = allow_chain ? get_field(val, MCONTROL_CHAIN) : 0; - match = legalize_match(get_field(val, MCONTROL_MATCH)); + match = legalize_match(get_field(val, MCONTROL_MATCH), maskmax); m = get_field(val, MCONTROL_M); s = proc->extension_enabled_const('S') ? get_field(val, CSR_MCONTROL_S) : 0; u = proc->extension_enabled_const('U') ? get_field(val, CSR_MCONTROL_U) : 0; @@ -244,11 +244,11 @@ std::optional mcontrol_common_t::detect_memory_access_match(proc return std::nullopt; } -mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val) noexcept +mcontrol_common_t::match_t mcontrol_common_t::legalize_match(reg_t val, reg_t maskmax) noexcept { switch (val) { + case MATCH_NAPOT: if (maskmax == 0) return MATCH_EQUAL; case MATCH_EQUAL: - case MATCH_NAPOT: case MATCH_GE: case MATCH_LT: case MATCH_MASK_LOW: @@ -294,13 +294,14 @@ void mcontrol6_t::tdata1_write(processor_t * const proc, const reg_t val, const auto xlen = proc->get_const_xlen(); assert(get_field(val, CSR_MCONTROL6_TYPE(xlen)) == CSR_TDATA1_TYPE_MCONTROL6); dmode = get_field(val, CSR_MCONTROL6_DMODE(xlen)); + const reg_t maskmax6 = xlen - 1; vs = get_field(val, CSR_MCONTROL6_VS); vu = get_field(val, CSR_MCONTROL6_VU); hit = hit_t(2 * get_field(val, CSR_MCONTROL6_HIT1) + get_field(val, CSR_MCONTROL6_HIT0)); // 2-bit field {hit1,hit0} select = get_field(val, CSR_MCONTROL6_SELECT); action = legalize_action(val, CSR_MCONTROL6_ACTION, CSR_MCONTROL6_DMODE(xlen)); chain = allow_chain ? get_field(val, CSR_MCONTROL6_CHAIN) : 0; - match = legalize_match(get_field(val, CSR_MCONTROL6_MATCH)); + match = legalize_match(get_field(val, CSR_MCONTROL6_MATCH), maskmax6); m = get_field(val, CSR_MCONTROL6_M); s = proc->extension_enabled_const('S') ? get_field(val, CSR_MCONTROL6_S) : 0; u = proc->extension_enabled_const('U') ? get_field(val, CSR_MCONTROL6_U) : 0; diff --git a/riscv/triggers.h b/riscv/triggers.h index 24f920630..d88678def 100644 --- a/riscv/triggers.h +++ b/riscv/triggers.h @@ -221,7 +221,7 @@ class mcontrol_common_t : public trigger_t { bool simple_match(unsigned xlen, reg_t value) const; protected: - static match_t legalize_match(reg_t val) noexcept; + static match_t legalize_match(reg_t val, reg_t maskmax) noexcept; static bool legalize_timing(reg_t val, reg_t timing_mask, reg_t select_mask, reg_t execute_mask, reg_t load_mask) noexcept; bool dmode = false; action_t action = ACTION_DEBUG_EXCEPTION; @@ -243,6 +243,7 @@ class mcontrol_t : public mcontrol_common_t { private: bool hit = false; + const reg_t maskmax = 0; }; class mcontrol6_t : public mcontrol_common_t {