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