#include "sim-main.h"
#include "sim-assert.h"
#ifndef SIM_ENGINE_PREFIX_HOOK
#define SIM_ENGINE_PREFIX_HOOK(sd)
#endif
#ifndef SIM_ENGINE_POSTFIX_HOOK
#define SIM_ENGINE_POSTFIX_HOOK(sd)
#endif
static sim_event_handler has_stepped;
static void prime_cpu (SIM_CPU *, int);
static void engine_run_1 (SIM_DESC, int, int);
static void engine_run_n (SIM_DESC, int, int, int, int);
void
sim_resume (SIM_DESC sd, int step, int siggnal)
{
sim_engine *engine = STATE_ENGINE (sd);
jmp_buf buf;
int jmpval;
ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
if (engine->stepper != NULL)
{
sim_events_deschedule (sd, engine->stepper);
engine->stepper = NULL;
}
if (step)
engine->stepper = sim_events_schedule (sd, 1, has_stepped, sd);
sim_module_resume (sd);
#if WITH_SCACHE
if (USING_SCACHE_P (sd))
scache_flush (sd);
#endif
sim_engine_set_run_state (sd, sim_running, 0);
engine->jmpbuf = &buf;
jmpval = setjmp (buf);
if (jmpval == sim_engine_start_jmpval
|| jmpval == sim_engine_restart_jmpval)
{
int last_cpu_nr = sim_engine_last_cpu_nr (sd);
int next_cpu_nr = sim_engine_next_cpu_nr (sd);
int nr_cpus = sim_engine_nr_cpus (sd);
int max_insns = (step
? 1
: (nr_cpus == 1
&& STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
? 0
: 8);
int fast_p = STATE_RUN_FAST_P (sd);
sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
if (next_cpu_nr >= nr_cpus)
next_cpu_nr = 0;
if (nr_cpus == 1)
engine_run_1 (sd, max_insns, fast_p);
else
engine_run_n (sd, next_cpu_nr, nr_cpus, max_insns, fast_p);
}
#if 1
else
{
SIM_CPU *cpu = STATE_CPU (sd, sim_engine_last_cpu_nr (sd));
++ CPU_INSN_COUNT (cpu);
TRACE_INSN_FINI (cpu, NULL, 1);
}
#endif
engine->jmpbuf = NULL;
{
int i;
int nr_cpus = sim_engine_nr_cpus (sd);
#if 0
if (step)
sim_engine_set_run_state (sd, sim_stopped, SIM_SIGTRAP);
else
sim_engine_set_run_state (sd, pending_reason, pending_sigrc);
#endif
for (i = 0; i < nr_cpus; ++i)
{
SIM_CPU *cpu = STATE_CPU (sd, i);
PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) += CPU_INSN_COUNT (cpu);
}
}
sim_module_suspend (sd);
}
static void
has_stepped (SIM_DESC sd, void *data)
{
ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
}
static void
prime_cpu (SIM_CPU *cpu, int max_insns)
{
CPU_MAX_SLICE_INSNS (cpu) = max_insns;
CPU_INSN_COUNT (cpu) = 0;
if (MACH_PREPARE_RUN (CPU_MACH (cpu)))
(* MACH_PREPARE_RUN (CPU_MACH (cpu))) (cpu);
}
static void
engine_run_1 (SIM_DESC sd, int max_insns, int fast_p)
{
sim_cpu *cpu = STATE_CPU (sd, 0);
ENGINE_FN *fn = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
prime_cpu (cpu, max_insns);
while (1)
{
SIM_ENGINE_PREFIX_HOOK (sd);
(*fn) (cpu);
SIM_ENGINE_POSTFIX_HOOK (sd);
if (sim_events_tick (sd))
sim_events_process (sd);
}
}
static void
engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast_p)
{
int i;
ENGINE_FN *engine_fns[MAX_NR_PROCESSORS];
for (i = 0; i < nr_cpus; ++i)
{
SIM_CPU *cpu = STATE_CPU (sd, i);
engine_fns[i] = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
prime_cpu (cpu, max_insns);
}
while (1)
{
SIM_ENGINE_PREFIX_HOOK (sd);
while (next_cpu_nr != nr_cpus)
{
SIM_CPU *cpu = STATE_CPU (sd, next_cpu_nr);
(* engine_fns[next_cpu_nr]) (cpu);
++next_cpu_nr;
}
SIM_ENGINE_POSTFIX_HOOK (sd);
if (sim_events_tick (sd))
sim_events_process (sd);
}
}