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