@@ -608,30 +608,10 @@ static void Exec_post(unsigned long flg, unsigned int mem_ref,
608608 }
609609}
610610
611- unsigned int DoExec (TNode * G , unsigned * pLastXKey )
611+ static unsigned ExecOne (TNode * G , unsigned * mem_ref , unsigned long * flg ,
612+ unsigned char * ecpu , unsigned int * pLastXKey )
612613{
613- unsigned long flg ;
614- unsigned char * ecpu ;
615- unsigned int mem_ref ;
616614 unsigned int ePC ;
617- unsigned short seqflg = G -> flags ;
618- unsigned char * SeqStart = G -> addr ;
619-
620- ecpu = CPUOFFS (0 );
621- if (debug_level ('e' )> 1 ) {
622- unsigned e = exit_pending ();
623- if (e & CeS_SIGPEND ) e_printf ("** SIGALRM is pending\n" );
624- if (e & CeS_RPIC ) e_printf ("** PIC is pending\n" );
625- e_printf ("==== Executing code at %p flg=%04x\n" ,
626- SeqStart ,seqflg );
627- }
628- #ifdef ASM_DUMP
629- fprintf (aLog ,"%p: exec\n" ,G -> key );
630- #endif
631- #if PROFILE >= 2
632- hitimer_t TimeStartExec ;
633- if (debug_level ('e' )) TimeStartExec = GETTSC ();
634- #endif
635615 /*
636616 * Just before execution comes the linker stage.
637617 * So the order is:
@@ -653,25 +633,75 @@ unsigned int DoExec(TNode *G, unsigned *pLastXKey)
653633 /* check links FROM LastXNode TO current node */
654634 if (* pLastXKey != G -> key )
655635 NodeLinker (FindTree (* pLastXKey ), G );
636+ ePC = Exec (mem_ref , flg , ecpu , G -> addr , G -> flags , pLastXKey );
637+ #ifdef SKIP_EMU_VBIOS
638+ if ((TheCPU .cs & 0xf000 )== config .vbios_seg && !TheCPU .err )
639+ TheCPU .err = EXCP_GOBACK ;
640+ #endif
641+ return ePC ;
642+ }
643+
644+ unsigned int DoExec (TNode * G , unsigned * pLastXKey )
645+ {
646+ unsigned long flg ;
647+ unsigned char * ecpu ;
648+ unsigned int mem_ref ;
649+ unsigned int ePC ;
650+ unsigned short seqflg = G -> flags ;
651+ int block_inhibit ;
652+ #if defined(SINGLESTEP )
653+ unsigned int key = G -> key ;
654+ #endif
656655
656+ ecpu = CPUOFFS (0 );
657+ if (debug_level ('e' )> 1 ) {
658+ unsigned e = exit_pending ();
659+ if (e & CeS_SIGPEND ) e_printf ("** SIGALRM is pending\n" );
660+ if (e & CeS_RPIC ) e_printf ("** PIC is pending\n" );
661+ e_printf ("==== Executing code at %p flg=%04x\n" ,
662+ G -> addr ,seqflg );
663+ }
664+ #ifdef ASM_DUMP
665+ fprintf (aLog ,"%p: exec\n" ,G -> key );
666+ #endif
667+ #if PROFILE >= 2
668+ hitimer_t TimeStartExec ;
669+ if (debug_level ('e' )) TimeStartExec = GETTSC ();
670+ #endif
671+ /* these flags need to be checked only once for the node */
672+ G -> flags &= ~(F_SPEC |F_LEAV );
673+ /* if there is just one compiled instruction inhibition
674+ should be ignored unconditionally if signals and traps
675+ were already ignored, e.g. two "sti"s in a row */
676+ block_inhibit = (seqflg & F_INHI ) && G -> seqnum == 1 &&
677+ (CEmuStat & CeS_INHI );
657678 flg = Exec_pre (ecpu );
658- ePC = Exec (& mem_ref , & flg , ecpu , SeqStart , seqflg , pLastXKey );
679+ #if !defined(ASM_DUMP ) && !defined(SINGLESTEP )
680+ /* try fast inner loop if nothing special is going on */
681+ if (!(EFLAGS & TF ) && !block_inhibit && !debug_level ('e' )) {
682+ while (1 ) {
683+ ePC = ExecOne (G , & mem_ref , & flg , ecpu , pLastXKey );
684+ if (TheCPU .err || exit_pending () ||
685+ (seqflg & (F_INHI |F_SLFJ |F_SPEC |F_LEAV )))
686+ break ;
687+ G = FindTree (ePC );
688+ if (!G || !GoodNode (G ))
689+ break ;
690+ seqflg = G -> flags ;
691+ }
692+ } else
693+ #endif
694+ ePC = ExecOne (G , & mem_ref , & flg , ecpu , pLastXKey );
659695 // G is unreliable (maybe deleted) past this point!
660696 Exec_post (flg , mem_ref , seqflg );
661697
662- if (debug_level ('e' )> 2 && * pLastXKey != ePC )
663- e_printf ("New LastXKey=%08x\n" ,* pLastXKey );
664-
665- #ifdef SKIP_EMU_VBIOS
666- if ((jcs & 0xf000 )== config .vbios_seg && !TheCPU .err )
667- TheCPU .err = EXCP_GOBACK ;
668- #endif
669-
670698 if (debug_level ('e' )) {
671699#if PROFILE >= 2
672700 ExecTime += GETTSC () - TimeStartExec ;
673701#endif
674702 if (debug_level ('e' )> 1 ) {
703+ if (debug_level ('e' )> 2 && * pLastXKey != ePC )
704+ e_printf ("New LastXKey=%08x\n" ,* pLastXKey );
675705 e_printf ("** End code, PC=%08x sig=%x\n" ,ePC ,
676706 exit_pending ());
677707 if ((debug_level ('e' )> 3 ) && (seqflg & F_FPOP )) {
@@ -684,14 +714,11 @@ unsigned int DoExec(TNode *G, unsigned *pLastXKey)
684714 }
685715 }
686716 }
687- /* signal_pending at this point is 1 if there was ANY signal,
717+ /* exit_pending at this point is non-zero if there was ANY signal,
688718 * not just a SIGALRM
689719 */
690- if (((seqflg & F_INHI ) || (CEmuStat & CeS_STI )) &&
691- !(G -> seqnum == 1 && (CEmuStat & CeS_INHI ))) {
692- /* ignore signals and traps for movss/popss; if there is just
693- one compiled instruction it should be ignored unconditionally
694- if signals and traps were already ignored */
720+ if (((seqflg & F_INHI ) || (CEmuStat & CeS_STI )) && !block_inhibit ) {
721+ /* ignore signals and traps for movss/popss */
695722 CEmuStat |= CeS_INHI ;
696723 CEmuStat &= ~CeS_TRAP ;
697724 } else {
@@ -700,47 +727,10 @@ unsigned int DoExec(TNode *G, unsigned *pLastXKey)
700727 }
701728
702729#if defined(SINGLESTEP )
703- InvalidateNodeRange (G -> key , 1 , NULL );
704- avltr_delete (G -> key );
705- #endif
706-
707- return ePC ;
708- }
709-
710- /* fast loop, only used if nothing special is going on; if anything
711- out of the ordinary happens, the above DoExec() is called */
712- unsigned int DoExec_fast (TNode * G , unsigned * pLastXKey )
713- {
714- unsigned char * ecpu = CPUOFFS (0 );
715- unsigned LastXKey = * pLastXKey ;
716- unsigned long flg = Exec_pre (ecpu );
717- unsigned int ePC , mem_ref ;
718- unsigned short seqflg = G -> flags ;
719-
720- do {
721- if (LastXKey != G -> key )
722- NodeLinker (FindTree (LastXKey ), G );
723- ePC = Exec (& mem_ref , & flg , ecpu , G -> addr , 0 , & LastXKey );
724- // G is unreliable (maybe deleted) past this point!
725- if (TheCPU .err == EXCP_STISHADOW ) {
726- /* as STI can exit here as well from the middle
727- of a block we must mirror DoExec here */
728- CEmuStat |= CeS_INHI ;
729- CEmuStat &= ~CeS_TRAP ;
730- break ;
731- }
732- if (exit_pending ())
733- break ;
734- #ifdef SKIP_EMU_VBIOS
735- if ((jcs & 0xf000 )== config .vbios_seg && !TheCPU .err )
736- TheCPU .err = EXCP_GOBACK ;
730+ InvalidateNodeRange (key , 1 , NULL );
731+ avltr_delete (key );
737732#endif
738- } while (!TheCPU .err && (G = FindTree (ePC )) &&
739- !((seqflg = G -> flags ) & (F_FPOP |F_INHI |F_SLFJ )) && GoodNode (G ));
740733
741- CEmuStat |= exit_pending_xchg (0 );
742- Exec_post (flg , mem_ref , G ? seqflg : 0 );
743- * pLastXKey = LastXKey ;
744734 return ePC ;
745735}
746736
0 commit comments