All VAX: Fix idle/inifinite loop detection for instructions with side effects

Recent enhancements to idle/infinite loop detection generalized handling
of detecting 'loop to self' cases.  This was done without considering that
some instructions have side effects (i.e. change other state like the stack
pointer) and thus aren't merely loop to self cases.

This problem was reported in #315
This commit is contained in:
Mark Pizzolato 2016-05-18 09:02:22 -07:00
parent 0c2bc4c617
commit 253e9deea7
3 changed files with 6 additions and 5 deletions

View file

@ -2279,7 +2279,7 @@ for ( ;; ) {
case RSB: case RSB:
temp = Read (SP, L_LONG, RA); /* get top of stk */ temp = Read (SP, L_LONG, RA); /* get top of stk */
SP = SP + 4; /* incr stk ptr */ SP = SP + 4; /* incr stk ptr */
JUMP (temp); JUMP_ALWAYS (temp);
if (sim_switches & SWMASK ('R')) { if (sim_switches & SWMASK ('R')) {
if (step_out_nest_level <= 0) if (step_out_nest_level <= 0)
ABORT (SCPE_STEP); ABORT (SCPE_STEP);

View file

@ -408,7 +408,7 @@ if (spamask & CALL_S) { /* CALLS? */
} }
PSL = (PSL & ~(PSW_DV | PSW_FU | PSW_IV | PSW_T)) | /* reset PSW */ PSL = (PSL & ~(PSW_DV | PSW_FU | PSW_IV | PSW_T)) | /* reset PSW */
(spamask & (PSW_DV | PSW_FU | PSW_IV | PSW_T)); (spamask & (PSW_DV | PSW_FU | PSW_IV | PSW_T));
JUMP (newpc); /* set new PC */ JUMP_ALWAYS(newpc); /* set new PC */
return spamask & (CC_MASK); /* return cc's */ return spamask & (CC_MASK); /* return cc's */
} }
@ -1132,7 +1132,7 @@ acc = ACC_MASK (KERN); /* new mode is kernel */
Write (SP - 4, oldpsl, L_LONG, WA); /* push old PSL */ Write (SP - 4, oldpsl, L_LONG, WA); /* push old PSL */
Write (SP - 8, PC, L_LONG, WA); /* push old PC */ Write (SP - 8, PC, L_LONG, WA); /* push old PC */
SP = SP - 8; /* update stk ptr */ SP = SP - 8; /* update stk ptr */
JUMP (newpc & ~3); /* change PC */ JUMP_ALWAYS (newpc & ~3); /* change PC */
in_ie = 0; /* out of flows */ in_ie = 0; /* out of flows */
return 0; return 0;
} }
@ -1171,7 +1171,7 @@ Write (tsp - 4, PSL | cc, L_LONG, WA); /* push PSL */
SP = tsp - 12; /* set new stk */ SP = tsp - 12; /* set new stk */
PSL = (mode << PSL_V_CUR) | (PSL & PSL_IPL) | /* set new PSL */ PSL = (mode << PSL_V_CUR) | (PSL & PSL_IPL) | /* set new PSL */
(cur << PSL_V_PRV); /* IPL unchanged */ (cur << PSL_V_PRV); /* IPL unchanged */
JUMP (newpc & ~03); /* set new PC */ JUMP_ALWAYS (newpc & ~03); /* set new PC */
return 0; /* cc = 0 */ return 0; /* cc = 0 */
} }
@ -1243,7 +1243,7 @@ else {
SISR = SISR | SISR_2; SISR = SISR | SISR_2;
} }
} }
JUMP (newpc); /* set new PC */ JUMP_ALWAYS (newpc); /* set new PC */
return newpsl & CC_MASK; /* set new cc */ return newpsl & CC_MASK; /* set new cc */
} }

View file

@ -611,6 +611,7 @@ enum opcodes {
/* Instructions which have side effects (ACB, AOBLSS, BBSC, BBCS, etc.) can't be an idle loop so avoid the idle check */ /* Instructions which have side effects (ACB, AOBLSS, BBSC, BBCS, etc.) can't be an idle loop so avoid the idle check */
#define BRANCHB_ALWAYS(d) do {PCQ_ENTRY; PC = PC + SXTB (d); FLUSH_ISTR; } while (0) #define BRANCHB_ALWAYS(d) do {PCQ_ENTRY; PC = PC + SXTB (d); FLUSH_ISTR; } while (0)
#define BRANCHW_ALWAYS(d) do {PCQ_ENTRY; PC = PC + SXTW (d); FLUSH_ISTR; } while (0) #define BRANCHW_ALWAYS(d) do {PCQ_ENTRY; PC = PC + SXTW (d); FLUSH_ISTR; } while (0)
#define JUMP_ALWAYS(d) do {PCQ_ENTRY; PC = (d); FLUSH_ISTR; } while (0)
/* Any basic branch instructions could be an idle loop */ /* Any basic branch instructions could be an idle loop */
#define BRANCHB(d) do {PCQ_ENTRY; PC = PC + SXTB (d); FLUSH_ISTR; CHECK_FOR_IDLE_LOOP; } while (0) #define BRANCHB(d) do {PCQ_ENTRY; PC = PC + SXTB (d); FLUSH_ISTR; CHECK_FOR_IDLE_LOOP; } while (0)
#define BRANCHW(d) do {PCQ_ENTRY; PC = PC + SXTW (d); FLUSH_ISTR; CHECK_FOR_IDLE_LOOP; } while (0) #define BRANCHW(d) do {PCQ_ENTRY; PC = PC + SXTW (d); FLUSH_ISTR; CHECK_FOR_IDLE_LOOP; } while (0)