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.
78 # Note that while the code can determine if the cpu supports parallel
79 # execution with HAVE_PARALLEL_INSNS [and thus this option is
80 # technically unnecessary], having this option cuts down on the clutter
83 # -switch file: specify file containing semantics implemented as a switch()
87 # Specify the cpu family name.
89 # -infile <input-file>
91 # Specify the mainloop.in input file.
93 # Only one of -scache/-pbb may be selected.
94 # -simple is the default.
99 # - build mainloop.in from .cpu file
115 -multi) type=multi
;;
118 -full-switch) full_switch
=yes ;;
120 -scache) scache
=yes ;;
123 -parallel) parallel
=yes ;;
124 -switch) shift ; switch
=$1 ;;
125 -cpu) shift ; cpu
=$1 ;;
126 -infile) shift ; infile
=$1 ;;
127 *) echo "unknown option: $1" >&2 ; exit 1 ;;
132 # Argument validation.
134 if [ x
$scache = xyes
-a x
$pbb = xyes
] ; then
135 echo "only one of -scache and -pbb may be selected" >&2
139 if [ "x$cpu" = xunknown
] ; then
140 echo "cpu family not specified" >&2
144 if [ "x$infile" = x
] ; then
145 echo "mainloop.in not specified" >&2
149 lowercase
='abcdefghijklmnopqrstuvwxyz'
150 uppercase
='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
151 CPU
=`echo ${cpu} | tr "${lowercase}" "${uppercase}"`
153 ##########################################################################
158 echo "/* engine configuration for ${cpu} */"
161 echo "/* WITH_FAST: non-zero if a fast version of the engine is available"
162 echo " in addition to the full-featured version. */"
163 if [ x
$fast = xyes
] ; then
164 echo "#define WITH_FAST 1"
166 echo "#define WITH_FAST 0"
170 echo "/* WITH_SCACHE_PBB_${CPU}: non-zero if the pbb engine was selected. */"
171 if [ x
$pbb = xyes
] ; then
172 echo "#define WITH_SCACHE_PBB_${CPU} 1"
174 echo "#define WITH_SCACHE_PBB_${CPU} 0"
178 echo "/* HAVE_PARALLEL_INSNS: non-zero if cpu can parallelly execute > 1 insn. */"
179 if [ x
$parallel = xyes
] ; then
180 echo "#define HAVE_PARALLEL_INSNS 1"
182 echo "#define HAVE_PARALLEL_INSNS 0"
185 if [ "x$switch" != x
] ; then
187 echo "/* WITH_SEM_SWITCH_FULL: non-zero if full-featured engine is"
188 echo " implemented as a switch(). */"
189 if [ x
$fast != xyes
-o x
$full_switch = xyes
] ; then
190 echo "#define WITH_SEM_SWITCH_FULL 1"
192 echo "#define WITH_SEM_SWITCH_FULL 0"
195 echo "/* WITH_SEM_SWITCH_FAST: non-zero if fast engine is"
196 echo " implemented as a switch(). */"
197 if [ x
$fast = xyes
] ; then
198 echo "#define WITH_SEM_SWITCH_FAST 1"
200 echo "#define WITH_SEM_SWITCH_FAST 0"
204 # Decls of functions we define.
207 echo "/* Functions defined in the generated mainloop.c file"
208 echo " (which doesn't necessarily have that file name). */"
210 echo "extern ENGINE_FN ${cpu}_engine_run_full;"
211 echo "extern ENGINE_FN ${cpu}_engine_run_fast;"
213 if [ x
$pbb = xyes
] ; then
215 echo "extern SEM_PC ${cpu}_pbb_begin (SIM_CPU *, int);"
216 echo "extern SEM_PC ${cpu}_pbb_chain (SIM_CPU *, SEM_ARG);"
217 echo "extern SEM_PC ${cpu}_pbb_cti_chain (SIM_CPU *, SEM_ARG, SEM_PC *, PCADDR);"
218 echo "extern void ${cpu}_pbb_before (SIM_CPU *, SCACHE *);"
219 echo "extern void ${cpu}_pbb_after (SIM_CPU *, SCACHE *);"
222 ##########################################################################
224 rm -f tmp-mloop.cin mloop.cin
227 # We use @cpu@ instead of ${cpu} because we still want to run sed to handle
228 # transformation of @cpu@ for mainloop.in.
231 /* This file is generated by the genmloop script. DO NOT EDIT! */
233 /* Enable switch() support in cgen headers. */
234 #define SEM_IN_SWITCH
237 #define WANT_CPU_${CPU}
239 #include "sim-main.h"
241 #include "cgen-mem.h"
242 #include "cgen-ops.h"
245 #include "sim-assert.h"
249 ${SHELL} $infile support
251 ##########################################################################
253 # Simple engine: fetch an instruction, execute the instruction.
255 if [ x
$scache != xyes
-a x
$pbb != xyes
] ; then
262 ${cpu}_engine_run_full (SIM_CPU *current_cpu)
265 SIM_DESC current_state = CPU_STATE (current_cpu);
266 SCACHE cache[MAX_LIW_INSNS];
267 SCACHE *sc = &cache[0];
271 if [ x
$parallel = xyes
] ; then
273 PAREXEC pbufs[MAX_PARALLEL_INSNS];
279 # Any initialization code before looping starts.
280 # Note that this code may declare some locals.
281 ${SHELL} $infile init
283 if [ x
$parallel = xyes
] ; then
286 #if defined (HAVE_PARALLEL_EXEC) && defined (__GNUC__)
288 if (! CPU_IDESC_READ_INIT_P (current_cpu))
290 /* ??? Later maybe paste read.c in when building mainloop.c. */
291 #define DEFINE_LABELS
293 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
305 /* begin full-{extract,exec}-simple */
308 ${SHELL} $infile extract-simple
310 ${SHELL} $infile full-exec-simple
313 /* end full-{extract,exec}-simple */
315 ++ CPU_INSN_COUNT (current_cpu);
317 while (0 /*CPU_RUNNING_P (current_cpu)*/);
325 ####################################
327 # Simple engine: fast version.
328 # ??? A somewhat dubious effort, but for completeness' sake.
330 if [ x
$fast = xyes
] ; then
346 ##########################################################################
348 # Scache engine: lookup insn in scache, fetch if missing, then execute it.
350 if [ x
$scache = xyes
] ; then
354 static INLINE SCACHE *
355 ${cpu}_scache_lookup (SIM_CPU *current_cpu, PCADDR vpc, SCACHE *scache,
356 unsigned int hash_mask, int FAST_P)
358 /* First step: look up current insn in hash table. */
359 SCACHE *sc = scache + SCACHE_HASH_PC (vpc, hash_mask);
361 /* If the entry isn't the one we want (cache miss),
362 fetch and decode the instruction. */
363 if (sc->argbuf.addr != vpc)
368 PROFILE_COUNT_SCACHE_MISS (current_cpu);
370 /* begin extract-scache */
373 ${SHELL} $infile extract-scache
376 /* end extract-scache */
380 PROFILE_COUNT_SCACHE_HIT (current_cpu);
381 /* Make core access statistics come out right.
382 The size is a guess, but it's currently not used either. */
383 PROFILE_COUNT_CORE (current_cpu, vpc, 2, exec_map);
392 ${cpu}_engine_run_full (SIM_CPU *current_cpu)
394 SIM_DESC current_state = CPU_STATE (current_cpu);
395 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
396 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
401 if [ x
$parallel = xyes
] ; then
403 PAREXEC pbufs[MAX_PARALLEL_INSNS];
409 # Any initialization code before looping starts.
410 # Note that this code may declare some locals.
411 ${SHELL} $infile init
413 if [ x
$parallel = xyes
] ; then
416 #if defined (HAVE_PARALLEL_EXEC) && defined (__GNUC__)
418 if (! CPU_IDESC_READ_INIT_P (current_cpu))
420 /* ??? Later maybe paste read.c in when building mainloop.c. */
421 #define DEFINE_LABELS
423 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
439 sc = ${cpu}_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
441 /* begin full-exec-scache */
444 ${SHELL} $infile full-exec-scache
447 /* end full-exec-scache */
451 ++ CPU_INSN_COUNT (current_cpu);
453 while (0 /*CPU_RUNNING_P (current_cpu)*/);
460 ####################################
462 # Scache engine: fast version.
464 if [ x
$fast = xyes
] ; then
471 ${cpu}_engine_run_fast (SIM_CPU *current_cpu)
473 SIM_DESC current_state = CPU_STATE (current_cpu);
474 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
475 unsigned int hash_mask = CPU_SCACHE_HASH_MASK (current_cpu);
480 if [ x
$parallel = xyes
] ; then
482 PAREXEC pbufs[MAX_PARALLEL_INSNS];
488 # Any initialization code before looping starts.
489 # Note that this code may declare some locals.
490 ${SHELL} $infile init
492 if [ x
$parallel = xyes
] ; then
495 #if defined (HAVE_PARALLEL_EXEC) && defined (__GNUC__)
497 if (! CPU_IDESC_READ_INIT_P (current_cpu))
499 /* ??? Later maybe paste read.c in when building mainloop.c. */
500 #define DEFINE_LABELS
502 CPU_IDESC_READ_INIT_P (current_cpu) = 1;
512 #if WITH_SEM_SWITCH_FAST && defined (__GNUC__)
514 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
516 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
517 #define DEFINE_LABELS
519 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
530 sc = ${cpu}_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
532 /* begin fast-exec-scache */
535 ${SHELL} $infile fast-exec-scache
538 /* end fast-exec-scache */
542 ++ CPU_INSN_COUNT (current_cpu);
544 while (0 /*CPU_RUNNING_P (current_cpu)*/);
555 ##########################################################################
557 # Compilation engine: lookup insn in scache, extract a pbb
558 # (pseudo-basic-block) if missing, then execute the pbb.
559 # A "pbb" is a sequence of insns up to the next cti insn or until
560 # some prespecified maximum.
561 # CTI: control transfer instruction.
563 if [ x
$pbb = xyes
] ; then
567 /* Record address of cti terminating a pbb. */
568 #define SET_CTI_VPC(sc) do { cti_sc = (sc); } while (0)
569 /* Record number of [real] insns in pbb. */
570 #define SET_INSN_COUNT(n) do { insn_count = (n); } while (0)
572 /* Fetch and extract a pseudo-basic-block.
573 FAST_P is non-zero if no tracing/profiling/etc. is wanted. */
576 ${cpu}_pbb_begin (SIM_CPU *current_cpu, int FAST_P)
581 int max_insns = CPU_SCACHE_MAX_CHAIN_LENGTH (current_cpu);
585 new_vpc = scache_lookup_or_alloc (current_cpu, pc, max_insns, &sc);
589 SCACHE *orig_sc = sc;
590 SCACHE *cti_sc = NULL;
591 int slice_insns = CPU_MAX_SLICE_INSNS (current_cpu);
593 /* First figure out how many instructions to compile.
594 MAX_INSNS is the size of the allocated buffer, which includes space
595 for before/after handlers if they're being used.
596 SLICE_INSNS is the maxinum number of real insns that can be
597 executed. Zero means "as many as we want". */
598 /* ??? max_insns is serving two incompatible roles.
599 1) Number of slots available in scache buffer.
600 2) Number of real insns to execute.
601 They're incompatible because there are virtual insns emitted too
602 (chain,cti-chain,before,after handlers). */
604 if (slice_insns == 1)
606 /* No need to worry about extra slots required for virtual insns
607 and parallel exec support because MAX_CHAIN_LENGTH is
608 guaranteed to be big enough to execute at least 1 insn! */
613 /* Allow enough slop so that while compiling insns, if max_insns > 0
614 then there's guaranteed to be enough space to emit one real insn.
615 MAX_CHAIN_LENGTH is typically much longer than
616 the normal number of insns between cti's anyway. */
617 max_insns -= (1 /* one for the trailing chain insn */
620 : (1 + MAX_PARALLEL_INSNS) /* before+after */)
621 + (MAX_PARALLEL_INSNS > 1
622 ? (MAX_PARALLEL_INSNS * 2)
625 /* Account for before/after handlers. */
630 && slice_insns < max_insns)
631 max_insns = slice_insns;
636 /* SC,PC must be updated to point passed the last entry used.
637 SET_CTI_VPC must be called if pbb is terminated by a cti.
638 SET_INSN_COUNT must be called to record number of real insns in
639 pbb [could be computed by us of course, extra cpu but perhaps
640 negligible enough]. */
642 /* begin extract-pbb */
645 ${SHELL} $infile extract-pbb
648 /* end extract-pbb */
650 /* The last one is a pseudo-insn to link to the next chain.
651 It is also used to record the insn count for this chain. */
655 /* Was pbb terminated by a cti? */
658 id = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_CTI_CHAIN];
662 id = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_CHAIN];
664 SEM_SET_CODE (&sc->argbuf, id, FAST_P);
665 sc->argbuf.idesc = id;
666 sc->argbuf.addr = pc;
667 sc->argbuf.fields.chain.insn_count = insn_count;
668 sc->argbuf.fields.chain.next = 0;
672 /* Update the pointer to the next free entry. */
673 CPU_SCACHE_NEXT_FREE (current_cpu) = sc;
674 /* Record length of chain if profiling.
675 This includes virtual insns since they count against
678 PROFILE_COUNT_SCACHE_CHAIN_LENGTH (current_cpu, sc - orig_sc);
684 /* Chain to the next block from a non-cti terminated previous block. */
687 ${cpu}_pbb_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg)
689 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
691 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
693 SET_H_PC (abuf->addr);
695 /* If not running forever, exit back to main loop. */
696 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0)
697 CPU_RUNNING_P (current_cpu) = 0;
699 /* If chained to next block, go straight to it. */
700 if (abuf->fields.chain.next)
701 return abuf->fields.chain.next;
702 /* See if next block has already been compiled. */
703 abuf->fields.chain.next = scache_lookup (current_cpu, abuf->addr);
704 if (abuf->fields.chain.next)
705 return abuf->fields.chain.next;
706 /* Nope, so next insn is a virtual insn to invoke the compiler
708 return CPU_SCACHE_PBB_BEGIN (current_cpu);
711 /* Chain to the next block from a cti terminated previous block.
712 NEW_VPC_PTR is one of SEM_BRANCH_UNTAKEN, SEM_BRANCH_UNCACHEABLE, or
713 a pointer to a location containing the SEM_PC of the branch's address.
714 NEW_PC is the target's branch address, and is only valid if
715 NEW_VPC_PTR != SEM_BRANCH_UNTAKEN. */
718 ${cpu}_pbb_cti_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg,
719 SEM_PC *new_vpc_ptr, PCADDR new_pc)
723 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
725 /* If not running forever, exit back to main loop. */
726 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0)
727 CPU_RUNNING_P (current_cpu) = 0;
729 /* Restart compiler if we branched to an uncacheable address
731 if (new_vpc_ptr == SEM_BRANCH_UNCACHEABLE)
734 return CPU_SCACHE_PBB_BEGIN (current_cpu);
737 /* If branch wasn't taken, update the pc and set BR_ADDR_PTR to our
739 if (new_vpc_ptr == SEM_BRANCH_UNTAKEN)
741 abuf = SEM_ARGBUF (sem_arg);
742 SET_H_PC (abuf->addr);
743 new_vpc_ptr = &abuf->fields.chain.next;
750 /* If chained to next block, go straight to it. */
753 /* See if next block has already been compiled. */
754 *new_vpc_ptr = scache_lookup (current_cpu, GET_H_PC ());
757 /* Nope, so next insn is a virtual insn to invoke the compiler
759 return CPU_SCACHE_PBB_BEGIN (current_cpu);
763 This is called before each insn. */
766 ${cpu}_pbb_before (SIM_CPU *current_cpu, SCACHE *sc)
768 SEM_ARG sem_arg = sc;
769 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
770 int first_p = abuf->fields.before.first_p;
771 const ARGBUF *cur_abuf = SEM_ARGBUF (sc + 1);
772 const IDESC *cur_idesc = cur_abuf->idesc;
773 PCADDR pc = cur_abuf->addr;
775 PROFILE_COUNT_INSN (current_cpu, pc, cur_idesc->num);
777 /* If this isn't the first insn, finish up the previous one. */
781 if (PROFILE_MODEL_P (current_cpu))
783 const SEM_ARG prev_sem_arg = sc - 1;
784 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
785 const IDESC *prev_idesc = prev_abuf->idesc;
788 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
789 ${cpu}_model_insn_after (current_cpu, 0 /*last_p*/, cycles);
792 TRACE_INSN_FINI (current_cpu, 0 /*last_p*/);
795 /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
796 if (PROFILE_MODEL_P (current_cpu))
797 ${cpu}_model_insn_before (current_cpu, first_p);
799 TRACE_INSN_INIT (current_cpu, first_p);
800 TRACE_INSN (current_cpu, cur_idesc->opcode, cur_abuf, cur_abuf->addr);
804 This is called after a serial insn or at the end of a group of parallel
808 ${cpu}_pbb_after (SIM_CPU *current_cpu, SCACHE *sc)
810 SEM_ARG sem_arg = sc;
811 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
813 if (PROFILE_MODEL_P (current_cpu))
815 const SEM_ARG prev_sem_arg = sc - 1;
816 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
817 const IDESC *prev_idesc = prev_abuf->idesc;
820 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
821 ${cpu}_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
823 TRACE_INSN_FINI (current_cpu, 1 /*last_p*/);
829 ${cpu}_engine_run_full (SIM_CPU *current_cpu)
831 SIM_DESC current_state = CPU_STATE (current_cpu);
832 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
833 /* virtual program counter */
835 #if WITH_SEM_SWITCH_FULL
836 /* For communication between cti's and cti-chain. */
838 SEM_PC *pbb_br_npc_ptr;
843 if [ x
$parallel = xyes
] ; then
845 PAREXEC pbufs[MAX_PARALLEL_INSNS];
846 PAREXEC *par_exec = &pbufs[0];
851 # Any initialization code before looping starts.
852 # Note that this code may declare some locals.
853 ${SHELL} $infile init
857 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
859 /* ??? 'twould be nice to move this up a level and only call it once.
860 On the other hand, in the "let's go fast" case the test is only done
861 once per pbb (since we only return to the main loop at the end of
862 a pbb). And in the "let's run until we're done" case we don't return
863 until the program exits. */
865 #if WITH_SEM_SWITCH_FULL && defined (__GNUC__)
866 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
867 #define DEFINE_LABELS
871 /* Initialize the "begin (compile) a pbb" virtual insn. */
872 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
873 SEM_SET_FULL_CODE (SEM_ARGBUF (vpc),
874 & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN]);
875 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN];
877 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
880 CPU_RUNNING_P (current_cpu) = 1;
881 /* ??? In the case where we're returning to the main loop after every
882 pbb we don't want to call pbb_begin each time (which hashes on the pc
883 and does a table lookup). A way to speed this up is to save vpc
885 vpc = ${cpu}_pbb_begin (current_cpu, FAST_P);
889 /* begin full-exec-pbb */
892 ${SHELL} $infile full-exec-pbb
895 /* end full-exec-pbb */
897 while (CPU_RUNNING_P (current_cpu));
904 ####################################
906 # Compile engine: fast version.
908 if [ x
$fast = xyes
] ; then
915 ${cpu}_engine_run_fast (SIM_CPU *current_cpu)
917 SIM_DESC current_state = CPU_STATE (current_cpu);
918 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
919 /* virtual program counter */
921 #if WITH_SEM_SWITCH_FAST
922 /* For communication between cti's and cti-chain. */
924 SEM_PC *pbb_br_npc_ptr;
929 if [ x
$parallel = xyes
] ; then
931 PAREXEC pbufs[MAX_PARALLEL_INSNS];
932 PAREXEC *par_exec = &pbufs[0];
937 # Any initialization code before looping starts.
938 # Note that this code may declare some locals.
939 ${SHELL} $infile init
943 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
945 /* ??? 'twould be nice to move this up a level and only call it once.
946 On the other hand, in the "let's go fast" case the test is only done
947 once per pbb (since we only return to the main loop at the end of
948 a pbb). And in the "let's run until we're done" case we don't return
949 until the program exits. */
951 #if WITH_SEM_SWITCH_FAST && defined (__GNUC__)
952 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
953 #define DEFINE_LABELS
957 /* Initialize the "begin (compile) a pbb" virtual insn. */
958 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
959 SEM_SET_FAST_CODE (SEM_ARGBUF (vpc),
960 & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN]);
961 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [${CPU}_INSN_X_BEGIN];
963 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
966 CPU_RUNNING_P (current_cpu) = 1;
967 /* ??? In the case where we're returning to the main loop after every
968 pbb we don't want to call pbb_begin each time (which hashes on the pc
969 and does a table lookup). A way to speed this up is to save vpc
971 vpc = ${cpu}_pbb_begin (current_cpu, FAST_P);
975 /* begin fast-exec-pbb */
978 ${SHELL} $infile fast-exec-pbb
981 /* end fast-exec-pbb */
983 while (CPU_RUNNING_P (current_cpu));
993 sed -e "s/@cpu@/$cpu/g" -e "s/@CPU@/$CPU/g" < tmp-mloop.cin
> mloop.cin
This page took 0.067583 seconds and 4 git commands to generate.