aboutsummaryrefslogtreecommitdiff
path: root/riscv/triggers.cc
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2022-03-24 11:12:39 -0700
committerTim Newsome <tim@sifive.com>2022-04-05 10:33:27 -0700
commitf3d14f936965fb48a140ab010a9e1b0b2908bf2d (patch)
tree7ae78337dc6a12f25a378f32a8a49def1b633393 /riscv/triggers.cc
parentbd7ca31454507df073e66d4c9e1d32a062231fc2 (diff)
downloadspike-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.cc74
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;
}