/* Main simulator loop for CGEN-based simulators.
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
This file is part of GDB, the GNU debugger.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* ??? These are old notes, kept around for now.
Collecting profile data and tracing slow us down so we don't do them in
#define SIM_ENGINE_POSTFIX_HOOK(sd)
#endif
-static void has_stepped (SIM_DESC, void *);
+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);
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 : 0 /*pbb*/;
+ /* ??? Setting max_insns to 0 allows pbb/jit code to run wild and is
+ useful if all one wants to do is run a benchmark. Need some better
+ way to identify this case. */
+ int max_insns = (step
+ ? 1
+ : (nr_cpus == 1
+ /*&& wip:no-events*/
+ /* Don't do this if running under gdb, need to
+ poll ui for events. */
+ && STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
+ ? 0
+ : 8); /*FIXME: magic number*/
int fast_p = STATE_RUN_FAST_P (sd);
sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
else
engine_run_n (sd, next_cpu_nr, nr_cpus, max_insns, fast_p);
}
-#if 0 /*wip*/
+#if 1 /*wip*/
else
{
/* Account for the last insn executed. */
+ SIM_CPU *cpu = STATE_CPU (sd, sim_engine_last_cpu_nr (sd));
++ CPU_INSN_COUNT (cpu);
- TRACE_INSN_FINI ((sim_cpu *) cpu, 1);
+ CGEN_TRACE_INSN_FINI (cpu, NULL, 1);
}
#endif
int i;
int nr_cpus = sim_engine_nr_cpus (sd);
-#if 0 /*wip*/
+#if 0 /*wip,ignore*/
/* If the loop exits, either we single-stepped or @cpu@_engine_stop
was called. */
if (step)
sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
}
+/* Prepare a cpu for running.
+ MAX_INSNS is the number of insns to execute per time slice.
+ If 0 it means the cpu can run as long as it wants (e.g. until the
+ program completes).
+ ??? Perhaps this should be an argument to the engine_fn. */
+
+static void
+prime_cpu (SIM_CPU *cpu, int max_insns)
+{
+ CPU_MAX_SLICE_INSNS (cpu) = max_insns;
+ CPU_INSN_COUNT (cpu) = 0;
+
+ /* Initialize the insn descriptor table.
+ This has to be done after all initialization so we just defer it to
+ here. */
+
+ if (MACH_PREPARE_RUN (CPU_MACH (cpu)))
+ (* MACH_PREPARE_RUN (CPU_MACH (cpu))) (cpu);
+}
+
+/* Main loop, for 1 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);
- CPU_MAX_SLICE_INSNS (cpu) = max_insns;
- CPU_INSN_COUNT (cpu) = 0;
+ prime_cpu (cpu, max_insns);
while (1)
{
}
}
+/* Main loop, for multiple cpus. */
+
static void
engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast_p)
{
SIM_CPU *cpu = STATE_CPU (sd, i);
engine_fns[i] = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
- CPU_MAX_SLICE_INSNS (cpu) = max_insns;
- CPU_INSN_COUNT (cpu) = 0;
+ prime_cpu (cpu, max_insns);
}
while (1)