aboutsummaryrefslogtreecommitdiff
path: root/sim/common
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>1998-10-07 23:55:42 +0000
committerDoug Evans <dje@google.com>1998-10-07 23:55:42 +0000
commit99bc9a6984f71f42d7ab877529894e2db9809768 (patch)
tree960da4347ac3c13f780292ba4e1cf4365d9eefe7 /sim/common
parent9b6b08c2c0f7a1e2f4f29aa871f8eca2aa7b6aef (diff)
downloadgdb-99bc9a6984f71f42d7ab877529894e2db9809768.zip
gdb-99bc9a6984f71f42d7ab877529894e2db9809768.tar.gz
gdb-99bc9a6984f71f42d7ab877529894e2db9809768.tar.bz2
cgen-run.c: new mainloop for cgen
sim-reg.c: generic sim_fetch/store_register interface fns
Diffstat (limited to 'sim/common')
-rw-r--r--sim/common/.Sanitize2
-rw-r--r--sim/common/cgen-run.c202
-rw-r--r--sim/common/sim-reg.c52
3 files changed, 256 insertions, 0 deletions
diff --git a/sim/common/.Sanitize b/sim/common/.Sanitize
index 0b708c4..cc1af22 100644
--- a/sim/common/.Sanitize
+++ b/sim/common/.Sanitize
@@ -38,6 +38,7 @@ aclocal.m4
callback.c
cgen-mem.h
cgen-ops.h
+cgen-run.c
cgen-scache.c
cgen-sim.h
cgen-trace.c
@@ -127,6 +128,7 @@ sim-options.h
sim-profile.c
sim-profile.h
sim-reason.c
+sim-reg.c
sim-resume.c
sim-run.c
sim-signal.c
diff --git a/sim/common/cgen-run.c b/sim/common/cgen-run.c
new file mode 100644
index 0000000..d4e83b0
--- /dev/null
+++ b/sim/common/cgen-run.c
@@ -0,0 +1,202 @@
+/* Main simulator loop for CGEN-based simulators.
+ Copyright (C) 1998 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.
+
+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. */
+
+/* ??? These are old notes, kept around for now.
+ Collecting profile data and tracing slow us down so we don't do them in
+ "fast mode".
+ There are 6 possibilities on 2 axes:
+ - no-scaching, insn-scaching, basic-block-scaching
+ - run with full features or run fast
+ Supporting all six possibilities in one executable is a bit much but
+ supporting full/fast seems reasonable.
+ If the scache is configured in it is always used.
+ If pbb-scaching is configured in it is always used.
+ ??? Sometimes supporting more than one set of semantic functions will make
+ the simulator too large - this should be configurable. Blah blah blah.
+ ??? Supporting full/fast can be more modular, blah blah blah.
+ When the framework is more modular, this can be.
+*/
+
+#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 void has_stepped (SIM_DESC, void *);
+static void engine_run_1 (SIM_DESC, int, int);
+static void engine_run_n (SIM_DESC, int, int, int, int);
+
+/* sim_resume for cgen */
+
+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);
+
+ /* we only want to be single stepping the simulator once */
+ 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
+
+ /* run/resume the simulator */
+
+ 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 : 0 /*pbb*/;
+ 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 0 /*wip*/
+ else
+ {
+ /* Account for the last insn executed. */
+ ++ CPU_INSN_COUNT (cpu);
+ TRACE_INSN_FINI ((sim_cpu *) cpu, 1);
+ }
+#endif
+
+ engine->jmpbuf = NULL;
+
+ {
+ int i;
+ int nr_cpus = sim_engine_nr_cpus (sd);
+
+#if 0 /*wip*/
+ /* If the loop exits, either we single-stepped or @cpu@_engine_stop
+ was called. */
+ 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);
+}
+
+/* Halt the simulator after just one instruction. */
+
+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
+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;
+
+ while (1)
+ {
+ SIM_ENGINE_PREFIX_HOOK (sd);
+
+ (*fn) (cpu);
+
+ SIM_ENGINE_POSTFIX_HOOK (sd);
+
+ /* process any events */
+ 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);
+ CPU_MAX_SLICE_INSNS (cpu) = max_insns;
+ CPU_INSN_COUNT (cpu) = 0;
+ }
+
+ while (1)
+ {
+ SIM_ENGINE_PREFIX_HOOK (sd);
+
+ /* FIXME: proper cycling of all of them, blah blah blah. */
+ 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);
+
+ /* process any events */
+ if (sim_events_tick (sd))
+ sim_events_process (sd);
+ }
+}
diff --git a/sim/common/sim-reg.c b/sim/common/sim-reg.c
new file mode 100644
index 0000000..3f3dc41
--- /dev/null
+++ b/sim/common/sim-reg.c
@@ -0,0 +1,52 @@
+/* Generic register read/write.
+ Copyright (C) 1998 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.
+
+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. */
+
+#include "sim-main.h"
+#include "sim-assert.h"
+
+/* Generic implementation of sim_fetch_register for simulators using
+ CPU_REG_FETCH.
+ The contents of BUF are in target byte order. */
+/* ??? Obviously the interface needs to be extended to handle multiple
+ cpus. */
+
+int
+sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
+{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+ return (* CPU_REG_FETCH (cpu)) (cpu, rn, buf, length);
+}
+
+/* Generic implementation of sim_fetch_register for simulators using
+ CPU_REG_FETCH.
+ The contents of BUF are in target byte order. */
+/* ??? Obviously the interface needs to be extended to handle multiple
+ cpus. */
+
+int
+sim_store_register (SIM_DESC sd, int rn, unsigned char *buf, int length)
+{
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+ return (* CPU_REG_STORE (cpu)) (cpu, rn, buf, length);
+}