From: Nicholas Piggin <[email protected]>
helper_itrigger_match() iterates over all triggers so it can maintain
itrigger_enabled rather than calling riscv_itrigger_enabled() which
becomes O(N^2) where N is the number of icount triggers.
Fixes: 2c9d747121 ("target/riscv: Add itrigger support when icount is not
enabled")
Signed-off-by: Nicholas Piggin <[email protected]>
Reviewed-by: Daniel Henrique Barboza <[email protected]>
---
target/riscv/tcg/debug.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/target/riscv/tcg/debug.c b/target/riscv/tcg/debug.c
index 74f1739697..d98e737763 100644
--- a/target/riscv/tcg/debug.c
+++ b/target/riscv/tcg/debug.c
@@ -695,9 +695,18 @@ bool riscv_itrigger_enabled(CPURISCVState *env)
return false;
}
+/*
+ * This is called by TCG when an instruction completes.
+ * TCG runs in single-step mode when itrigger_enabled = true, so
+ * it can call after each insn.
+ */
void helper_itrigger_match(CPURISCVState *env)
{
int count;
+ bool enabled = false;
+
+ g_assert(env->itrigger_enabled);
+
for (int i = 0; i < env->num_triggers; i++) {
if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
continue;
@@ -711,10 +720,12 @@ void helper_itrigger_match(CPURISCVState *env)
}
itrigger_set_count(env, i, count--);
if (!count) {
- env->itrigger_enabled = riscv_itrigger_enabled(env);
do_trigger_action(env, i);
+ } else {
+ enabled = true;
}
}
+ env->itrigger_enabled = enabled;
}
static void riscv_itrigger_update_count(CPURISCVState *env)
--
2.43.0