]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/cgen-run.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / sim / common / cgen-run.c
CommitLineData
99bc9a69
DE
1/* Main simulator loop for CGEN-based simulators.
2 Copyright (C) 1998 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 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
47static void has_stepped (SIM_DESC, void *);
48static void engine_run_1 (SIM_DESC, int, int);
49static void engine_run_n (SIM_DESC, int, int, int, int);
50
51/* sim_resume for cgen */
52
53void
54sim_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
138static void
139has_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
145static void
146engine_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
168static void
169engine_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}