]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m32r/mloop.in
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / m32r / mloop.in
CommitLineData
c906108c 1# Simulator main loop for m32r. -*- C -*-
a86de8e0 2#
8acc9f48 3# Copyright (C) 1996-2013 Free Software Foundation, Inc.
c906108c
SS
4#
5# This file is part of the GNU Simulators.
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
4744ac1b
JB
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
c906108c
SS
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#
4744ac1b
JB
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
c906108c
SS
19
20# Syntax:
21# /bin/sh mainloop.in command
22#
23# Command is one of:
24#
25# init
26# support
27# extract-{simple,scache,pbb}
28# {full,fast}-exec-{simple,scache,pbb}
29#
30# A target need only provide a "full" version of one of simple,scache,pbb.
31# If the target wants it can also provide a fast version of same, or if
32# the slow (full featured) version is `simple', then the fast version can be
33# one of scache/pbb.
34# A target can't provide more than this.
35# However for illustration's sake this file provides examples of all.
36
37# ??? After a few more ports are done, revisit.
38# Will eventually need to machine generate a lot of this.
39
40case "x$1" in
41
42xsupport)
43
44cat <<EOF
45
46static INLINE const IDESC *
47extract16 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
48 ARGBUF *abuf, int fast_p)
49{
50 const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
51
52 @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
53 if (! fast_p)
54 {
55 int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
56 int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
57 @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
58 }
59 return id;
60}
61
62static INLINE const IDESC *
63extract32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
64 ARGBUF *abuf, int fast_p)
65{
66 const IDESC *id = @cpu@_decode (current_cpu, pc, (USI) insn >> 16, insn, abuf);
67
68 @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
69 if (! fast_p)
70 {
71 int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
72 int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
73 @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
74 }
75 return id;
76}
77
78static INLINE SEM_PC
79execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
80{
81 SEM_PC vpc;
82
83 if (fast_p)
84 {
85#if ! WITH_SEM_SWITCH_FAST
86#if WITH_SCACHE
87 vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
88#else
89 vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
90#endif
91#else
92 abort ();
93#endif /* WITH_SEM_SWITCH_FAST */
94 }
95 else
96 {
97#if ! WITH_SEM_SWITCH_FULL
98 ARGBUF *abuf = &sc->argbuf;
99 const IDESC *idesc = abuf->idesc;
100 const CGEN_INSN *idata = idesc->idata;
101#if WITH_SCACHE_PBB
102 int virtual_p = CGEN_INSN_ATTR_VALUE (idata, CGEN_INSN_VIRTUAL);
103#else
104 int virtual_p = 0;
105#endif
106
107 if (! virtual_p)
108 {
109 /* FIXME: call x-before */
110 if (ARGBUF_PROFILE_P (abuf))
111 PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
112 /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
113 if (PROFILE_MODEL_P (current_cpu)
114 && ARGBUF_PROFILE_P (abuf))
115 @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
116 TRACE_INSN_INIT (current_cpu, abuf, 1);
117 TRACE_INSN (current_cpu, idata,
118 (const struct argbuf *) abuf, abuf->addr);
119 }
120#if WITH_SCACHE
121 vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
122#else
123 vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
124#endif
125 if (! virtual_p)
126 {
127 /* FIXME: call x-after */
128 if (PROFILE_MODEL_P (current_cpu)
129 && ARGBUF_PROFILE_P (abuf))
130 {
131 int cycles;
132
133 cycles = (*idesc->timing->model_fn) (current_cpu, sc);
134 @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
135 }
136 TRACE_INSN_FINI (current_cpu, abuf, 1);
137 }
138#else
139 abort ();
140#endif /* WITH_SEM_SWITCH_FULL */
141 }
142
143 return vpc;
144}
145
146EOF
147
148;;
149
150xinit)
151
152# Nothing needed.
153
154;;
155
156xextract-simple | xextract-scache)
157
158cat <<EOF
159{
160 if ((pc & 3) != 0)
161 {
162 /* This only occurs when single stepping.
163 The test is unnecessary otherwise, but the cost is teensy,
164 compared with decoding/extraction. */
165 UHI insn = GETIMEMUHI (current_cpu, pc);
166 extract16 (current_cpu, pc, insn & 0x7fff, sc, FAST_P);
167 }
168 else
169 {
170 USI insn = GETIMEMUSI (current_cpu, pc);
171 if ((SI) insn < 0)
172 {
173 extract32 (current_cpu, pc, insn, sc, FAST_P);
174 }
175 else
176 {
177 extract16 (current_cpu, pc, insn >> 16, sc, FAST_P);
178 extract16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, FAST_P);
179 /* The m32r doesn't support parallel execution. */
180 if ((insn & 0x8000) != 0
181 && (insn & 0x7fff) != 0x7000) /* parallel nops are ok */
182 sim_engine_illegal_insn (current_cpu, pc);
183 }
184 }
185}
186EOF
187
188;;
189
190xextract-pbb)
191
192# Inputs: current_cpu, pc, sc, max_insns, FAST_P
193# Outputs: sc, pc
194# sc must be left pointing past the last created entry.
195# pc must be left pointing past the last created entry.
196# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
197# to record the vpc of the cti insn.
198# SET_INSN_COUNT(n) must be called to record number of real insns.
199
200cat <<EOF
201{
202 const IDESC *idesc;
203 int icount = 0;
204
205 if ((pc & 3) != 0)
206 {
207 /* This only occurs when single stepping.
208 The test is unnecessary otherwise, but the cost is teensy,
209 compared with decoding/extraction. */
210 UHI insn = GETIMEMUHI (current_cpu, pc);
211 idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
212 ++sc;
213 --max_insns;
214 ++icount;
215 pc += 2;
216 if (IDESC_CTI_P (idesc))
217 {
218 SET_CTI_VPC (sc - 1);
219 goto Finish;
220 }
221 }
222
223 while (max_insns > 0)
224 {
225 USI insn = GETIMEMUSI (current_cpu, pc);
226 if ((SI) insn < 0)
227 {
228 idesc = extract32 (current_cpu, pc, insn, &sc->argbuf, FAST_P);
229 ++sc;
230 --max_insns;
231 ++icount;
232 pc += 4;
233 if (IDESC_CTI_P (idesc))
234 {
235 SET_CTI_VPC (sc - 1);
236 break;
237 }
238 }
239 else
240 {
241 idesc = extract16 (current_cpu, pc, insn >> 16, &sc->argbuf, FAST_P);
242 ++sc;
243 --max_insns;
244 ++icount;
245 pc += 2;
246 if (IDESC_CTI_P (idesc))
247 {
248 SET_CTI_VPC (sc - 1);
249 break;
250 }
251 /* The m32r doesn't support parallel execution. */
252 if ((insn & 0x8000) != 0)
253 {
254 /* ??? Defer signalling to execution. */
255 if ((insn & 0x7fff) != 0x7000) /* parallel nops are ok */
2acceee2 256 sim_engine_invalid_insn (current_cpu, pc - 2, 0);
c906108c
SS
257 /* There's no point in processing parallel nops in fast mode.
258 We might as well do this test since we've already tested
259 that we have a parallel nop. */
260 if (0 && FAST_P)
261 {
262 pc += 2;
263 continue;
264 }
265 }
266 else
267 {
268 /* Non-parallel case.
269 While we're guaranteed that there's room to extract the
270 insn, when single stepping we can't; the pbb must stop
271 after the first insn. */
272 if (max_insns == 0)
273 break;
274 }
275 /* We're guaranteed that we can always process 16 bit insns in
276 pairs. */
277 idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
278 ++sc;
279 --max_insns;
280 ++icount;
281 pc += 2;
282 if (IDESC_CTI_P (idesc))
283 {
284 SET_CTI_VPC (sc - 1);
285 break;
286 }
287 }
288 }
289
290 Finish:
291 SET_INSN_COUNT (icount);
292}
293EOF
294
295;;
296
297xfull-exec-* | xfast-exec-*)
298
299# Inputs: current_cpu, vpc, FAST_P
300# Outputs: vpc
301# vpc is the virtual program counter.
302
303cat <<EOF
304#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
305#define DEFINE_SWITCH
306#include "sem-switch.c"
307#else
308 vpc = execute (current_cpu, vpc, FAST_P);
309#endif
310EOF
311
312;;
313
314*)
315 echo "Invalid argument to mainloop.in: $1" >&2
316 exit 1
317 ;;
318
319esac