import gdb-1999-07-19 snapshot
[external/binutils.git] / sim / common / sim-engine.c
index 46f69e5..9415f63 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic simulator halt/restart.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GDB, the GNU debugger.
@@ -18,11 +18,36 @@ 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 <stdio.h>
+
 #include "sim-main.h"
+#include "sim-assert.h"
 
-#include <stdio.h>
-#include <signal.h>
+/* Get the run state.
+   REASON/SIGRC are the values returned by sim_stop_reason.
+   ??? Should each cpu have its own copy?  */
+
+void
+sim_engine_get_run_state (SIM_DESC sd, enum sim_stop *reason, int *sigrc)
+{
+  sim_engine *engine = STATE_ENGINE (sd);
+  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+  *reason = engine->reason;
+  *sigrc = engine->sigrc;
+}
+
+/* Set the run state to REASON/SIGRC.
+   REASON/SIGRC are the values returned by sim_stop_reason.
+   ??? Should each cpu have its own copy?  */
 
+void
+sim_engine_set_run_state (SIM_DESC sd, enum sim_stop reason, int sigrc)
+{
+  sim_engine *engine = STATE_ENGINE (sd);
+  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+  engine->reason = reason;
+  engine->sigrc = sigrc;
+}
 
 /* Generic halt */
 
@@ -35,6 +60,7 @@ sim_engine_halt (SIM_DESC sd,
                 int sigrc)
 {
   sim_engine *engine = STATE_ENGINE (sd);
+  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
   if (engine->jmpbuf != NULL)
     {
       jmp_buf *halt_buf = engine->jmpbuf;
@@ -42,8 +68,15 @@ sim_engine_halt (SIM_DESC sd,
       engine->next_cpu = next_cpu;
       engine->reason = reason;
       engine->sigrc = sigrc;
+
       SIM_ENGINE_HALT_HOOK (sd, last_cpu, cia);
-      longjmp(*halt_buf, 1);
+
+#ifdef SIM_CPU_EXCEPTION_SUSPEND
+      if (last_cpu != NULL && reason != sim_exited)
+       SIM_CPU_EXCEPTION_SUSPEND (sd, last_cpu, sim_signal_to_host (sd, sigrc));
+#endif
+
+      longjmp (*halt_buf, sim_engine_halt_jmpval);
     }
   else
     sim_io_error (sd, "sim_halt - bad long jump");
@@ -59,13 +92,14 @@ sim_engine_restart (SIM_DESC sd,
                    sim_cia cia)
 {
   sim_engine *engine = STATE_ENGINE (sd);
+  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
   if (engine->jmpbuf != NULL)
     {
       jmp_buf *halt_buf = engine->jmpbuf;
       engine->last_cpu = last_cpu;
       engine->next_cpu = next_cpu;
       SIM_ENGINE_RESTART_HOOK (sd, last_cpu, cia);
-      longjmp(*halt_buf, 0);
+      longjmp (*halt_buf, sim_engine_restart_jmpval);
     }
   else
     sim_io_error (sd, "sim_restart - bad long jump");
@@ -75,41 +109,47 @@ sim_engine_restart (SIM_DESC sd,
 /* Generic error code */
 
 void
-sim_engine_abort (SIM_DESC sd,
-                 sim_cpu *cpu,
-                 sim_cia cia,
-                 const char *fmt,
-                 ...)
+sim_engine_vabort (SIM_DESC sd,
+                  sim_cpu *cpu,
+                  sim_cia cia,
+                  const char *fmt,
+                  va_list ap)
 {
+  ASSERT (sd == NULL || STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
   if (sd == NULL)
     {
-      va_list ap;
-      va_start(ap, fmt);
       vfprintf (stderr, fmt, ap);
-      va_end(ap);
       fprintf (stderr, "\nQuit\n");
       abort ();
     }
   else if (STATE_ENGINE (sd)->jmpbuf == NULL)
     {
-      va_list ap;
-      va_start(ap, fmt);
       sim_io_evprintf (sd, fmt, ap);
-      va_end(ap);
       sim_io_eprintf (sd, "\n");
       sim_io_error (sd, "Quit Simulator");
     }
   else
     {
-      va_list ap;
-      va_start(ap, fmt);
       sim_io_evprintf (sd, fmt, ap);
-      va_end(ap);
       sim_io_eprintf (sd, "\n");
-      sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIGABRT);
+      sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGABRT);
     }
 }
 
+void
+sim_engine_abort (SIM_DESC sd,
+                 sim_cpu *cpu,
+                 sim_cia cia,
+                 const char *fmt,
+                 ...)
+{
+  va_list ap;
+  ASSERT (sd == NULL || STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+  va_start(ap, fmt);
+  sim_engine_vabort (sd, cpu, cia, fmt, ap);
+  va_end (ap);
+}
+
 
 /* Generic next/last cpu */
 
@@ -132,3 +172,39 @@ sim_engine_next_cpu_nr (SIM_DESC sd)
   else
     return sim_engine_last_cpu_nr (sd) + 1;
 }
+
+int
+sim_engine_nr_cpus (SIM_DESC sd)
+{
+  sim_engine *engine = STATE_ENGINE (sd);
+  return engine->nr_cpus;
+}
+
+
+
+
+/* Initialization */
+
+static SIM_RC
+sim_engine_init (SIM_DESC sd)
+{
+  /* initialize the start/stop/resume engine */
+  sim_engine *engine = STATE_ENGINE (sd);
+  engine->jmpbuf = NULL;
+  engine->last_cpu = NULL;
+  engine->next_cpu = NULL;
+  engine->nr_cpus = MAX_NR_PROCESSORS;
+  engine->reason = sim_running;
+  engine->sigrc = 0;
+  engine->stepper = NULL; /* sim_events_init will clean it up */
+  return SIM_RC_OK;
+}
+
+
+SIM_RC
+sim_engine_install (SIM_DESC sd)
+{
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+  sim_module_add_init_fn (sd, sim_engine_init);
+  return SIM_RC_OK;
+}