This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / common / cgen-run.c
1 /* Main simulator loop for CGEN-based simulators.
2    Copyright (C) 1998 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4
5 This file is part of GDB, the GNU debugger.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* ??? These are old notes, kept around for now.
22    Collecting profile data and tracing slow us down so we don't do them in
23    "fast mode".
24    There are 6 possibilities on 2 axes:
25    - no-scaching, insn-scaching, basic-block-scaching
26    - run with full features or run fast
27    Supporting all six possibilities in one executable is a bit much but
28    supporting full/fast seems reasonable.
29    If the scache is configured in it is always used.
30    If pbb-scaching is configured in it is always used.
31    ??? Sometimes supporting more than one set of semantic functions will make
32    the simulator too large - this should be configurable.  Blah blah blah.
33    ??? Supporting full/fast can be more modular, blah blah blah.
34    When the framework is more modular, this can be.
35 */
36
37 #include "sim-main.h"
38 #include "sim-assert.h"
39
40 #ifndef SIM_ENGINE_PREFIX_HOOK
41 #define SIM_ENGINE_PREFIX_HOOK(sd)
42 #endif
43 #ifndef SIM_ENGINE_POSTFIX_HOOK
44 #define SIM_ENGINE_POSTFIX_HOOK(sd)
45 #endif
46
47 static void has_stepped (SIM_DESC, void *);
48 static void engine_run_1 (SIM_DESC, int, int);
49 static void engine_run_n (SIM_DESC, int, int, int, int);
50
51 /* sim_resume for cgen */
52
53 void
54 sim_resume (SIM_DESC sd, int step, int siggnal)
55 {
56   sim_engine *engine = STATE_ENGINE (sd);
57   jmp_buf buf;
58   int jmpval;
59
60   ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
61
62   /* we only want to be single stepping the simulator once */
63   if (engine->stepper != NULL)
64     {
65       sim_events_deschedule (sd, engine->stepper);
66       engine->stepper = NULL;
67     }
68   if (step)
69     engine->stepper = sim_events_schedule (sd, 1, has_stepped, sd);
70
71   sim_module_resume (sd);
72
73 #if WITH_SCACHE
74   if (USING_SCACHE_P (sd))
75     scache_flush (sd);
76 #endif
77
78   /* run/resume the simulator */
79
80   sim_engine_set_run_state (sd, sim_running, 0);
81
82   engine->jmpbuf = &buf;
83   jmpval = setjmp (buf);
84   if (jmpval == sim_engine_start_jmpval
85       || jmpval == sim_engine_restart_jmpval)
86     {
87       int last_cpu_nr = sim_engine_last_cpu_nr (sd);
88       int next_cpu_nr = sim_engine_next_cpu_nr (sd);
89       int nr_cpus = sim_engine_nr_cpus (sd);
90       int max_insns = step ? 1 : 0 /*pbb*/;
91       int fast_p = STATE_RUN_FAST_P (sd);
92
93       sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
94       if (next_cpu_nr >= nr_cpus)
95         next_cpu_nr = 0;
96       if (nr_cpus == 1)
97         engine_run_1 (sd, max_insns, fast_p);
98       else
99         engine_run_n (sd, next_cpu_nr, nr_cpus, max_insns, fast_p);
100     }
101 #if 0 /*wip*/
102   else
103     {
104       /* Account for the last insn executed.  */
105       ++ CPU_INSN_COUNT (cpu);
106       TRACE_INSN_FINI ((sim_cpu *) cpu, 1);
107     }
108 #endif
109
110   engine->jmpbuf = NULL;
111
112   {
113     int i;
114     int nr_cpus = sim_engine_nr_cpus (sd);
115
116 #if 0 /*wip*/
117     /* If the loop exits, either we single-stepped or @cpu@_engine_stop
118        was called.  */
119     if (step)
120       sim_engine_set_run_state (sd, sim_stopped, SIM_SIGTRAP);
121     else
122       sim_engine_set_run_state (sd, pending_reason, pending_sigrc);
123 #endif
124
125     for (i = 0; i < nr_cpus; ++i)
126       {
127         SIM_CPU *cpu = STATE_CPU (sd, i);
128
129         PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) += CPU_INSN_COUNT (cpu);
130       }
131   }
132
133   sim_module_suspend (sd);
134 }
135
136 /* Halt the simulator after just one instruction.  */
137
138 static void
139 has_stepped (SIM_DESC sd, void *data)
140 {
141   ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
142   sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
143 }
144
145 static void
146 engine_run_1 (SIM_DESC sd, int max_insns, int fast_p)
147 {
148   sim_cpu *cpu = STATE_CPU (sd, 0);
149   ENGINE_FN *fn = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
150
151   CPU_MAX_SLICE_INSNS (cpu) = max_insns;
152   CPU_INSN_COUNT (cpu) = 0;
153
154   while (1)
155     {
156       SIM_ENGINE_PREFIX_HOOK (sd);
157
158       (*fn) (cpu);
159
160       SIM_ENGINE_POSTFIX_HOOK (sd);
161
162       /* process any events */
163       if (sim_events_tick (sd))
164         sim_events_process (sd);
165     }
166 }
167
168 static void
169 engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast_p)
170 {
171   int i;
172   ENGINE_FN *engine_fns[MAX_NR_PROCESSORS];
173
174   for (i = 0; i < nr_cpus; ++i)
175     {
176       SIM_CPU *cpu = STATE_CPU (sd, i);
177
178       engine_fns[i] = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
179       CPU_MAX_SLICE_INSNS (cpu) = max_insns;
180       CPU_INSN_COUNT (cpu) = 0;
181     }
182
183   while (1)
184     {
185       SIM_ENGINE_PREFIX_HOOK (sd);
186
187       /* FIXME: proper cycling of all of them, blah blah blah.  */
188       while (next_cpu_nr != nr_cpus)
189         {
190           SIM_CPU *cpu = STATE_CPU (sd, next_cpu_nr);
191
192           (* engine_fns[next_cpu_nr]) (cpu);
193           ++next_cpu_nr;
194         }
195
196       SIM_ENGINE_POSTFIX_HOOK (sd);
197
198       /* process any events */
199       if (sim_events_tick (sd))
200         sim_events_process (sd);
201     }
202 }