daily update
[external/binutils.git] / sim / common / cgen-run.c
index d4e83b0..6640eac 100644 (file)
@@ -1,22 +1,21 @@
 /* Main simulator loop for CGEN-based simulators.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2007, 2008, 2009 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
@@ -44,7 +43,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #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);
 
@@ -87,7 +87,18 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
       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);
@@ -98,12 +109,13 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
       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);
+      TRACE_INSN_FINI (cpu, NULL, 1);
     }
 #endif
 
@@ -113,7 +125,7 @@ sim_resume (SIM_DESC sd, int step, int siggnal)
     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)
@@ -142,14 +154,35 @@ has_stepped (SIM_DESC sd, void *data)
   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)
     {
@@ -165,6 +198,8 @@ engine_run_1 (SIM_DESC sd, int max_insns, int fast_p)
     }
 }
 
+/* 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)
 {
@@ -176,8 +211,7 @@ engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast
       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)