Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / common / genmloop.sh
CommitLineData
c906108c 1# Generate the main loop of the simulator.
88b9d363 2# Copyright (C) 1996-2022 Free Software Foundation, Inc.
c906108c
SS
3# Contributed by Cygnus Support.
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# This file creates two files: eng.hin and mloop.cin.
21# eng.hin defines a few macros that specify what kind of engine was selected
22# based on the arguments to this script.
23# mloop.cin contains the engine.
24#
25# ??? Rename mloop.c to eng.c?
26# ??? Rename mainloop.in to engine.in?
27# ??? Add options to specify output file names?
28# ??? Rename this file to genengine.sh?
29#
30# Syntax: genmloop.sh [options]
31#
32# Options:
33#
34# -mono | -multi
35# - specify single cpu or multiple cpus (number specifyable at runtime),
36# maximum number is a configuration parameter
37# - -multi wip
38#
39# -fast: include support for fast execution in addition to full featured mode
40#
41# Full featured mode is for tracing, profiling, etc. and is always
42# provided. Fast mode contains no frills, except speed.
43# A target need only provide a "full" version of one of
44# simple,scache,pbb. If the target wants it can also provide a fast
45# version of same. It can't provide more than this.
46# ??? Later add ability to have another set of full/fast semantics
47# for use in with-devices/with-smp situations (pbb can be inappropriate
48# here).
49#
50# -full-switch: same as -fast but for full featured version of -switch
51# Only needed if -fast present.
52#
53# -simple: simple execution engine (the default)
54#
55# This engine fetches and executes one instruction at a time.
56# Field extraction is done in the semantic routines.
57#
58# ??? There are two possible flavours of -simple. One that extracts
59# fields in the semantic routine (which is what is implemented here),
60# and one that stores the extracted fields in ARGBUF before calling the
61# semantic routine. The latter is essentially the -scache case with a
62# cache size of one (and the scache lookup code removed). There are no
63# current uses of this and it's not clear when doing this would be a win.
64# More complicated ISA's that want to use -simple may find this a win.
65# Should this ever be desirable, implement a new engine style here and
66# call it -extract (or some such). It's believed that the CGEN-generated
67# code for the -scache case would be usable here, so no new code
68# generation option would be needed for CGEN.
69#
70# -scache: use the scache to speed things up (not always a win)
71#
72# This engine caches the extracted instruction before executing it.
73# When executing instructions they are first looked up in the scache.
74#
75# -pbb: same as -scache but extract a (pseudo-) basic block at a time
76#
77# This engine is basically identical to the scache version except that
78# extraction is done a pseudo-basic-block at a time and the address of
79# the scache entry of a branch target is recorded as well.
80# Additional speedups are then possible by defering Ctrl-C checking
81# to the end of basic blocks and by threading the insns together.
82# We call them pseudo-basic-block's instead of just basic-blocks because
83# they're not necessarily basic-blocks, though normally are.
84#
85# -parallel-read: support parallel execution with read-before-exec support.
86# -parallel-write: support parallel execution with write-after-exec support.
53a5351d
JM
87# -parallel-generic-write: support parallel execution with generic queued
88# writes.
c906108c
SS
89#
90# One of these options is specified in addition to -simple, -scache,
91# -pbb. Note that while the code can determine if the cpu supports
92# parallel execution with HAVE_PARALLEL_INSNS [and thus this option is
93# technically unnecessary], having this option cuts down on the clutter
94# in the result.
95#
53a5351d
JM
96# -parallel-only: semantic code only supports parallel version of insn
97#
98# Semantic code only supports parallel versions of each insn.
99# Things can be sped up by generating both serial and parallel versions
100# and is better suited to mixed parallel architectures like the m32r.
101#
bb4e03e5
BE
102# -prefix: string to prepend to function names in mloop.c/eng.h.
103#
104# If no prefix is specified, the cpu type is used.
105#
c906108c
SS
106# -switch file: specify file containing semantics implemented as a switch()
107#
108# -cpu <cpu-family>
109#
110# Specify the cpu family name.
111#
112# -infile <input-file>
113#
114# Specify the mainloop.in input file.
115#
bb4e03e5
BE
116# -outfile-suffix <output-file-suffix>
117#
118# Specify the suffix to append to output files.
119#
086c6838
NC
120# -shell <shell>
121#
122# Specify the shell to use to execute <input-file>
123#
c906108c
SS
124# Only one of -scache/-pbb may be selected.
125# -simple is the default.
126#
127####
128#
129# TODO
130# - build mainloop.in from .cpu file
131
132type=mono
133#scache=
134#fast=
135#full_switch=
136#pbb=
137parallel=no
53a5351d 138parallel_only=no
c906108c
SS
139switch=
140cpu="unknown"
141infile=""
bb4e03e5
BE
142prefix="unknown"
143outsuffix=""
c906108c
SS
144
145while test $# -gt 0
146do
147 case $1 in
148 -mono) type=mono ;;
149 -multi) type=multi ;;
150 -no-fast) ;;
151 -fast) fast=yes ;;
152 -full-switch) full_switch=yes ;;
153 -simple) ;;
154 -scache) scache=yes ;;
155 -pbb) pbb=yes ;;
156 -no-parallel) ;;
bb4e03e5 157 -outfile-suffix) shift ; outsuffix=$1 ;;
c906108c
SS
158 -parallel-read) parallel=read ;;
159 -parallel-write) parallel=write ;;
53a5351d
JM
160 -parallel-generic-write) parallel=genwrite ;;
161 -parallel-only) parallel_only=yes ;;
bb4e03e5 162 -prefix) shift ; prefix=$1 ;;
c906108c
SS
163 -switch) shift ; switch=$1 ;;
164 -cpu) shift ; cpu=$1 ;;
165 -infile) shift ; infile=$1 ;;
086c6838 166 -shell) shift ; SHELL=$1 ;;
c906108c
SS
167 *) echo "unknown option: $1" >&2 ; exit 1 ;;
168 esac
169 shift
170done
171
172# Argument validation.
173
174if [ x$scache = xyes -a x$pbb = xyes ] ; then
175 echo "only one of -scache and -pbb may be selected" >&2
176 exit 1
177fi
178
179if [ "x$cpu" = xunknown ] ; then
180 echo "cpu family not specified" >&2
181 exit 1
182fi
183
184if [ "x$infile" = x ] ; then
185 echo "mainloop.in not specified" >&2
186 exit 1
187fi
188
bb4e03e5
BE
189if [ "x$prefix" = xunknown ] ; then
190 prefix=$cpu
191fi
192
c906108c
SS
193lowercase='abcdefghijklmnopqrstuvwxyz'
194uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
195CPU=`echo ${cpu} | tr "${lowercase}" "${uppercase}"`
bb4e03e5 196PREFIX=`echo ${prefix} | tr "${lowercase}" "${uppercase}"`
c906108c
SS
197
198##########################################################################
199
bb4e03e5
BE
200rm -f eng${outsuffix}.hin
201exec 1>eng${outsuffix}.hin
c906108c
SS
202
203echo "/* engine configuration for ${cpu} */"
204echo ""
205
206echo "/* WITH_FAST: non-zero if a fast version of the engine is available"
207echo " in addition to the full-featured version. */"
208if [ x$fast = xyes ] ; then
209 echo "#define WITH_FAST 1"
210else
211 echo "#define WITH_FAST 0"
212fi
213
214echo ""
bb4e03e5 215echo "/* WITH_SCACHE_PBB_${PREFIX}: non-zero if the pbb engine was selected. */"
c906108c 216if [ x$pbb = xyes ] ; then
bb4e03e5 217 echo "#define WITH_SCACHE_PBB_${PREFIX} 1"
c906108c 218else
bb4e03e5 219 echo "#define WITH_SCACHE_PBB_${PREFIX} 0"
c906108c
SS
220fi
221
222echo ""
223echo "/* HAVE_PARALLEL_INSNS: non-zero if cpu can parallelly execute > 1 insn. */"
53a5351d
JM
224# blah blah blah, other ways to do this, blah blah blah
225case x$parallel in
226xno)
227 echo "#define HAVE_PARALLEL_INSNS 0"
228 echo "#define WITH_PARALLEL_READ 0"
229 echo "#define WITH_PARALLEL_WRITE 0"
230 echo "#define WITH_PARALLEL_GENWRITE 0"
231 ;;
232xread)
233 echo "#define HAVE_PARALLEL_INSNS 1"
234 echo "/* Parallel execution is supported by read-before-exec. */"
235 echo "#define WITH_PARALLEL_READ 1"
236 echo "#define WITH_PARALLEL_WRITE 0"
237 echo "#define WITH_PARALLEL_GENWRITE 0"
238 ;;
239xwrite)
240 echo "#define HAVE_PARALLEL_INSNS 1"
241 echo "/* Parallel execution is supported by write-after-exec. */"
242 echo "#define WITH_PARALLEL_READ 0"
243 echo "#define WITH_PARALLEL_WRITE 1"
244 echo "#define WITH_PARALLEL_GENWRITE 0"
245 ;;
246xgenwrite)
247 echo "#define HAVE_PARALLEL_INSNS 1"
248 echo "/* Parallel execution is supported by generic write-after-exec. */"
249 echo "#define WITH_PARALLEL_READ 0"
250 echo "#define WITH_PARALLEL_WRITE 0"
251 echo "#define WITH_PARALLEL_GENWRITE 1"
252 ;;
253esac
c906108c
SS
254
255if [ "x$switch" != x ] ; then
256 echo ""
257 echo "/* WITH_SEM_SWITCH_FULL: non-zero if full-featured engine is"
258 echo " implemented as a switch(). */"
259 if [ x$fast != xyes -o x$full_switch = xyes ] ; then
260 echo "#define WITH_SEM_SWITCH_FULL 1"
261 else
262 echo "#define WITH_SEM_SWITCH_FULL 0"
263 fi
264 echo ""
265 echo "/* WITH_SEM_SWITCH_FAST: non-zero if fast engine is"
266 echo " implemented as a switch(). */"
267 if [ x$fast = xyes ] ; then
268 echo "#define WITH_SEM_SWITCH_FAST 1"
269 else
270 echo "#define WITH_SEM_SWITCH_FAST 0"
271 fi
272fi
273
274# Decls of functions we define.
275
276echo ""
277echo "/* Functions defined in the generated mainloop.c file"
278echo " (which doesn't necessarily have that file name). */"
279echo ""
bb4e03e5
BE
280echo "extern ENGINE_FN ${prefix}_engine_run_full;"
281echo "extern ENGINE_FN ${prefix}_engine_run_fast;"
c906108c
SS
282
283if [ x$pbb = xyes ] ; then
284 echo ""
bb4e03e5
BE
285 echo "extern SEM_PC ${prefix}_pbb_begin (SIM_CPU *, int);"
286 echo "extern SEM_PC ${prefix}_pbb_chain (SIM_CPU *, SEM_ARG);"
287 echo "extern SEM_PC ${prefix}_pbb_cti_chain (SIM_CPU *, SEM_ARG, SEM_BRANCH_TYPE, PCADDR);"
288 echo "extern void ${prefix}_pbb_before (SIM_CPU *, SCACHE *);"
289 echo "extern void ${prefix}_pbb_after (SIM_CPU *, SCACHE *);"
c906108c
SS
290fi
291
292##########################################################################
293
bb4e03e5
BE
294rm -f tmp-mloop-$$.cin mloop${outsuffix}.cin
295exec 1>tmp-mloop-$$.cin
c906108c
SS
296
297# We use @cpu@ instead of ${cpu} because we still need to run sed to handle
298# transformation of @cpu@ for mainloop.in, so there's no need to use ${cpu}
299# here.
300
301cat << EOF
302/* This file is generated by the genmloop script. DO NOT EDIT! */
303
6df01ab8
MF
304/* This must come before any other includes. */
305#include "defs.h"
306
c906108c
SS
307/* Enable switch() support in cgen headers. */
308#define SEM_IN_SWITCH
309
310#define WANT_CPU @cpu@
311#define WANT_CPU_@CPU@
312
313#include "sim-main.h"
314#include "bfd.h"
315#include "cgen-mem.h"
316#include "cgen-ops.h"
317#include "sim-assert.h"
318
319/* Fill in the administrative ARGBUF fields required by all insns,
320 virtual and real. */
321
322static INLINE void
bb4e03e5 323@prefix@_fill_argbuf (const SIM_CPU *cpu, ARGBUF *abuf, const IDESC *idesc,
c906108c
SS
324 PCADDR pc, int fast_p)
325{
326#if WITH_SCACHE
327 SEM_SET_CODE (abuf, idesc, fast_p);
328 ARGBUF_ADDR (abuf) = pc;
329#endif
330 ARGBUF_IDESC (abuf) = idesc;
331}
332
333/* Fill in tracing/profiling fields of an ARGBUF. */
334
335static INLINE void
bb4e03e5 336@prefix@_fill_argbuf_tp (const SIM_CPU *cpu, ARGBUF *abuf,
c906108c
SS
337 int trace_p, int profile_p)
338{
339 ARGBUF_TRACE_P (abuf) = trace_p;
340 ARGBUF_PROFILE_P (abuf) = profile_p;
341}
342
343#if WITH_SCACHE_PBB
344
345/* Emit the "x-before" handler.
346 x-before is emitted before each insn (serial or parallel).
347 This is as opposed to x-after which is only emitted at the end of a group
348 of parallel insns. */
349
350static INLINE void
bb4e03e5 351@prefix@_emit_before (SIM_CPU *current_cpu, SCACHE *sc, PCADDR pc, int first_p)
c906108c
SS
352{
353 ARGBUF *abuf = &sc[0].argbuf;
bb4e03e5 354 const IDESC *id = & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_BEFORE];
c906108c
SS
355
356 abuf->fields.before.first_p = first_p;
bb4e03e5 357 @prefix@_fill_argbuf (current_cpu, abuf, id, pc, 0);
c906108c
SS
358 /* no need to set trace_p,profile_p */
359}
360
361/* Emit the "x-after" handler.
362 x-after is emitted after a serial insn or at the end of a group of
363 parallel insns. */
364
365static INLINE void
bb4e03e5 366@prefix@_emit_after (SIM_CPU *current_cpu, SCACHE *sc, PCADDR pc)
c906108c
SS
367{
368 ARGBUF *abuf = &sc[0].argbuf;
bb4e03e5 369 const IDESC *id = & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_AFTER];
c906108c 370
bb4e03e5 371 @prefix@_fill_argbuf (current_cpu, abuf, id, pc, 0);
c906108c
SS
372 /* no need to set trace_p,profile_p */
373}
374
375#endif /* WITH_SCACHE_PBB */
376
377EOF
378
379${SHELL} $infile support
380
381##########################################################################
382
383# Simple engine: fetch an instruction, execute the instruction.
384#
385# Instruction fields are not extracted into ARGBUF, they are extracted in
386# the semantic routines themselves. However, there is still a need to pass
387# and return misc. information to the semantic routines so we still use ARGBUF.
388# [One could certainly implement things differently and remove ARGBUF.
389# It's not clear this is necessarily always a win.]
390# ??? The use of the SCACHE struct is for consistency with the with-scache
391# case though it might be a source of confusion.
392
393if [ x$scache != xyes -a x$pbb != xyes ] ; then
394
395 cat << EOF
396
397#define FAST_P 0
398
399void
bb4e03e5 400@prefix@_engine_run_full (SIM_CPU *current_cpu)
c906108c
SS
401{
402#define FAST_P 0
403 SIM_DESC current_state = CPU_STATE (current_cpu);
404 /* ??? Use of SCACHE is a bit of a hack as we don't actually use the scache.
405 We do however use ARGBUF so for consistency with the other engine flavours
406 the SCACHE type is used. */
407 SCACHE cache[MAX_LIW_INSNS];
408 SCACHE *sc = &cache[0];
409
410EOF
411
53a5351d
JM
412case x$parallel in
413xread | xwrite)
414 cat << EOF
c906108c
SS
415 PAREXEC pbufs[MAX_PARALLEL_INSNS];
416 PAREXEC *par_exec;
417
418EOF
53a5351d
JM
419 ;;
420esac
c906108c
SS
421
422# Any initialization code before looping starts.
423# Note that this code may declare some locals.
424${SHELL} $infile init
425
96baa820 426if [ x$parallel = xread ] ; then
c906108c
SS
427 cat << EOF
428
96baa820 429#if defined (__GNUC__)
c906108c
SS
430 {
431 if (! CPU_IDESC_READ_INIT_P (current_cpu))
432 {
433/* ??? Later maybe paste read.c in when building mainloop.c. */
434#define DEFINE_LABELS
435#include "readx.c"
436 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
437 }
438 }
439#endif
440
441EOF
442fi
443
444cat << EOF
445
96baa820
JM
446 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
447 {
448#if WITH_SEM_SWITCH_FULL
449#if defined (__GNUC__)
c906108c
SS
450/* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
451#define DEFINE_LABELS
452#include "$switch"
c906108c 453#endif
96baa820 454#else
bb4e03e5 455 @prefix@_sem_init_idesc_table (current_cpu);
96baa820
JM
456#endif
457 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
458 }
c906108c
SS
459
460 do
461 {
462/* begin full-exec-simple */
463EOF
464
465${SHELL} $infile full-exec-simple
466
467cat << EOF
468/* end full-exec-simple */
469
470 ++ CPU_INSN_COUNT (current_cpu);
471 }
472 while (0 /*CPU_RUNNING_P (current_cpu)*/);
473}
474
475#undef FAST_P
476
477EOF
478
479####################################
480
481# Simple engine: fast version.
482# ??? A somewhat dubious effort, but for completeness' sake.
483
484if [ x$fast = xyes ] ; then
485
486 cat << EOF
487
488#define FAST_P 1
489
490FIXME: "fast simple version unimplemented, delete -fast arg to genmloop.sh."
491
492#undef FAST_P
493
494EOF
495
496fi # -fast
497
498fi # simple engine
499
500##########################################################################
501
96baa820
JM
502# Non-parallel scache engine: lookup insn in scache, fetch if missing,
503# then execute it.
c906108c 504
96baa820 505if [ x$scache = xyes -a x$parallel = xno ] ; then
c906108c
SS
506
507 cat << EOF
508
509static INLINE SCACHE *
bb4e03e5 510@prefix@_scache_lookup (SIM_CPU *current_cpu, PCADDR vpc, SCACHE *scache,
c906108c
SS
511 unsigned int hash_mask, int FAST_P)
512{
513 /* First step: look up current insn in hash table. */
514 SCACHE *sc = scache + SCACHE_HASH_PC (vpc, hash_mask);
515
516 /* If the entry isn't the one we want (cache miss),
517 fetch and decode the instruction. */
518 if (sc->argbuf.addr != vpc)
519 {
96baa820 520 if (! FAST_P)
c906108c
SS
521 PROFILE_COUNT_SCACHE_MISS (current_cpu);
522
523/* begin extract-scache */
524EOF
525
526${SHELL} $infile extract-scache
527
528cat << EOF
529/* end extract-scache */
530 }
96baa820 531 else if (! FAST_P)
c906108c
SS
532 {
533 PROFILE_COUNT_SCACHE_HIT (current_cpu);
534 /* Make core access statistics come out right.
535 The size is a guess, but it's currently not used either. */
536 PROFILE_COUNT_CORE (current_cpu, vpc, 2, exec_map);
537 }
538
539 return sc;
540}
541
542#define FAST_P 0
543
544void
bb4e03e5 545@prefix@_engine_run_full (SIM_CPU *current_cpu)
c906108c
SS
546{
547 SIM_DESC current_state = CPU_STATE (current_cpu);
548 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
549 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
550 SEM_PC vpc;
551
552EOF
553
96baa820
JM
554# Any initialization code before looping starts.
555# Note that this code may declare some locals.
556${SHELL} $infile init
557
558cat << EOF
559
560 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
561 {
562#if ! WITH_SEM_SWITCH_FULL
bb4e03e5 563 @prefix@_sem_init_idesc_table (current_cpu);
96baa820
JM
564#endif
565 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
566 }
567
568 vpc = GET_H_PC ();
569
570 do
571 {
572 SCACHE *sc;
573
bb4e03e5 574 sc = @prefix@_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
96baa820
JM
575
576/* begin full-exec-scache */
577EOF
578
579${SHELL} $infile full-exec-scache
580
581cat << EOF
582/* end full-exec-scache */
583
584 SET_H_PC (vpc);
585
586 ++ CPU_INSN_COUNT (current_cpu);
587 }
588 while (0 /*CPU_RUNNING_P (current_cpu)*/);
589}
590
591#undef FAST_P
592
593EOF
594
595####################################
596
597# Non-parallel scache engine: fast version.
598
599if [ x$fast = xyes ] ; then
600
601 cat << EOF
602
603#define FAST_P 1
604
605void
bb4e03e5 606@prefix@_engine_run_fast (SIM_CPU *current_cpu)
96baa820
JM
607{
608 SIM_DESC current_state = CPU_STATE (current_cpu);
609 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
610 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
611 SEM_PC vpc;
c906108c
SS
612
613EOF
c906108c
SS
614
615# Any initialization code before looping starts.
616# Note that this code may declare some locals.
617${SHELL} $infile init
618
96baa820 619cat << EOF
c906108c 620
96baa820
JM
621 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
622 {
623#if WITH_SEM_SWITCH_FAST
624#if defined (__GNUC__)
625/* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
626#define DEFINE_LABELS
627#include "$switch"
628#endif
629#else
bb4e03e5 630 @prefix@_semf_init_idesc_table (current_cpu);
96baa820
JM
631#endif
632 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
633 }
634
635 vpc = GET_H_PC ();
636
637 do
638 {
639 SCACHE *sc;
640
bb4e03e5 641 sc = @prefix@_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
96baa820
JM
642
643/* begin fast-exec-scache */
644EOF
645
646${SHELL} $infile fast-exec-scache
647
648cat << EOF
649/* end fast-exec-scache */
650
651 SET_H_PC (vpc);
652
653 ++ CPU_INSN_COUNT (current_cpu);
654 }
655 while (0 /*CPU_RUNNING_P (current_cpu)*/);
656}
657
658#undef FAST_P
659
660EOF
661
662fi # -fast
663
664fi # -scache && ! parallel
665
666##########################################################################
667
668# Parallel scache engine: lookup insn in scache, fetch if missing,
669# then execute it.
670# For the parallel case we give the target more flexibility.
671
672if [ x$scache = xyes -a x$parallel != xno ] ; then
673
674 cat << EOF
675
676static INLINE SCACHE *
bb4e03e5 677@prefix@_scache_lookup (SIM_CPU *current_cpu, PCADDR vpc, SCACHE *scache,
6426a772 678 unsigned int hash_mask, int FAST_P)
96baa820
JM
679{
680 /* First step: look up current insn in hash table. */
681 SCACHE *sc = scache + SCACHE_HASH_PC (vpc, hash_mask);
682
683 /* If the entry isn't the one we want (cache miss),
684 fetch and decode the instruction. */
685 if (sc->argbuf.addr != vpc)
686 {
687 if (! FAST_P)
688 PROFILE_COUNT_SCACHE_MISS (current_cpu);
689
6426a772 690#define SET_LAST_INSN_P(last_p) do { sc->last_insn_p = (last_p); } while (0)
96baa820
JM
691/* begin extract-scache */
692EOF
693
694${SHELL} $infile extract-scache
695
696cat << EOF
697/* end extract-scache */
698#undef SET_LAST_INSN_P
699 }
700 else if (! FAST_P)
701 {
702 PROFILE_COUNT_SCACHE_HIT (current_cpu);
703 /* Make core access statistics come out right.
704 The size is a guess, but it's currently not used either. */
705 PROFILE_COUNT_CORE (current_cpu, vpc, 2, exec_map);
706 }
707
708 return sc;
709}
710
711#define FAST_P 0
712
713void
bb4e03e5 714@prefix@_engine_run_full (SIM_CPU *current_cpu)
96baa820
JM
715{
716 SIM_DESC current_state = CPU_STATE (current_cpu);
717 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
718 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
719 SEM_PC vpc;
720
721EOF
722
723# Any initialization code before looping starts.
724# Note that this code may declare some locals.
725${SHELL} $infile init
726
727if [ x$parallel = xread ] ; then
728cat << EOF
729#if defined (__GNUC__)
c906108c
SS
730 {
731 if (! CPU_IDESC_READ_INIT_P (current_cpu))
732 {
733/* ??? Later maybe paste read.c in when building mainloop.c. */
734#define DEFINE_LABELS
735#include "readx.c"
736 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
737 }
738 }
739#endif
740
741EOF
742fi
743
744cat << EOF
745
96baa820
JM
746 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
747 {
748#if ! WITH_SEM_SWITCH_FULL
bb4e03e5 749 @prefix@_sem_init_idesc_table (current_cpu);
96baa820
JM
750#endif
751 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
752 }
753
c906108c
SS
754 vpc = GET_H_PC ();
755
756 do
757 {
c906108c
SS
758/* begin full-exec-scache */
759EOF
760
761${SHELL} $infile full-exec-scache
762
763cat << EOF
764/* end full-exec-scache */
c906108c
SS
765 }
766 while (0 /*CPU_RUNNING_P (current_cpu)*/);
767}
768
769#undef FAST_P
770
771EOF
772
773####################################
774
96baa820 775# Parallel scache engine: fast version.
c906108c
SS
776
777if [ x$fast = xyes ] ; then
778
779 cat << EOF
780
781#define FAST_P 1
782
783void
bb4e03e5 784@prefix@_engine_run_fast (SIM_CPU *current_cpu)
c906108c
SS
785{
786 SIM_DESC current_state = CPU_STATE (current_cpu);
787 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
788 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
789 SEM_PC vpc;
c906108c
SS
790 PAREXEC pbufs[MAX_PARALLEL_INSNS];
791 PAREXEC *par_exec;
792
793EOF
c906108c
SS
794
795# Any initialization code before looping starts.
796# Note that this code may declare some locals.
797${SHELL} $infile init
798
96baa820
JM
799if [ x$parallel = xread ] ; then
800cat << EOF
c906108c 801
96baa820 802#if defined (__GNUC__)
c906108c
SS
803 {
804 if (! CPU_IDESC_READ_INIT_P (current_cpu))
805 {
806/* ??? Later maybe paste read.c in when building mainloop.c. */
807#define DEFINE_LABELS
808#include "readx.c"
809 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
810 }
811 }
812#endif
813
814EOF
96baa820 815fi
c906108c
SS
816
817cat << EOF
818
96baa820
JM
819 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
820 {
821#if WITH_SEM_SWITCH_FAST
822#if defined (__GNUC__)
c906108c
SS
823/* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
824#define DEFINE_LABELS
825#include "$switch"
c906108c 826#endif
96baa820 827#else
bb4e03e5 828 @prefix@_semf_init_idesc_table (current_cpu);
96baa820
JM
829#endif
830 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
831 }
c906108c
SS
832
833 vpc = GET_H_PC ();
834
835 do
836 {
c906108c
SS
837/* begin fast-exec-scache */
838EOF
839
840${SHELL} $infile fast-exec-scache
841
842cat << EOF
843/* end fast-exec-scache */
c906108c
SS
844 }
845 while (0 /*CPU_RUNNING_P (current_cpu)*/);
846}
847
848#undef FAST_P
849
850EOF
851
852fi # -fast
853
96baa820 854fi # -scache && parallel
c906108c
SS
855
856##########################################################################
857
858# Compilation engine: lookup insn in scache, extract a pbb
859# (pseudo-basic-block) if missing, then execute the pbb.
860# A "pbb" is a sequence of insns up to the next cti insn or until
861# some prespecified maximum.
862# CTI: control transfer instruction.
863
864if [ x$pbb = xyes ] ; then
865
866 cat << EOF
867
868/* Record address of cti terminating a pbb. */
869#define SET_CTI_VPC(sc) do { _cti_sc = (sc); } while (0)
870/* Record number of [real] insns in pbb. */
871#define SET_INSN_COUNT(n) do { _insn_count = (n); } while (0)
872
873/* Fetch and extract a pseudo-basic-block.
874 FAST_P is non-zero if no tracing/profiling/etc. is wanted. */
875
876INLINE SEM_PC
bb4e03e5 877@prefix@_pbb_begin (SIM_CPU *current_cpu, int FAST_P)
c906108c
SS
878{
879 SEM_PC new_vpc;
880 PCADDR pc;
881 SCACHE *sc;
882 int max_insns = CPU_SCACHE_MAX_CHAIN_LENGTH (current_cpu);
883
884 pc = GET_H_PC ();
885
886 new_vpc = scache_lookup_or_alloc (current_cpu, pc, max_insns, &sc);
887 if (! new_vpc)
888 {
889 /* Leading '_' to avoid collision with mainloop.in. */
890 int _insn_count = 0;
891 SCACHE *orig_sc = sc;
892 SCACHE *_cti_sc = NULL;
893 int slice_insns = CPU_MAX_SLICE_INSNS (current_cpu);
894
895 /* First figure out how many instructions to compile.
896 MAX_INSNS is the size of the allocated buffer, which includes space
897 for before/after handlers if they're being used.
898 SLICE_INSNS is the maxinum number of real insns that can be
899 executed. Zero means "as many as we want". */
900 /* ??? max_insns is serving two incompatible roles.
901 1) Number of slots available in scache buffer.
902 2) Number of real insns to execute.
903 They're incompatible because there are virtual insns emitted too
904 (chain,cti-chain,before,after handlers). */
905
906 if (slice_insns == 1)
907 {
908 /* No need to worry about extra slots required for virtual insns
909 and parallel exec support because MAX_CHAIN_LENGTH is
910 guaranteed to be big enough to execute at least 1 insn! */
911 max_insns = 1;
912 }
913 else
914 {
915 /* Allow enough slop so that while compiling insns, if max_insns > 0
916 then there's guaranteed to be enough space to emit one real insn.
917 MAX_CHAIN_LENGTH is typically much longer than
918 the normal number of insns between cti's anyway. */
919 max_insns -= (1 /* one for the trailing chain insn */
920 + (FAST_P
921 ? 0
922 : (1 + MAX_PARALLEL_INSNS) /* before+after */)
923 + (MAX_PARALLEL_INSNS > 1
924 ? (MAX_PARALLEL_INSNS * 2)
925 : 0));
926
927 /* Account for before/after handlers. */
928 if (! FAST_P)
929 slice_insns *= 3;
930
931 if (slice_insns > 0
932 && slice_insns < max_insns)
933 max_insns = slice_insns;
934 }
935
936 new_vpc = sc;
937
938 /* SC,PC must be updated to point passed the last entry used.
939 SET_CTI_VPC must be called if pbb is terminated by a cti.
940 SET_INSN_COUNT must be called to record number of real insns in
941 pbb [could be computed by us of course, extra cpu but perhaps
942 negligible enough]. */
943
944/* begin extract-pbb */
945EOF
946
947${SHELL} $infile extract-pbb
948
949cat << EOF
950/* end extract-pbb */
951
952 /* The last one is a pseudo-insn to link to the next chain.
953 It is also used to record the insn count for this chain. */
954 {
955 const IDESC *id;
956
957 /* Was pbb terminated by a cti? */
958 if (_cti_sc)
959 {
bb4e03e5 960 id = & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_CTI_CHAIN];
c906108c
SS
961 }
962 else
963 {
bb4e03e5 964 id = & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_CHAIN];
c906108c
SS
965 }
966 SEM_SET_CODE (&sc->argbuf, id, FAST_P);
967 sc->argbuf.idesc = id;
968 sc->argbuf.addr = pc;
969 sc->argbuf.fields.chain.insn_count = _insn_count;
970 sc->argbuf.fields.chain.next = 0;
96baa820 971 sc->argbuf.fields.chain.branch_target = 0;
c906108c
SS
972 ++sc;
973 }
974
085dd6e6
JM
975 /* Update the pointer to the next free entry, may not have used as
976 many entries as was asked for. */
c906108c
SS
977 CPU_SCACHE_NEXT_FREE (current_cpu) = sc;
978 /* Record length of chain if profiling.
979 This includes virtual insns since they count against
980 max_insns too. */
981 if (! FAST_P)
982 PROFILE_COUNT_SCACHE_CHAIN_LENGTH (current_cpu, sc - orig_sc);
983 }
984
985 return new_vpc;
986}
987
988/* Chain to the next block from a non-cti terminated previous block. */
989
990INLINE SEM_PC
bb4e03e5 991@prefix@_pbb_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg)
c906108c
SS
992{
993 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
994
995 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
996
997 SET_H_PC (abuf->addr);
998
999 /* If not running forever, exit back to main loop. */
1000 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0
1001 /* Also exit back to main loop if there's an event.
1002 Note that if CPU_MAX_SLICE_INSNS != 1, events won't get processed
1003 at the "right" time, but then that was what was asked for.
1004 There is no silver bullet for simulator engines.
1005 ??? Clearly this needs a cleaner interface.
1006 At present it's just so Ctrl-C works. */
1007 || STATE_EVENTS (CPU_STATE (current_cpu))->work_pending)
1008 CPU_RUNNING_P (current_cpu) = 0;
1009
1010 /* If chained to next block, go straight to it. */
1011 if (abuf->fields.chain.next)
1012 return abuf->fields.chain.next;
1013 /* See if next block has already been compiled. */
1014 abuf->fields.chain.next = scache_lookup (current_cpu, abuf->addr);
1015 if (abuf->fields.chain.next)
1016 return abuf->fields.chain.next;
1017 /* Nope, so next insn is a virtual insn to invoke the compiler
1018 (begin a pbb). */
1019 return CPU_SCACHE_PBB_BEGIN (current_cpu);
1020}
1021
1022/* Chain to the next block from a cti terminated previous block.
96baa820
JM
1023 BR_TYPE indicates whether the branch was taken and whether we can cache
1024 the vpc of the branch target.
c906108c 1025 NEW_PC is the target's branch address, and is only valid if
96baa820 1026 BR_TYPE != SEM_BRANCH_UNTAKEN. */
c906108c
SS
1027
1028INLINE SEM_PC
bb4e03e5 1029@prefix@_pbb_cti_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg,
96baa820 1030 SEM_BRANCH_TYPE br_type, PCADDR new_pc)
c906108c 1031{
96baa820
JM
1032 SEM_PC *new_vpc_ptr;
1033
c906108c
SS
1034 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
1035
1036 /* If not running forever, exit back to main loop. */
1037 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0
1038 /* Also exit back to main loop if there's an event.
1039 Note that if CPU_MAX_SLICE_INSNS != 1, events won't get processed
1040 at the "right" time, but then that was what was asked for.
1041 There is no silver bullet for simulator engines.
1042 ??? Clearly this needs a cleaner interface.
1043 At present it's just so Ctrl-C works. */
1044 || STATE_EVENTS (CPU_STATE (current_cpu))->work_pending)
1045 CPU_RUNNING_P (current_cpu) = 0;
1046
1047 /* Restart compiler if we branched to an uncacheable address
1048 (e.g. "j reg"). */
96baa820 1049 if (br_type == SEM_BRANCH_UNCACHEABLE)
c906108c
SS
1050 {
1051 SET_H_PC (new_pc);
1052 return CPU_SCACHE_PBB_BEGIN (current_cpu);
1053 }
1054
1055 /* If branch wasn't taken, update the pc and set BR_ADDR_PTR to our
1056 next chain ptr. */
96baa820 1057 if (br_type == SEM_BRANCH_UNTAKEN)
c906108c 1058 {
085dd6e6 1059 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
96baa820
JM
1060 new_pc = abuf->addr;
1061 SET_H_PC (new_pc);
c906108c
SS
1062 new_vpc_ptr = &abuf->fields.chain.next;
1063 }
1064 else
1065 {
96baa820 1066 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
c906108c 1067 SET_H_PC (new_pc);
96baa820 1068 new_vpc_ptr = &abuf->fields.chain.branch_target;
c906108c
SS
1069 }
1070
1071 /* If chained to next block, go straight to it. */
1072 if (*new_vpc_ptr)
1073 return *new_vpc_ptr;
1074 /* See if next block has already been compiled. */
96baa820 1075 *new_vpc_ptr = scache_lookup (current_cpu, new_pc);
c906108c
SS
1076 if (*new_vpc_ptr)
1077 return *new_vpc_ptr;
1078 /* Nope, so next insn is a virtual insn to invoke the compiler
1079 (begin a pbb). */
1080 return CPU_SCACHE_PBB_BEGIN (current_cpu);
1081}
1082
1083/* x-before handler.
1084 This is called before each insn. */
1085
1086void
bb4e03e5 1087@prefix@_pbb_before (SIM_CPU *current_cpu, SCACHE *sc)
c906108c
SS
1088{
1089 SEM_ARG sem_arg = sc;
1090 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
1091 int first_p = abuf->fields.before.first_p;
1092 const ARGBUF *cur_abuf = SEM_ARGBUF (sc + 1);
1093 const IDESC *cur_idesc = cur_abuf->idesc;
1094 PCADDR pc = cur_abuf->addr;
1095
1096 if (ARGBUF_PROFILE_P (cur_abuf))
1097 PROFILE_COUNT_INSN (current_cpu, pc, cur_idesc->num);
1098
1099 /* If this isn't the first insn, finish up the previous one. */
1100
1101 if (! first_p)
1102 {
1103 if (PROFILE_MODEL_P (current_cpu))
1104 {
1105 const SEM_ARG prev_sem_arg = sc - 1;
1106 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
1107 const IDESC *prev_idesc = prev_abuf->idesc;
1108 int cycles;
1109
1110 /* ??? May want to measure all insns if doing insn tracing. */
1111 if (ARGBUF_PROFILE_P (prev_abuf))
1112 {
1113 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
bb4e03e5 1114 @prefix@_model_insn_after (current_cpu, 0 /*last_p*/, cycles);
c906108c
SS
1115 }
1116 }
1117
db7858e2 1118 CGEN_TRACE_INSN_FINI (current_cpu, cur_abuf, 0 /*last_p*/);
c906108c
SS
1119 }
1120
1121 /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
1122 if (PROFILE_MODEL_P (current_cpu)
1123 && ARGBUF_PROFILE_P (cur_abuf))
bb4e03e5 1124 @prefix@_model_insn_before (current_cpu, first_p);
c906108c 1125
db7858e2
MF
1126 CGEN_TRACE_INSN_INIT (current_cpu, cur_abuf, first_p);
1127 CGEN_TRACE_INSN (current_cpu, cur_idesc->idata, cur_abuf, pc);
c906108c
SS
1128}
1129
1130/* x-after handler.
1131 This is called after a serial insn or at the end of a group of parallel
1132 insns. */
1133
1134void
bb4e03e5 1135@prefix@_pbb_after (SIM_CPU *current_cpu, SCACHE *sc)
c906108c
SS
1136{
1137 SEM_ARG sem_arg = sc;
1138 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
1139 const SEM_ARG prev_sem_arg = sc - 1;
1140 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
1141
1142 /* ??? May want to measure all insns if doing insn tracing. */
1143 if (PROFILE_MODEL_P (current_cpu)
1144 && ARGBUF_PROFILE_P (prev_abuf))
1145 {
1146 const IDESC *prev_idesc = prev_abuf->idesc;
1147 int cycles;
1148
1149 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
bb4e03e5 1150 @prefix@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
c906108c 1151 }
db7858e2 1152 CGEN_TRACE_INSN_FINI (current_cpu, prev_abuf, 1 /*last_p*/);
c906108c
SS
1153}
1154
1155#define FAST_P 0
1156
1157void
bb4e03e5 1158@prefix@_engine_run_full (SIM_CPU *current_cpu)
c906108c
SS
1159{
1160 SIM_DESC current_state = CPU_STATE (current_cpu);
1161 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
1162 /* virtual program counter */
1163 SEM_PC vpc;
1164#if WITH_SEM_SWITCH_FULL
1165 /* For communication between cti's and cti-chain. */
96baa820 1166 SEM_BRANCH_TYPE pbb_br_type;
c906108c 1167 PCADDR pbb_br_npc;
c906108c
SS
1168#endif
1169
1170EOF
1171
53a5351d
JM
1172case x$parallel in
1173xread | xwrite)
1174 cat << EOF
c906108c
SS
1175 PAREXEC pbufs[MAX_PARALLEL_INSNS];
1176 PAREXEC *par_exec = &pbufs[0];
1177
1178EOF
53a5351d
JM
1179 ;;
1180esac
c906108c
SS
1181
1182# Any initialization code before looping starts.
1183# Note that this code may declare some locals.
1184${SHELL} $infile init
1185
1186cat << EOF
1187
1188 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
1189 {
1190 /* ??? 'twould be nice to move this up a level and only call it once.
1191 On the other hand, in the "let's go fast" case the test is only done
1192 once per pbb (since we only return to the main loop at the end of
1193 a pbb). And in the "let's run until we're done" case we don't return
1194 until the program exits. */
1195
96baa820
JM
1196#if WITH_SEM_SWITCH_FULL
1197#if defined (__GNUC__)
c906108c
SS
1198/* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
1199#define DEFINE_LABELS
1200#include "$switch"
96baa820
JM
1201#endif
1202#else
bb4e03e5 1203 @prefix@_sem_init_idesc_table (current_cpu);
c906108c
SS
1204#endif
1205
1206 /* Initialize the "begin (compile) a pbb" virtual insn. */
1207 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
1208 SEM_SET_FULL_CODE (SEM_ARGBUF (vpc),
bb4e03e5
BE
1209 & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_BEGIN]);
1210 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_BEGIN];
c906108c
SS
1211
1212 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
1213 }
1214
1215 CPU_RUNNING_P (current_cpu) = 1;
1216 /* ??? In the case where we're returning to the main loop after every
1217 pbb we don't want to call pbb_begin each time (which hashes on the pc
1218 and does a table lookup). A way to speed this up is to save vpc
1219 between calls. */
bb4e03e5 1220 vpc = @prefix@_pbb_begin (current_cpu, FAST_P);
c906108c
SS
1221
1222 do
1223 {
1224/* begin full-exec-pbb */
1225EOF
1226
1227${SHELL} $infile full-exec-pbb
1228
1229cat << EOF
1230/* end full-exec-pbb */
1231 }
1232 while (CPU_RUNNING_P (current_cpu));
1233}
1234
1235#undef FAST_P
1236
1237EOF
1238
1239####################################
1240
1241# Compile engine: fast version.
1242
1243if [ x$fast = xyes ] ; then
1244
1245 cat << EOF
1246
1247#define FAST_P 1
1248
1249void
bb4e03e5 1250@prefix@_engine_run_fast (SIM_CPU *current_cpu)
c906108c
SS
1251{
1252 SIM_DESC current_state = CPU_STATE (current_cpu);
1253 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
1254 /* virtual program counter */
1255 SEM_PC vpc;
1256#if WITH_SEM_SWITCH_FAST
1257 /* For communication between cti's and cti-chain. */
96baa820 1258 SEM_BRANCH_TYPE pbb_br_type;
c906108c 1259 PCADDR pbb_br_npc;
c906108c
SS
1260#endif
1261
1262EOF
1263
53a5351d
JM
1264case x$parallel in
1265xread | xwrite)
1266 cat << EOF
c906108c
SS
1267 PAREXEC pbufs[MAX_PARALLEL_INSNS];
1268 PAREXEC *par_exec = &pbufs[0];
1269
1270EOF
53a5351d
JM
1271 ;;
1272esac
c906108c
SS
1273
1274# Any initialization code before looping starts.
1275# Note that this code may declare some locals.
1276${SHELL} $infile init
1277
1278cat << EOF
1279
1280 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
1281 {
1282 /* ??? 'twould be nice to move this up a level and only call it once.
1283 On the other hand, in the "let's go fast" case the test is only done
1284 once per pbb (since we only return to the main loop at the end of
1285 a pbb). And in the "let's run until we're done" case we don't return
1286 until the program exits. */
1287
96baa820
JM
1288#if WITH_SEM_SWITCH_FAST
1289#if defined (__GNUC__)
c906108c
SS
1290/* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
1291#define DEFINE_LABELS
1292#include "$switch"
1293#endif
96baa820 1294#else
bb4e03e5 1295 @prefix@_semf_init_idesc_table (current_cpu);
96baa820 1296#endif
c906108c
SS
1297
1298 /* Initialize the "begin (compile) a pbb" virtual insn. */
1299 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
1300 SEM_SET_FAST_CODE (SEM_ARGBUF (vpc),
bb4e03e5
BE
1301 & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_BEGIN]);
1302 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [@PREFIX@_INSN_X_BEGIN];
c906108c
SS
1303
1304 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
1305 }
1306
1307 CPU_RUNNING_P (current_cpu) = 1;
1308 /* ??? In the case where we're returning to the main loop after every
1309 pbb we don't want to call pbb_begin each time (which hashes on the pc
1310 and does a table lookup). A way to speed this up is to save vpc
1311 between calls. */
bb4e03e5 1312 vpc = @prefix@_pbb_begin (current_cpu, FAST_P);
c906108c
SS
1313
1314 do
1315 {
1316/* begin fast-exec-pbb */
1317EOF
1318
1319${SHELL} $infile fast-exec-pbb
1320
1321cat << EOF
1322/* end fast-exec-pbb */
1323 }
1324 while (CPU_RUNNING_P (current_cpu));
1325}
1326
1327#undef FAST_P
1328
1329EOF
1330fi # -fast
1331
1332fi # -pbb
1333
bb4e03e5
BE
1334# Expand @..@ macros appearing in tmp-mloop-{pid}.cin.
1335sed \
1336 -e "s/@cpu@/$cpu/g" -e "s/@CPU@/$CPU/g" \
1337 -e "s/@prefix@/$prefix/g" -e "s/@PREFIX@/$PREFIX/g" < tmp-mloop-$$.cin > mloop${outsuffix}.cin
c906108c 1338rc=$?
bb4e03e5 1339rm -f tmp-mloop-$$.cin
c906108c
SS
1340
1341exit $rc
This page took 1.00945 seconds and 4 git commands to generate.