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.
Signed-off-by: Nicholas Piggin <[email protected]> --- target/riscv/debug.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/target/riscv/debug.c b/target/riscv/debug.c index d835c0e79a..7ae02fe2d2 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -693,9 +693,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 < RV_MAX_TRIGGERS; i++) { if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) { continue; @@ -709,10 +718,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.51.0
