1 # Generate the main loop of the simulator.
2 # Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3 # Contributed by Cygnus Support.
5 # This file is part of the GNU simulators.
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)
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.
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.
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.
26 # ??? Rename mloop.c to eng.c?
27 # ??? Rename mainloop.in to engine.in?
28 # ??? Rename this file to genengine.sh?
30 # Syntax: genmloop.sh [options]
35 # - specify single cpu or multiple cpus (number specifyable at runtime),
36 # maximum number is a configuration parameter
39 # -fast: include support for fast execution in addition to full featured mode
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
50 # -full-switch: same as -fast but for full featured version of -switch
51 # Only needed if -fast present.
53 # -simple: simple execution engine (the default)
55 # This engine fetches and executes one instruction at a time.
56 # ??? The implementation is currently slower than necessary for
57 # simplicity. Instead of storing extract insn fields in ARGBUF,
58 # they should just be extracted from the insn when needed.
60 # -scache: use the scache to speed things up (not always a win)
62 # This engine caches the extracted instruction before executing it.
63 # When executing instructions they are first looked up in the scache.
65 # -pbb: same as -scache but extract a (pseudo-) basic block at a time
67 # This engine is basically identical to the scache version except that
68 # extraction is done a pseudo-basic-block at a time and the address of
69 # the scache entry of a branch target is recorded as well.
70 # Additional speedups are then possible by defering Ctrl-C checking
71 # to the end of basic blocks and by threading the insns together.
72 # We call them pseudo-basic-block's instead of just basic-blocks because
73 # they're not necessarily basic-blocks, though normally are.
75 # -parallel: cpu can execute multiple instructions parallely
77 # This option is specified in addition to -simple, -scache, -pbb.
79 # -switch file: specify file containing semantics implemented as a switch()
83 # Specify the cpu family name.
85 # -infile <input-file>
87 # Specify the mainloop.in input file.
89 # Only one of -scache/-pbb may be selected.
90 # -simple is the default.
95 # - build mainloop.in from .cpu file
111 -multi) type=multi
;;
114 -full-switch) full_switch
=yes ;;
116 -scache) scache
=yes ;;
119 -parallel) parallel
=yes ;;
120 -switch) shift ; switch
=$1 ;;
121 -cpu) shift ; cpu
=$1 ;;
122 -infile) shift ; infile
=$1 ;;
123 *) echo "unknown option: $1" >&2 ; exit 1 ;;
128 # Argument validation.
130 if [ x
$scache = xyes
-a x
$pbb = xyes
] ; then
131 echo "only one of -scache and -pbb may be selected" >&2
135 if [ "x$cpu" = xunknown
] ; then
136 echo "cpu family not specified" >&2
140 if [ "x$infile" = x
] ; then
141 echo "mainloop.in not specified" >&2
145 lowercase
='abcdefghijklmnopqrstuvwxyz'
146 uppercase
='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
147 CPU
=`echo ${cpu} | tr "${lowercase}" "${uppercase}"`
149 ##########################################################################
154 echo "/* engine configuration for ${cpu} */"
157 echo "/* WITH_FAST: non-zero if a fast version of the engine is available"
158 echo " in addition to the full-featured version. */"
159 if [ x
$fast = xyes
] ; then
160 echo "#define WITH_FAST 1"
162 echo "#define WITH_FAST 0"
166 echo "/* WITH_SCACHE_PBB_${CPU}: non-zero if the pbb engine was selected. */"
167 if [ x
$pbb = xyes
] ; then
168 echo "#define WITH_SCACHE_PBB_${CPU} 1"
170 echo "#define WITH_SCACHE_PBB_${CPU} 0"
174 echo "/* HAVE_PARALLEL_EXEC: defined if cpu can parallelly execute > 1 insn. */"
175 if [ x
$parallel = xyes
] ; then
176 echo "#define HAVE_PARALLEL_EXEC"
178 echo "#undef HAVE_PARALLEL_EXEC"
181 if [ "x$switch" != x
] ; then
183 echo "/* WITH_SEM_SWITCH_FULL: non-zero if full-featured engine is"
184 echo " implemented as a switch(). */"
185 if [ x
$fast != xyes
-o x
$full_switch = xyes
] ; then
186 echo "#define WITH_SEM_SWITCH_FULL 1"
188 echo "#define WITH_SEM_SWITCH_FULL 0"
191 echo "/* WITH_SEM_SWITCH_FAST: non-zero if fast engine is"
192 echo " implemented as a switch(). */"
193 if [ x
$fast = xyes
] ; then
194 echo "#define WITH_SEM_SWITCH_FAST 1"
196 echo "#define WITH_SEM_SWITCH_FAST 0"
200 ##########################################################################
202 rm -f tmp-mloop.cin mloop.cin
205 # We use @cpu@ instead of ${cpu} because we still want to run sed to handle
206 # transformation of @cpu@ for mainloop.in.
209 /* This file is generated by the genmloop script. DO NOT EDIT! */
211 /* Enable switch() support in cgen headers. */
212 #define SEM_IN_SWITCH
215 #define WANT_CPU_${CPU}
217 #include "sim-main.h"
219 #include "cgen-mem.h"
220 #include "cgen-ops.h"
223 #include "sim-assert.h"
227 ${SHELL} $infile support
229 ##########################################################################
231 # Simple engine: fetch an instruction, execute the instruction.
233 if [ x
$scache != xyes
-a x
$pbb != xyes
] ; then
240 ${cpu}_engine_run_full (SIM_CPU *current_cpu)
243 SIM_DESC current_state = CPU_STATE (current_cpu);
244 SCACHE cache[MAX_LIW_INSNS];
245 SCACHE *sc = &cache[0];
249 if [ x
$parallel = xyes
] ; then
251 PAREXEC pbufs[MAX_PARALLEL_INSNS];
257 # Any initialization code before looping starts.
258 # Note that this code may declare some locals.
259 ${SHELL} $infile init
261 if [ x
$parallel = xyes
] ; then
264 #if defined (HAVE_PARALLEL_EXEC) && defined (__GNUC__)
266 if (! CPU_IDESC_READ_INIT_P (current_cpu))
268 /* ??? Later maybe paste read.c in when building mainloop.c. */
269 #define DEFINE_LABELS
271 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
283 /* begin full-{extract,exec}-simple */
286 ${SHELL} $infile extract-simple
288 ${SHELL} $infile full-exec-simple
291 /* end full-{extract,exec}-simple */
293 ++ CPU_INSN_COUNT (current_cpu);
295 while (0 /*CPU_RUNNING_P (current_cpu)*/);
303 ####################################
305 # Simple engine: fast version.
306 # ??? A somewhat dubious effort, but for completeness' sake.
308 if [ x
$fast = xyes
] ; then
324 ##########################################################################
326 # Scache engine: lookup insn in scache, fetch if missing, then execute it.
328 if [ x
$scache = xyes
] ; then
332 static INLINE SCACHE *
333 ${cpu}_scache_lookup (SIM_CPU *current_cpu, SCACHE *scache,
334 unsigned int hash_mask, int FAST_P)
336 /* First step: look up current insn in hash table. */
338 SCACHE *sc = scache + SCACHE_HASH_PC (pc, hash_mask);
340 /* If the entry isn't the one we want (cache miss),
341 fetch and decode the instruction. */
342 if (sc->argbuf.addr != pc)
347 PROFILE_COUNT_SCACHE_MISS (current_cpu);
349 /* begin extract-scache */
352 ${SHELL} $infile extract-scache
355 /* end extract-scache */
359 PROFILE_COUNT_SCACHE_HIT (current_cpu);
360 /* Make core access statistics come out right.
361 The size is a guess, but it's currently not used either. */
362 PROFILE_COUNT_CORE (current_cpu, pc, 2, exec_map);
369 ${cpu}_engine_run_full (SIM_CPU *current_cpu)
371 SIM_DESC current_state = CPU_STATE (current_cpu);
372 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
373 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
377 if [ x
$parallel = xyes
] ; then
379 PAREXEC pbufs[MAX_PARALLEL_INSNS];
385 # Any initialization code before looping starts.
386 # Note that this code may declare some locals.
387 ${SHELL} $infile init
389 if [ x
$parallel = xyes
] ; then
392 #if defined (HAVE_PARALLEL_EXEC) && defined (__GNUC__)
394 if (! CPU_IDESC_READ_INIT_P (current_cpu))
396 /* ??? Later maybe paste read.c in when building mainloop.c. */
397 #define DEFINE_LABELS
399 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
414 sc = ${cpu}_scache_lookup (current_cpu, scache, hash_mask, FAST_P);
416 /* begin full-exec-scache */
419 ${SHELL} $infile full-exec-scache
422 /* end full-exec-scache */
426 ++ CPU_INSN_COUNT (current_cpu);
428 while (0 /*CPU_RUNNING_P (current_cpu)*/);
435 ####################################
437 # Scache engine: fast version.
439 if [ x
$fast = xyes
] ; then
446 ${cpu}_engine_run_fast (SIM_CPU *current_cpu)
448 SIM_DESC current_state = CPU_STATE (current_cpu);
449 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
450 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
454 if [ x
$parallel = xyes
] ; then
456 PAREXEC pbufs[MAX_PARALLEL_INSNS];
462 # Any initialization code before looping starts.
463 # Note that this code may declare some locals.
464 ${SHELL} $infile init
466 if [ x
$parallel = xyes
] ; then
469 #if defined (HAVE_PARALLEL_EXEC) && defined (__GNUC__)
471 if (! CPU_IDESC_READ_INIT_P (current_cpu))
473 /* ??? Later maybe paste read.c in when building mainloop.c. */
474 #define DEFINE_LABELS
476 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
486 #if WITH_SEM_SWITCH_FAST && defined (__GNUC__)
488 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
490 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
491 #define DEFINE_LABELS
493 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
503 sc = ${cpu}_scache_lookup (current_cpu, scache, hash_mask, FAST_P);
505 /* begin fast-exec-scache */
508 ${SHELL} $infile fast-exec-scache
511 /* end fast-exec-scache */
515 ++ CPU_INSN_COUNT (current_cpu);
517 while (0 /*CPU_RUNNING_P (current_cpu)*/);
528 ##########################################################################
530 # Compilation engine: lookup insn in scache, extract a pbb
531 # (pseudo-basic-block) if missing, then execute the pbb.
532 # A "pbb" is a sequence of insns up to the next cti insn or until
533 # some prespecified maximum.
534 # CTI: control transfer instruction.
536 if [ x
$pbb = xyes
] ; then
540 /* Record address of cti terminating a pbb. */
541 #define SET_CTI_VPC(sc) do { cti_sc = (sc); } while (0)
542 /* Record number of [real] insns in pbb. */
543 #define SET_INSN_COUNT(n) do { insn_count = (n); } while (0)
545 /* Fetch and extract a pseudo-basic-block.
546 FAST_P is non-zero if no tracing/profiling/etc. is wanted. */
549 ${cpu}_pbb_begin (SIM_CPU *current_cpu, int FAST_P)
554 int max_insns = CPU_SCACHE_MAX_CHAIN_LENGTH (current_cpu);
558 new_vpc = scache_lookup_or_alloc (current_cpu, pc, max_insns, &sc);
562 SCACHE *orig_sc = sc;
563 SCACHE *cti_sc = NULL;
564 int slice_insns = CPU_MAX_SLICE_INSNS (current_cpu);
566 /* First figure out how many instructions to compile.
567 MAX_INSNS is the size of the allocated buffer, which includes space
568 for before/after handlers if they're being used.
569 SLICE_INSNS is the maxinum number of real insns that can be
570 executed. Zero means "as many as we want". */
571 /* ??? max_insns is serving two incompatible roles.
572 1) Number of slots available in scache buffer.
573 2) Number of real insns to execute.
574 They're incompatible because there are virtual insns emitted too
575 (chain,cti-chain,before,after handlers). */
577 if (slice_insns == 1)
579 /* No need to worry about extra slots required for virtual insns
580 and parallel exec support because MAX_CHAIN_LENGTH is
581 guaranteed to be big enough to execute at least 1 insn! */
586 /* Allow enough slop so that while compiling insns, if max_insns > 0
587 then there's guaranteed to be enough space to emit one real insn.
588 MAX_CHAIN_LENGTH is typically much longer than
589 the normal number of insns between cti's anyway. */
590 max_insns -= (1 /* one for the trailing chain insn */
593 : (1 + MAX_PARALLEL_INSNS) /* before+after */)
594 + (MAX_PARALLEL_INSNS > 1
595 ? (MAX_PARALLEL_INSNS * 2)
598 /* Account for before/after handlers. */
603 && slice_insns < max_insns)
604 max_insns = slice_insns;
609 /* SC,PC must be updated to point passed the last entry used.
610 SET_CTI_VPC must be called if pbb is terminated by a cti.
611 SET_INSN_COUNT must be called to record number of real insns in
612 pbb [could be computed by us of course, extra cpu but perhaps
613 negligible enough]. */
615 /* begin extract-pbb */
618 ${SHELL} $infile extract-pbb
621 /* end extract-pbb */
623 /* The last one is a pseudo-insn to link to the next chain.
624 It is also used to record the insn count for this chain. */
628 /* Was pbb terminated by a cti? */
631 id = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_CTI_CHAIN];
635 id = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_CHAIN];
637 SEM_SET_CODE (&sc->argbuf, id, FAST_P);
638 sc->argbuf.idesc = id;
639 sc->argbuf.addr = pc;
640 sc->argbuf.fields.chain.insn_count = insn_count;
641 sc->argbuf.fields.chain.next = 0;
645 /* Update the pointer to the next free entry. */
646 CPU_SCACHE_NEXT_FREE (current_cpu) = sc;
647 /* Record length of chain if profiling.
648 This includes virtual insns since they count against
651 PROFILE_COUNT_SCACHE_CHAIN_LENGTH (current_cpu, sc - orig_sc);
657 /* Chain to the next block from a non-cti terminated previous block. */
660 ${cpu}_pbb_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg)
662 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
664 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
666 SET_H_PC (abuf->addr);
668 /* If not running forever, exit back to main loop. */
669 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0)
670 CPU_RUNNING_P (current_cpu) = 0;
672 /* If chained to next block, go straight to it. */
673 if (abuf->fields.chain.next)
674 return abuf->fields.chain.next;
675 /* See if next block has already been compiled. */
676 abuf->fields.chain.next = scache_lookup (current_cpu, abuf->addr);
677 if (abuf->fields.chain.next)
678 return abuf->fields.chain.next;
679 /* Nope, so next insn is a virtual insn to invoke the compiler
681 return CPU_SCACHE_PBB_BEGIN (current_cpu);
684 /* Chain to the next block from a cti terminated previous block.
685 NEW_VPC_PTR is one of SEM_BRANCH_UNTAKEN, SEM_BRANCH_UNCACHEABLE, or
686 a pointer to a location containing the SEM_PC of the branch's address.
687 NEW_PC is the target's branch address, and is only valid if
688 NEW_VPC_PTR != SEM_BRANCH_UNTAKEN. */
691 ${cpu}_pbb_cti_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg,
692 SEM_PC *new_vpc_ptr, PCADDR new_pc)
696 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
698 /* If not running forever, exit back to main loop. */
699 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0)
700 CPU_RUNNING_P (current_cpu) = 0;
702 /* Restart compiler if we branched to an uncacheable address
704 if (new_vpc_ptr == SEM_BRANCH_UNCACHEABLE)
707 return CPU_SCACHE_PBB_BEGIN (current_cpu);
710 /* If branch wasn't taken, update the pc and set BR_ADDR_PTR to our
712 if (new_vpc_ptr == SEM_BRANCH_UNTAKEN)
714 abuf = SEM_ARGBUF (sem_arg);
715 SET_H_PC (abuf->addr);
716 new_vpc_ptr = &abuf->fields.chain.next;
723 /* If chained to next block, go straight to it. */
726 /* See if next block has already been compiled. */
727 *new_vpc_ptr = scache_lookup (current_cpu, GET_H_PC ());
730 /* Nope, so next insn is a virtual insn to invoke the compiler
732 return CPU_SCACHE_PBB_BEGIN (current_cpu);
736 This is called before each insn. */
739 ${cpu}_pbb_before (SIM_CPU *current_cpu, SCACHE *sc)
741 SEM_ARG sem_arg = sc;
742 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
743 int first_p = abuf->fields.before.first_p;
744 const ARGBUF *cur_abuf = SEM_ARGBUF (sc + 1);
745 const IDESC *cur_idesc = cur_abuf->idesc;
746 PCADDR pc = cur_abuf->addr;
748 PROFILE_COUNT_INSN (current_cpu, pc, cur_idesc->num);
750 /* If this isn't the first insn, finish up the previous one. */
754 if (PROFILE_MODEL_P (current_cpu))
756 const SEM_ARG prev_sem_arg = sc - 1;
757 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
758 const IDESC *prev_idesc = prev_abuf->idesc;
761 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
762 ${cpu}_model_insn_after (current_cpu, 0 /*last_p*/, cycles);
765 TRACE_INSN_FINI (current_cpu, 0 /*last_p*/);
768 /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
769 if (PROFILE_MODEL_P (current_cpu))
770 ${cpu}_model_insn_before (current_cpu, first_p);
772 TRACE_INSN_INIT (current_cpu, first_p);
773 TRACE_INSN (current_cpu, cur_idesc->opcode, cur_abuf, cur_abuf->addr);
777 This is called after a serial insn or at the end of a group of parallel
781 ${cpu}_pbb_after (SIM_CPU *current_cpu, SCACHE *sc)
783 SEM_ARG sem_arg = sc;
784 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
786 if (PROFILE_MODEL_P (current_cpu))
788 const SEM_ARG prev_sem_arg = sc - 1;
789 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
790 const IDESC *prev_idesc = prev_abuf->idesc;
793 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
794 ${cpu}_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
796 TRACE_INSN_FINI (current_cpu, 1 /*last_p*/);
802 ${cpu}_engine_run_full (SIM_CPU *current_cpu)
804 SIM_DESC current_state = CPU_STATE (current_cpu);
805 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
806 /* virtual program counter */
808 #if WITH_SEM_SWITCH_FULL
809 /* For communication between cti's and cti-chain. */
811 SEM_PC *pbb_br_npc_ptr;
816 if [ x
$parallel = xyes
] ; then
818 PAREXEC pbufs[MAX_PARALLEL_INSNS];
819 PAREXEC *par_exec = &pbufs[0];
824 # Any initialization code before looping starts.
825 # Note that this code may declare some locals.
826 ${SHELL} $infile init
830 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
832 /* ??? 'twould be nice to move this up a level and only call it once.
833 On the other hand, in the "let's go fast" case the test is only done
834 once per pbb (since we only return to the main loop at the end of
835 a pbb). And in the "let's run until we're done" case we don't return
836 until the program exits. */
838 #if WITH_SEM_SWITCH_FULL && defined (__GNUC__)
839 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
840 #define DEFINE_LABELS
844 /* Initialize the "begin (compile) a pbb" virtual insn. */
845 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
846 SEM_SET_FULL_CODE (SEM_ARGBUF (vpc),
847 & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN]);
848 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN];
850 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
853 CPU_RUNNING_P (current_cpu) = 1;
854 /* ??? In the case where we're returning to the main loop after every
855 pbb we don't want to call pbb_begin each time (which hashes on the pc
856 and does a table lookup). A way to speed this up is to save vpc
858 vpc = ${cpu}_pbb_begin (current_cpu, FAST_P);
862 /* begin full-exec-pbb */
865 ${SHELL} $infile full-exec-pbb
868 /* end full-exec-pbb */
870 while (CPU_RUNNING_P (current_cpu));
877 ####################################
879 # Compile engine: fast version.
881 if [ x
$fast = xyes
] ; then
888 ${cpu}_engine_run_fast (SIM_CPU *current_cpu)
890 SIM_DESC current_state = CPU_STATE (current_cpu);
891 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
892 /* virtual program counter */
894 #if WITH_SEM_SWITCH_FAST
895 /* For communication between cti's and cti-chain. */
897 SEM_PC *pbb_br_npc_ptr;
902 if [ x
$parallel = xyes
] ; then
904 PAREXEC pbufs[MAX_PARALLEL_INSNS];
905 PAREXEC *par_exec = &pbufs[0];
910 # Any initialization code before looping starts.
911 # Note that this code may declare some locals.
912 ${SHELL} $infile init
916 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
918 /* ??? 'twould be nice to move this up a level and only call it once.
919 On the other hand, in the "let's go fast" case the test is only done
920 once per pbb (since we only return to the main loop at the end of
921 a pbb). And in the "let's run until we're done" case we don't return
922 until the program exits. */
924 #if WITH_SEM_SWITCH_FAST && defined (__GNUC__)
925 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
926 #define DEFINE_LABELS
930 /* Initialize the "begin (compile) a pbb" virtual insn. */
931 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
932 SEM_SET_FAST_CODE (SEM_ARGBUF (vpc),
933 & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN]);
934 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN];
936 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
939 CPU_RUNNING_P (current_cpu) = 1;
940 /* ??? In the case where we're returning to the main loop after every
941 pbb we don't want to call pbb_begin each time (which hashes on the pc
942 and does a table lookup). A way to speed this up is to save vpc
944 vpc = ${cpu}_pbb_begin (current_cpu, FAST_P);
948 /* begin fast-exec-pbb */
951 ${SHELL} $infile fast-exec-pbb
954 /* end fast-exec-pbb */
956 while (CPU_RUNNING_P (current_cpu));
966 sed -e "s/@cpu@/$cpu/g" -e "s/@CPU@/$CPU/g" < tmp-mloop.cin
> mloop.cin