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 18static INLINE void 19sh64_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 31static INLINE void 32sh64_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 46static INLINE void 47sh64_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 61static INLINE void 62sh64_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 74static INLINE const IDESC * 75extract (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 90static INLINE SEM_PC 91execute (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 166INLINE SEM_PC 167sh64_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 324INLINE SEM_PC 325sh64_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 363INLINE SEM_PC 364sh64_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 430void 431sh64_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 478void 479sh64_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 501void 502sh64_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 570void 571sh64_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 636