From 253e9deea7023104931fbca8e409388bbbd75336 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 18 May 2016 09:02:22 -0700 Subject: [PATCH] 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 --- VAX/vax_cpu.c | 2 +- VAX/vax_cpu1.c | 8 ++++---- VAX/vax_defs.h | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index 2a4e8ed3..82abeddb 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -2279,7 +2279,7 @@ for ( ;; ) { case RSB: temp = Read (SP, L_LONG, RA); /* get top of stk */ SP = SP + 4; /* incr stk ptr */ - JUMP (temp); + JUMP_ALWAYS (temp); if (sim_switches & SWMASK ('R')) { if (step_out_nest_level <= 0) ABORT (SCPE_STEP); diff --git a/VAX/vax_cpu1.c b/VAX/vax_cpu1.c index 868b501b..bd68441b 100644 --- a/VAX/vax_cpu1.c +++ b/VAX/vax_cpu1.c @@ -408,7 +408,7 @@ if (spamask & CALL_S) { /* CALLS? */ } PSL = (PSL & ~(PSW_DV | PSW_FU | PSW_IV | PSW_T)) | /* reset PSW */ (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 */ } @@ -1132,7 +1132,7 @@ acc = ACC_MASK (KERN); /* new mode is kernel */ Write (SP - 4, oldpsl, L_LONG, WA); /* push old PSL */ Write (SP - 8, PC, L_LONG, WA); /* push old PC */ SP = SP - 8; /* update stk ptr */ -JUMP (newpc & ~3); /* change PC */ +JUMP_ALWAYS (newpc & ~3); /* change PC */ in_ie = 0; /* out of flows */ return 0; } @@ -1171,7 +1171,7 @@ Write (tsp - 4, PSL | cc, L_LONG, WA); /* push PSL */ SP = tsp - 12; /* set new stk */ PSL = (mode << PSL_V_CUR) | (PSL & PSL_IPL) | /* set new PSL */ (cur << PSL_V_PRV); /* IPL unchanged */ -JUMP (newpc & ~03); /* set new PC */ +JUMP_ALWAYS (newpc & ~03); /* set new PC */ return 0; /* cc = 0 */ } @@ -1243,7 +1243,7 @@ else { SISR = SISR | SISR_2; } } -JUMP (newpc); /* set new PC */ +JUMP_ALWAYS (newpc); /* set new PC */ return newpsl & CC_MASK; /* set new cc */ } diff --git a/VAX/vax_defs.h b/VAX/vax_defs.h index a62bfdc6..6b103798 100644 --- a/VAX/vax_defs.h +++ b/VAX/vax_defs.h @@ -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 */ #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 JUMP_ALWAYS(d) do {PCQ_ENTRY; PC = (d); FLUSH_ISTR; } while (0) /* 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 BRANCHW(d) do {PCQ_ENTRY; PC = PC + SXTW (d); FLUSH_ISTR; CHECK_FOR_IDLE_LOOP; } while (0)