aboutsummaryrefslogtreecommitdiff
path: root/riscv/triggers.cc
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2022-03-18 10:55:25 -0700
committerTim Newsome <tim@sifive.com>2022-04-05 10:10:03 -0700
commitda4afeac5812a8d0751301a1b566bc3abaea2bda (patch)
treed66d98e3f5ecf8c7c1996f6c9a90bf3e25110cf8 /riscv/triggers.cc
parentf2646bf1fb2a40d9a723f8c32078d971a17dba7b (diff)
downloadspike-da4afeac5812a8d0751301a1b566bc3abaea2bda.zip
spike-da4afeac5812a8d0751301a1b566bc3abaea2bda.tar.gz
spike-da4afeac5812a8d0751301a1b566bc3abaea2bda.tar.bz2
Move mcontrol match logic into mcontrol_t.
Diffstat (limited to 'riscv/triggers.cc')
-rw-r--r--riscv/triggers.cc115
1 files changed, 54 insertions, 61 deletions
diff --git a/riscv/triggers.cc b/riscv/triggers.cc
index 59c7bf8..092dbbd 100644
--- a/riscv/triggers.cc
+++ b/riscv/triggers.cc
@@ -81,6 +81,57 @@ 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;
+ }
+
+ switch (match) {
+ case triggers::mcontrol_t::MATCH_EQUAL:
+ return value == tdata2;
+ case triggers::mcontrol_t::MATCH_NAPOT:
+ {
+ reg_t mask = ~((1 << (cto(tdata2)+1)) - 1);
+ return (value & mask) == (tdata2 & mask);
+ }
+ case triggers::mcontrol_t::MATCH_GE:
+ return value >= tdata2;
+ case triggers::mcontrol_t::MATCH_LT:
+ return value < tdata2;
+ case triggers::mcontrol_t::MATCH_MASK_LOW:
+ {
+ reg_t mask = tdata2 >> (xlen/2);
+ return (value & mask) == (tdata2 & mask);
+ }
+ case triggers::mcontrol_t::MATCH_MASK_HIGH:
+ {
+ reg_t mask = tdata2 >> (xlen/2);
+ return ((value >> (xlen/2)) & mask) == (tdata2 & mask);
+ }
+ }
+ assert(0);
+}
+
module_t::module_t(unsigned count) : triggers(count) {
for (unsigned i = 0; i < count; i++) {
triggers[i] = new mcontrol_t();
@@ -95,7 +146,6 @@ int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_
return -1;
bool chain_ok = true;
- auto xlen = proc->get_xlen();
for (unsigned int i = 0; i < triggers.size(); i++) {
if (!chain_ok) {
@@ -103,68 +153,11 @@ int module_t::trigger_match(triggers::operation_t operation, reg_t address, reg_
continue;
}
- if ((operation == triggers::OPERATION_EXECUTE && !triggers[i]->execute) ||
- (operation == triggers::OPERATION_STORE && !triggers[i]->store) ||
- (operation == triggers::OPERATION_LOAD && !triggers[i]->load) ||
- (state->prv == PRV_M && !triggers[i]->m) ||
- (state->prv == PRV_S && !triggers[i]->s) ||
- (state->prv == PRV_U && !triggers[i]->u)) {
- continue;
- }
-
- reg_t value;
- if (triggers[i]->select) {
- value = data;
- } else {
- value = address;
- }
-
- // We need this because in 32-bit mode sometimes the PC bits get sign
- // extended.
- if (xlen == 32) {
- value &= 0xffffffff;
- }
-
- auto tdata2 = triggers[i]->tdata2;
- switch (triggers[i]->match) {
- case triggers::mcontrol_t::MATCH_EQUAL:
- if (value != tdata2)
- continue;
- break;
- case triggers::mcontrol_t::MATCH_NAPOT:
- {
- reg_t mask = ~((1 << (cto(tdata2)+1)) - 1);
- if ((value & mask) != (tdata2 & mask))
- continue;
- }
- break;
- case triggers::mcontrol_t::MATCH_GE:
- if (value < tdata2)
- continue;
- break;
- case triggers::mcontrol_t::MATCH_LT:
- if (value >= tdata2)
- continue;
- break;
- case triggers::mcontrol_t::MATCH_MASK_LOW:
- {
- reg_t mask = tdata2 >> (xlen/2);
- if ((value & mask) != (tdata2 & mask))
- continue;
- }
- break;
- case triggers::mcontrol_t::MATCH_MASK_HIGH:
- {
- reg_t mask = tdata2 >> (xlen/2);
- if (((value >> (xlen/2)) & mask) != (tdata2 & mask))
- continue;
- }
- break;
- }
-
- if (!triggers[i]->chain) {
+ if (triggers[i]->memory_access_match(proc, operation, address, data) &&
+ !triggers[i]->chain) {
return i;
}
+
chain_ok = true;
}
return -1;