]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/m32r/mloop.in
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / m32r / mloop.in
1 # Simulator main loop for m32r. -*- C -*-
2 # Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
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
8 # the Free Software Foundation; either version 2, or (at your option)
9 # any later version.
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 #
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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
40 case "x$1" in
41
42 xsupport)
43
44 cat <<EOF
45
46 static INLINE const IDESC *
47 extract16 (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
62 static INLINE const IDESC *
63 extract32 (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
78 static INLINE SEM_PC
79 execute (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
146 EOF
147
148 ;;
149
150 xinit)
151
152 # Nothing needed.
153
154 ;;
155
156 xextract-simple | xextract-scache)
157
158 cat <<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 }
186 EOF
187
188 ;;
189
190 xextract-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
200 cat <<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 */
256 sim_engine_invalid_insn (current_cpu, pc - 2);
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 }
293 EOF
294
295 ;;
296
297 xfull-exec-* | xfast-exec-*)
298
299 # Inputs: current_cpu, vpc, FAST_P
300 # Outputs: vpc
301 # vpc is the virtual program counter.
302
303 cat <<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
310 EOF
311
312 ;;
313
314 *)
315 echo "Invalid argument to mainloop.in: $1" >&2
316 exit 1
317 ;;
318
319 esac