@@ -589,16 +589,10 @@ static unsigned int Exec_pre(unsigned char *ecpu)
589589 return flg ;
590590}
591591
592- static void Exec_post (unsigned long flg , unsigned int mem_ref ,
593- unsigned short seqflg )
592+ static void Exec_post (unsigned long flg , unsigned int mem_ref )
594593{
595594 EFLAGS = (EFLAGS & ~EFLAGS_CC ) | (flg & EFLAGS_CC );
596595 TheCPU .mem_ref = mem_ref ;
597- /* checking for infinite loops, flagged in JumpGen() */
598- if ((seqflg & F_SLFJ ) && !(EFLAGS & (VIF |IF |TF ))) {
599- error ("!Forever loop!\n" );
600- leavedos_main (0xebfe );
601- }
602596}
603597
604598static void HandleEmuSignals (int tfset )
@@ -612,8 +606,7 @@ static void HandleEmuSignals(int tfset)
612606#endif
613607 if (tfset ) {
614608 /* force exit for single step trap */
615- if (!TheCPU .err )
616- TheCPU .err = EXCP01_SSTP ;
609+ TheCPU .err = EXCP01_SSTP ;
617610 }
618611 //else if (CEmuStat & CeS_DRTRAP) {
619612 // if (e_debug_check(PC)) {
@@ -695,8 +688,6 @@ unsigned int DoExec(TNode *G, unsigned *pLastXKey)
695688 hitimer_t TimeStartExec ;
696689 if (debug_level ('e' )) TimeStartExec = GETTSC ();
697690#endif
698- /* these flags need to be checked only once for the node */
699- G -> flags &= ~(F_SPEC |F_LEAV );
700691 /* if there is just one compiled instruction inhibition
701692 should be ignored unconditionally if signals and traps
702693 were already ignored, e.g. two "sti"s in a row */
@@ -706,22 +697,25 @@ unsigned int DoExec(TNode *G, unsigned *pLastXKey)
706697 flg = Exec_pre (ecpu );
707698#if !defined(ASM_DUMP ) && !defined(SINGLESTEP )
708699 /* try fast inner loop if nothing special is going on */
709- if (!tfset && !block_inhibit && !debug_level ('e' )) {
700+ if (!tfset && !block_inhibit && !debug_level ('e' ) &&
701+ !(seqflg & (F_SPEC |F_LEAV ))) {
710702 while (1 ) {
711703 ePC = ExecOne (G , & mem_ref , & flg , ecpu , pLastXKey );
712- if (TheCPU .err || exit_pending () ||
713- (seqflg & (F_INHI |F_SLFJ |F_SPEC |F_LEAV )))
704+ if (TheCPU .err || exit_pending ())
714705 break ;
715706 G = FindTree (ePC );
716707 if (!G || !GoodNode (G ))
717708 break ;
718- seqflg = G -> flags ;
719709 }
720710 } else
721711#endif
712+ {
713+ /* these flags need to be checked only once for the node */
714+ G -> flags &= ~(F_SPEC |F_LEAV );
722715 ePC = ExecOne (G , & mem_ref , & flg , ecpu , pLastXKey );
716+ }
723717 // G is unreliable (maybe deleted) past this point!
724- Exec_post (flg , mem_ref , seqflg );
718+ Exec_post (flg , mem_ref );
725719
726720 if (debug_level ('e' )) {
727721#if PROFILE >= 2
@@ -745,14 +739,27 @@ unsigned int DoExec(TNode *G, unsigned *pLastXKey)
745739 /* exit_pending at this point is non-zero if there was ANY signal,
746740 * not just a SIGALRM
747741 */
748- if (((seqflg & F_INHI ) || (exit_pending () & exit_INHI )) && !block_inhibit ) {
749- /* ignore signals and traps for movss/popss */
750- CEmuStat |= CeS_INHI ;
751- if (exit_pending () & exit_INHI )
752- exit_pending_and (~exit_INHI );
753- } else {
754- CEmuStat &= ~CeS_INHI ;
755- HandleEmuSignals (tfset );
742+ CEmuStat &= ~CeS_INHI ;
743+ if (TheCPU .err ) {
744+ /* CPU exceptions override everything else */
745+ exit_pending_w (0 );
746+ }
747+ else if (exit_pending () || tfset ) {
748+ /* TheCPU.eip points to the first instruction of the last
749+ executed block, except for real-mode retf, which neither
750+ inhibits interrupts nor causes forever loops */
751+ TNode * LastG = FindTree (LONG_CS + TheCPU .eip );
752+ seqflg = LastG ? LastG -> flags : 0 ;
753+ if ((seqflg & F_INHI ) && !block_inhibit )
754+ /* ignore signals and traps for movss/popss */
755+ CEmuStat |= CeS_INHI ;
756+ else
757+ HandleEmuSignals (tfset );
758+ /* checking for infinite loops, flagged in JumpGen() */
759+ if ((seqflg & F_SLFJ ) && !(EFLAGS & (VIF |IF |TF ))) {
760+ error ("!Forever loop!\n" );
761+ leavedos_main (0xebfe );
762+ }
756763 }
757764
758765#if defined(SINGLESTEP )
0 commit comments