diff options
author | Tim Newsome <tim@sifive.com> | 2022-03-24 11:12:39 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2022-04-05 10:33:27 -0700 |
commit | f3d14f936965fb48a140ab010a9e1b0b2908bf2d (patch) | |
tree | 7ae78337dc6a12f25a378f32a8a49def1b633393 /riscv/triggers.cc | |
parent | bd7ca31454507df073e66d4c9e1d32a062231fc2 (diff) | |
download | spike-f3d14f936965fb48a140ab010a9e1b0b2908bf2d.zip spike-f3d14f936965fb48a140ab010a9e1b0b2908bf2d.tar.gz spike-f3d14f936965fb48a140ab010a9e1b0b2908bf2d.tar.bz2 |
Move trigger match logic into triggers.cc
Diffstat (limited to 'riscv/triggers.cc')
-rw-r--r-- | riscv/triggers.cc | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc index b693bfd..5b9d853 100644 --- a/riscv/triggers.cc +++ b/riscv/triggers.cc @@ -81,31 +81,7 @@ bool mcontrol_t::tdata2_write(processor_t *proc, const reg_t val) noexcept { return true; } -bool mcontrol_t::memory_access_match(processor_t *proc, operation_t operation, reg_t address, reg_t data) { - state_t *state = proc->get_state(); - if ((operation == triggers::OPERATION_EXECUTE && !execute) || - (operation == triggers::OPERATION_STORE && !store) || - (operation == triggers::OPERATION_LOAD && !load) || - (state->prv == PRV_M && !m) || - (state->prv == PRV_S && !s) || - (state->prv == PRV_U && !u)) { - return false; - } - - reg_t value; - if (select) { - value = data; - } else { - value = address; - } - - // We need this because in 32-bit mode sometimes the PC bits get sign - // extended. - auto xlen = proc->get_xlen(); - if (xlen == 32) { - value &= 0xffffffff; - } - +bool mcontrol_t::simple_match(unsigned xlen, reg_t value) const { switch (match) { case triggers::mcontrol_t::MATCH_EQUAL: return value == tdata2; @@ -132,18 +108,51 @@ bool mcontrol_t::memory_access_match(processor_t *proc, operation_t operation, r assert(0); } +match_result_t mcontrol_t::memory_access_match(processor_t *proc, operation_t operation, reg_t address, reg_t data) { + state_t *state = proc->get_state(); + if ((operation == triggers::OPERATION_EXECUTE && !execute) || + (operation == triggers::OPERATION_STORE && !store) || + (operation == triggers::OPERATION_LOAD && !load) || + (state->prv == PRV_M && !m) || + (state->prv == PRV_S && !s) || + (state->prv == PRV_U && !u)) { + return MATCH_NONE; + } + + reg_t value; + if (select) { + value = data; + } else { + value = address; + } + + // We need this because in 32-bit mode sometimes the PC bits get sign + // extended. + auto xlen = proc->get_xlen(); + if (xlen == 32) { + value &= 0xffffffff; + } + + if (simple_match(xlen, value)) { + if (timing) + return MATCH_FIRE_AFTER; + else + return MATCH_FIRE_BEFORE; + } + return MATCH_NONE; +} + module_t::module_t(unsigned count) : triggers(count) { for (unsigned i = 0; i < count; i++) { triggers[i] = new mcontrol_t(); } } -// Return the index of a trigger that matched, or -1. -int module_t::memory_access_match(triggers::operation_t operation, reg_t address, reg_t data) +match_result_t module_t::memory_access_match(action_t *action, operation_t operation, reg_t address, reg_t data) { state_t *state = proc->get_state(); if (state->debug_mode) - return -1; + return MATCH_NONE; bool chain_ok = true; @@ -153,14 +162,15 @@ int module_t::memory_access_match(triggers::operation_t operation, reg_t address continue; } - if (triggers[i]->memory_access_match(proc, operation, address, data) && - !triggers[i]->chain) { - return i; + match_result_t result = triggers[i]->memory_access_match(proc, operation, address, data); + if (result != MATCH_NONE && !triggers[i]->chain) { + *action = triggers[i]->action; + return result; } chain_ok = true; } - return -1; + return MATCH_NONE; } |