]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/sh64/mloop-compact.c
config:
[thirdparty/binutils-gdb.git] / sim / sh64 / mloop-compact.c
1 /* This file is generated by the genmloop script. DO NOT EDIT! */
2
3 /* Enable switch() support in cgen headers. */
4 #define SEM_IN_SWITCH
5
6 #define WANT_CPU sh64
7 #define WANT_CPU_SH64
8
9 #include "sim-main.h"
10 #include "bfd.h"
11 #include "cgen-mem.h"
12 #include "cgen-ops.h"
13 #include "sim-assert.h"
14
15 /* Fill in the administrative ARGBUF fields required by all insns,
16 virtual and real. */
17
18 static INLINE void
19 sh64_compact_fill_argbuf (const SIM_CPU *cpu, ARGBUF *abuf, const IDESC *idesc,
20 PCADDR pc, int fast_p)
21 {
22 #if WITH_SCACHE
23 SEM_SET_CODE (abuf, idesc, fast_p);
24 ARGBUF_ADDR (abuf) = pc;
25 #endif
26 ARGBUF_IDESC (abuf) = idesc;
27 }
28
29 /* Fill in tracing/profiling fields of an ARGBUF. */
30
31 static INLINE void
32 sh64_compact_fill_argbuf_tp (const SIM_CPU *cpu, ARGBUF *abuf,
33 int trace_p, int profile_p)
34 {
35 ARGBUF_TRACE_P (abuf) = trace_p;
36 ARGBUF_PROFILE_P (abuf) = profile_p;
37 }
38
39 #if WITH_SCACHE_PBB
40
41 /* Emit the "x-before" handler.
42 x-before is emitted before each insn (serial or parallel).
43 This is as opposed to x-after which is only emitted at the end of a group
44 of parallel insns. */
45
46 static INLINE void
47 sh64_compact_emit_before (SIM_CPU *current_cpu, SCACHE *sc, PCADDR pc, int first_p)
48 {
49 ARGBUF *abuf = &sc[0].argbuf;
50 const IDESC *id = & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_BEFORE];
51
52 abuf->fields.before.first_p = first_p;
53 sh64_compact_fill_argbuf (current_cpu, abuf, id, pc, 0);
54 /* no need to set trace_p,profile_p */
55 }
56
57 /* Emit the "x-after" handler.
58 x-after is emitted after a serial insn or at the end of a group of
59 parallel insns. */
60
61 static INLINE void
62 sh64_compact_emit_after (SIM_CPU *current_cpu, SCACHE *sc, PCADDR pc)
63 {
64 ARGBUF *abuf = &sc[0].argbuf;
65 const IDESC *id = & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_AFTER];
66
67 sh64_compact_fill_argbuf (current_cpu, abuf, id, pc, 0);
68 /* no need to set trace_p,profile_p */
69 }
70
71 #endif /* WITH_SCACHE_PBB */
72
73
74 static INLINE const IDESC *
75 extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,
76 int fast_p)
77 {
78 const IDESC *id = sh64_compact_decode (current_cpu, pc, insn, insn, abuf);
79
80 sh64_compact_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
81 if (! fast_p)
82 {
83 int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
84 int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
85 sh64_compact_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
86 }
87 return id;
88 }
89
90 static INLINE SEM_PC
91 execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
92 {
93 SEM_PC vpc;
94
95 if (fast_p)
96 {
97 #if ! WITH_SEM_SWITCH_FAST
98 #if WITH_SCACHE
99 vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
100 #else
101 vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
102 #endif
103 #else
104 abort ();
105 #endif /* WITH_SEM_SWITCH_FAST */
106 }
107 else
108 {
109 #if ! WITH_SEM_SWITCH_FULL
110 ARGBUF *abuf = &sc->argbuf;
111 const IDESC *idesc = abuf->idesc;
112 #if WITH_SCACHE_PBB
113 int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);
114 #else
115 int virtual_p = 0;
116 #endif
117
118 if (! virtual_p)
119 {
120 /* FIXME: call x-before */
121 if (ARGBUF_PROFILE_P (abuf))
122 PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
123 /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
124 if (PROFILE_MODEL_P (current_cpu)
125 && ARGBUF_PROFILE_P (abuf))
126 sh64_compact_model_insn_before (current_cpu, 1 /*first_p*/);
127 TRACE_INSN_INIT (current_cpu, abuf, 1);
128 TRACE_INSN (current_cpu, idesc->idata,
129 (const struct argbuf *) abuf, abuf->addr);
130 }
131 #if WITH_SCACHE
132 vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
133 #else
134 vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
135 #endif
136 if (! virtual_p)
137 {
138 /* FIXME: call x-after */
139 if (PROFILE_MODEL_P (current_cpu)
140 && ARGBUF_PROFILE_P (abuf))
141 {
142 int cycles;
143
144 cycles = (*idesc->timing->model_fn) (current_cpu, sc);
145 sh64_compact_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
146 }
147 TRACE_INSN_FINI (current_cpu, abuf, 1);
148 }
149 #else
150 abort ();
151 #endif /* WITH_SEM_SWITCH_FULL */
152 }
153
154 return vpc;
155 }
156
157
158 /* Record address of cti terminating a pbb. */
159 #define SET_CTI_VPC(sc) do { _cti_sc = (sc); } while (0)
160 /* Record number of [real] insns in pbb. */
161 #define SET_INSN_COUNT(n) do { _insn_count = (n); } while (0)
162
163 /* Fetch and extract a pseudo-basic-block.
164 FAST_P is non-zero if no tracing/profiling/etc. is wanted. */
165
166 INLINE SEM_PC
167 sh64_compact_pbb_begin (SIM_CPU *current_cpu, int FAST_P)
168 {
169 SEM_PC new_vpc;
170 PCADDR pc;
171 SCACHE *sc;
172 int max_insns = CPU_SCACHE_MAX_CHAIN_LENGTH (current_cpu);
173
174 pc = GET_H_PC ();
175
176 new_vpc = scache_lookup_or_alloc (current_cpu, pc, max_insns, &sc);
177 if (! new_vpc)
178 {
179 /* Leading '_' to avoid collision with mainloop.in. */
180 int _insn_count = 0;
181 SCACHE *orig_sc = sc;
182 SCACHE *_cti_sc = NULL;
183 int slice_insns = CPU_MAX_SLICE_INSNS (current_cpu);
184
185 /* First figure out how many instructions to compile.
186 MAX_INSNS is the size of the allocated buffer, which includes space
187 for before/after handlers if they're being used.
188 SLICE_INSNS is the maxinum number of real insns that can be
189 executed. Zero means "as many as we want". */
190 /* ??? max_insns is serving two incompatible roles.
191 1) Number of slots available in scache buffer.
192 2) Number of real insns to execute.
193 They're incompatible because there are virtual insns emitted too
194 (chain,cti-chain,before,after handlers). */
195
196 if (slice_insns == 1)
197 {
198 /* No need to worry about extra slots required for virtual insns
199 and parallel exec support because MAX_CHAIN_LENGTH is
200 guaranteed to be big enough to execute at least 1 insn! */
201 max_insns = 1;
202 }
203 else
204 {
205 /* Allow enough slop so that while compiling insns, if max_insns > 0
206 then there's guaranteed to be enough space to emit one real insn.
207 MAX_CHAIN_LENGTH is typically much longer than
208 the normal number of insns between cti's anyway. */
209 max_insns -= (1 /* one for the trailing chain insn */
210 + (FAST_P
211 ? 0
212 : (1 + MAX_PARALLEL_INSNS) /* before+after */)
213 + (MAX_PARALLEL_INSNS > 1
214 ? (MAX_PARALLEL_INSNS * 2)
215 : 0));
216
217 /* Account for before/after handlers. */
218 if (! FAST_P)
219 slice_insns *= 3;
220
221 if (slice_insns > 0
222 && slice_insns < max_insns)
223 max_insns = slice_insns;
224 }
225
226 new_vpc = sc;
227
228 /* SC,PC must be updated to point passed the last entry used.
229 SET_CTI_VPC must be called if pbb is terminated by a cti.
230 SET_INSN_COUNT must be called to record number of real insns in
231 pbb [could be computed by us of course, extra cpu but perhaps
232 negligible enough]. */
233
234 /* begin extract-pbb */
235 {
236 const IDESC *idesc;
237 int icount = 0;
238
239 while (max_insns > 0)
240 {
241 UHI insn = GETIMEMUHI (current_cpu, pc);
242
243 idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
244 SEM_SKIP_COMPILE (current_cpu, sc, 1);
245 ++sc;
246 --max_insns;
247 ++icount;
248 pc += idesc->length;
249
250 if (IDESC_CTI_P (idesc))
251 {
252 SET_CTI_VPC (sc - 1);
253
254 if (CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT))
255 {
256 USI insn = GETIMEMUHI (current_cpu, pc);
257 idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
258
259 if (IDESC_CTI_P (idesc) ||
260 CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_ILLSLOT))
261 {
262 SIM_DESC sd = CPU_STATE (current_cpu);
263 sim_io_eprintf (CPU_STATE (current_cpu),
264 "malformed program, `%s' insn in delay slot\n",
265 CGEN_INSN_NAME (idesc->idata));
266 sim_engine_halt (sd, current_cpu, NULL, pc,
267 sim_stopped, SIM_SIGILL);
268 }
269 else
270 {
271 ++sc;
272 --max_insns;
273 ++icount;
274 pc += idesc->length;
275 }
276 }
277 break;
278 }
279 }
280
281 Finish:
282 SET_INSN_COUNT (icount);
283 }
284 /* end extract-pbb */
285
286 /* The last one is a pseudo-insn to link to the next chain.
287 It is also used to record the insn count for this chain. */
288 {
289 const IDESC *id;
290
291 /* Was pbb terminated by a cti? */
292 if (_cti_sc)
293 {
294 id = & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_CTI_CHAIN];
295 }
296 else
297 {
298 id = & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_CHAIN];
299 }
300 SEM_SET_CODE (&sc->argbuf, id, FAST_P);
301 sc->argbuf.idesc = id;
302 sc->argbuf.addr = pc;
303 sc->argbuf.fields.chain.insn_count = _insn_count;
304 sc->argbuf.fields.chain.next = 0;
305 sc->argbuf.fields.chain.branch_target = 0;
306 ++sc;
307 }
308
309 /* Update the pointer to the next free entry, may not have used as
310 many entries as was asked for. */
311 CPU_SCACHE_NEXT_FREE (current_cpu) = sc;
312 /* Record length of chain if profiling.
313 This includes virtual insns since they count against
314 max_insns too. */
315 if (! FAST_P)
316 PROFILE_COUNT_SCACHE_CHAIN_LENGTH (current_cpu, sc - orig_sc);
317 }
318
319 return new_vpc;
320 }
321
322 /* Chain to the next block from a non-cti terminated previous block. */
323
324 INLINE SEM_PC
325 sh64_compact_pbb_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg)
326 {
327 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
328
329 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
330
331 SET_H_PC (abuf->addr);
332
333
334 /* If not running forever, exit back to main loop. */
335 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0
336 /* Also exit back to main loop if there's an event.
337 Note that if CPU_MAX_SLICE_INSNS != 1, events won't get processed
338 at the "right" time, but then that was what was asked for.
339 There is no silver bullet for simulator engines.
340 ??? Clearly this needs a cleaner interface.
341 At present it's just so Ctrl-C works. */
342 || STATE_EVENTS (CPU_STATE (current_cpu))->work_pending)
343 CPU_RUNNING_P (current_cpu) = 0;
344
345 /* If chained to next block, go straight to it. */
346 if (abuf->fields.chain.next)
347 return abuf->fields.chain.next;
348 /* See if next block has already been compiled. */
349 abuf->fields.chain.next = scache_lookup (current_cpu, abuf->addr);
350 if (abuf->fields.chain.next)
351 return abuf->fields.chain.next;
352 /* Nope, so next insn is a virtual insn to invoke the compiler
353 (begin a pbb). */
354 return CPU_SCACHE_PBB_BEGIN (current_cpu);
355 }
356
357 /* Chain to the next block from a cti terminated previous block.
358 BR_TYPE indicates whether the branch was taken and whether we can cache
359 the vpc of the branch target.
360 NEW_PC is the target's branch address, and is only valid if
361 BR_TYPE != SEM_BRANCH_UNTAKEN. */
362
363 INLINE SEM_PC
364 sh64_compact_pbb_cti_chain (SIM_CPU *current_cpu, SEM_ARG sem_arg,
365 SEM_BRANCH_TYPE br_type, PCADDR new_pc)
366 {
367 SEM_PC *new_vpc_ptr;
368
369 PBB_UPDATE_INSN_COUNT (current_cpu, sem_arg);
370
371 /* If we have switched ISAs, exit back to main loop.
372 Set idesc to 0 to cause the engine to point to the right insn table. */
373 if (new_pc & 1)
374 {
375 /* Switch to SHmedia. */
376 CPU_IDESC_SEM_INIT_P (current_cpu) = 0;
377 CPU_RUNNING_P (current_cpu) = 0;
378 }
379
380 /* If not running forever, exit back to main loop. */
381 if (CPU_MAX_SLICE_INSNS (current_cpu) != 0
382 /* Also exit back to main loop if there's an event.
383 Note that if CPU_MAX_SLICE_INSNS != 1, events won't get processed
384 at the "right" time, but then that was what was asked for.
385 There is no silver bullet for simulator engines.
386 ??? Clearly this needs a cleaner interface.
387 At present it's just so Ctrl-C works. */
388 || STATE_EVENTS (CPU_STATE (current_cpu))->work_pending)
389 CPU_RUNNING_P (current_cpu) = 0;
390
391 /* Restart compiler if we branched to an uncacheable address
392 (e.g. "j reg"). */
393 if (br_type == SEM_BRANCH_UNCACHEABLE)
394 {
395 SET_H_PC (new_pc);
396 return CPU_SCACHE_PBB_BEGIN (current_cpu);
397 }
398
399 /* If branch wasn't taken, update the pc and set BR_ADDR_PTR to our
400 next chain ptr. */
401 if (br_type == SEM_BRANCH_UNTAKEN)
402 {
403 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
404 new_pc = abuf->addr;
405 SET_H_PC (new_pc);
406 new_vpc_ptr = &abuf->fields.chain.next;
407 }
408 else
409 {
410 ARGBUF *abuf = SEM_ARGBUF (sem_arg);
411 SET_H_PC (new_pc);
412 new_vpc_ptr = &abuf->fields.chain.branch_target;
413 }
414
415 /* If chained to next block, go straight to it. */
416 if (*new_vpc_ptr)
417 return *new_vpc_ptr;
418 /* See if next block has already been compiled. */
419 *new_vpc_ptr = scache_lookup (current_cpu, new_pc);
420 if (*new_vpc_ptr)
421 return *new_vpc_ptr;
422 /* Nope, so next insn is a virtual insn to invoke the compiler
423 (begin a pbb). */
424 return CPU_SCACHE_PBB_BEGIN (current_cpu);
425 }
426
427 /* x-before handler.
428 This is called before each insn. */
429
430 void
431 sh64_compact_pbb_before (SIM_CPU *current_cpu, SCACHE *sc)
432 {
433 SEM_ARG sem_arg = sc;
434 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
435 int first_p = abuf->fields.before.first_p;
436 const ARGBUF *cur_abuf = SEM_ARGBUF (sc + 1);
437 const IDESC *cur_idesc = cur_abuf->idesc;
438 PCADDR pc = cur_abuf->addr;
439
440 if (ARGBUF_PROFILE_P (cur_abuf))
441 PROFILE_COUNT_INSN (current_cpu, pc, cur_idesc->num);
442
443 /* If this isn't the first insn, finish up the previous one. */
444
445 if (! first_p)
446 {
447 if (PROFILE_MODEL_P (current_cpu))
448 {
449 const SEM_ARG prev_sem_arg = sc - 1;
450 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
451 const IDESC *prev_idesc = prev_abuf->idesc;
452 int cycles;
453
454 /* ??? May want to measure all insns if doing insn tracing. */
455 if (ARGBUF_PROFILE_P (prev_abuf))
456 {
457 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
458 sh64_compact_model_insn_after (current_cpu, 0 /*last_p*/, cycles);
459 }
460 }
461
462 TRACE_INSN_FINI (current_cpu, cur_abuf, 0 /*last_p*/);
463 }
464
465 /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
466 if (PROFILE_MODEL_P (current_cpu)
467 && ARGBUF_PROFILE_P (cur_abuf))
468 sh64_compact_model_insn_before (current_cpu, first_p);
469
470 TRACE_INSN_INIT (current_cpu, cur_abuf, first_p);
471 TRACE_INSN (current_cpu, cur_idesc->idata, cur_abuf, pc);
472 }
473
474 /* x-after handler.
475 This is called after a serial insn or at the end of a group of parallel
476 insns. */
477
478 void
479 sh64_compact_pbb_after (SIM_CPU *current_cpu, SCACHE *sc)
480 {
481 SEM_ARG sem_arg = sc;
482 const ARGBUF *abuf = SEM_ARGBUF (sem_arg);
483 const SEM_ARG prev_sem_arg = sc - 1;
484 const ARGBUF *prev_abuf = SEM_ARGBUF (prev_sem_arg);
485
486 /* ??? May want to measure all insns if doing insn tracing. */
487 if (PROFILE_MODEL_P (current_cpu)
488 && ARGBUF_PROFILE_P (prev_abuf))
489 {
490 const IDESC *prev_idesc = prev_abuf->idesc;
491 int cycles;
492
493 cycles = (*prev_idesc->timing->model_fn) (current_cpu, prev_sem_arg);
494 sh64_compact_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
495 }
496 TRACE_INSN_FINI (current_cpu, prev_abuf, 1 /*last_p*/);
497 }
498
499 #define FAST_P 0
500
501 void
502 sh64_compact_engine_run_full (SIM_CPU *current_cpu)
503 {
504 SIM_DESC current_state = CPU_STATE (current_cpu);
505 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
506 /* virtual program counter */
507 SEM_PC vpc;
508 #if WITH_SEM_SWITCH_FULL
509 /* For communication between cti's and cti-chain. */
510 SEM_BRANCH_TYPE pbb_br_type;
511 PCADDR pbb_br_npc;
512 #endif
513
514
515 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
516 {
517 /* ??? 'twould be nice to move this up a level and only call it once.
518 On the other hand, in the "let's go fast" case the test is only done
519 once per pbb (since we only return to the main loop at the end of
520 a pbb). And in the "let's run until we're done" case we don't return
521 until the program exits. */
522
523 #if WITH_SEM_SWITCH_FULL
524 #if defined (__GNUC__)
525 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
526 #define DEFINE_LABELS
527 #include "sem-compact-switch.c"
528 #endif
529 #else
530 sh64_compact_sem_init_idesc_table (current_cpu);
531 #endif
532
533 /* Initialize the "begin (compile) a pbb" virtual insn. */
534 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
535 SEM_SET_FULL_CODE (SEM_ARGBUF (vpc),
536 & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_BEGIN]);
537 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_BEGIN];
538
539 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
540 }
541
542 CPU_RUNNING_P (current_cpu) = 1;
543 /* ??? In the case where we're returning to the main loop after every
544 pbb we don't want to call pbb_begin each time (which hashes on the pc
545 and does a table lookup). A way to speed this up is to save vpc
546 between calls. */
547 vpc = sh64_compact_pbb_begin (current_cpu, FAST_P);
548
549 do
550 {
551 /* begin full-exec-pbb */
552 {
553 #if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
554 #define DEFINE_SWITCH
555 #include "sem-compact-switch.c"
556 #else
557 vpc = execute (current_cpu, vpc, FAST_P);
558 #endif
559 }
560 /* end full-exec-pbb */
561 }
562 while (CPU_RUNNING_P (current_cpu));
563 }
564
565 #undef FAST_P
566
567
568 #define FAST_P 1
569
570 void
571 sh64_compact_engine_run_fast (SIM_CPU *current_cpu)
572 {
573 SIM_DESC current_state = CPU_STATE (current_cpu);
574 SCACHE *scache = CPU_SCACHE_CACHE (current_cpu);
575 /* virtual program counter */
576 SEM_PC vpc;
577 #if WITH_SEM_SWITCH_FAST
578 /* For communication between cti's and cti-chain. */
579 SEM_BRANCH_TYPE pbb_br_type;
580 PCADDR pbb_br_npc;
581 #endif
582
583
584 if (! CPU_IDESC_SEM_INIT_P (current_cpu))
585 {
586 /* ??? 'twould be nice to move this up a level and only call it once.
587 On the other hand, in the "let's go fast" case the test is only done
588 once per pbb (since we only return to the main loop at the end of
589 a pbb). And in the "let's run until we're done" case we don't return
590 until the program exits. */
591
592 #if WITH_SEM_SWITCH_FAST
593 #if defined (__GNUC__)
594 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
595 #define DEFINE_LABELS
596 #include "sem-compact-switch.c"
597 #endif
598 #else
599 sh64_compact_semf_init_idesc_table (current_cpu);
600 #endif
601
602 /* Initialize the "begin (compile) a pbb" virtual insn. */
603 vpc = CPU_SCACHE_PBB_BEGIN (current_cpu);
604 SEM_SET_FAST_CODE (SEM_ARGBUF (vpc),
605 & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_BEGIN]);
606 vpc->argbuf.idesc = & CPU_IDESC (current_cpu) [SH64_COMPACT_INSN_X_BEGIN];
607
608 CPU_IDESC_SEM_INIT_P (current_cpu) = 1;
609 }
610
611 CPU_RUNNING_P (current_cpu) = 1;
612 /* ??? In the case where we're returning to the main loop after every
613 pbb we don't want to call pbb_begin each time (which hashes on the pc
614 and does a table lookup). A way to speed this up is to save vpc
615 between calls. */
616 vpc = sh64_compact_pbb_begin (current_cpu, FAST_P);
617
618 do
619 {
620 /* begin fast-exec-pbb */
621 {
622 #if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
623 #define DEFINE_SWITCH
624 #include "sem-compact-switch.c"
625 #else
626 vpc = execute (current_cpu, vpc, FAST_P);
627 #endif
628 }
629 /* end fast-exec-pbb */
630 }
631 while (CPU_RUNNING_P (current_cpu));
632 }
633
634 #undef FAST_P
635