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