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