diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index 36a1e3ad..827276d2 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -227,11 +227,6 @@ R[rn] = rl; \ R[rn + 1] = rh; \ } -#define CHECK_FOR_IDLE_LOOP if (PC == fault_PC) { /* to self? */ \ - if (PSL_GETIPL (PSL) == 0x1F) /* int locked out? */ \ - ABORT (STOP_LOOP); /* infinite loop */ \ - cpu_idle (); /* idle loop */ \ - } #define HIST_MIN 64 @@ -2185,12 +2180,10 @@ for ( ;; ) { case BRB: BRANCHB (brdisp); /* branch */ - CHECK_FOR_IDLE_LOOP; break; case BRW: BRANCHW (brdisp); /* branch */ - CHECK_FOR_IDLE_LOOP; break; case BSBB: @@ -2304,7 +2297,7 @@ for ( ;; ) { CC_IIZP_L (r); /* set cc's */ V_SUB_L (r, 1, op0); /* test for ovflo */ if (r >= 0) /* if >= 0, branch */ - BRANCHB (brdisp); + BRANCHB_ALWAYS (brdisp); break; case SOBGTR: @@ -2313,7 +2306,7 @@ for ( ;; ) { CC_IIZP_L (r); /* set cc's */ V_SUB_L (r, 1, op0); /* test for ovflo */ if (r > 0) /* if >= 0, branch */ - BRANCHB (brdisp); + BRANCHB_ALWAYS (brdisp); break; /* AOB instructions - op limit.rl,idx.ml,disp.bb @@ -2331,7 +2324,7 @@ for ( ;; ) { CC_IIZP_L (r); /* set cc's */ V_ADD_L (r, 1, op1); /* test for ovflo */ if (r < op0) /* if < lim, branch */ - BRANCHB (brdisp); + BRANCHB_ALWAYS (brdisp); break; case AOBLEQ: @@ -2340,7 +2333,7 @@ for ( ;; ) { CC_IIZP_L (r); /* set cc's */ V_ADD_L (r, 1, op1); /* test for ovflo */ if (r <= op0) /* if < lim, branch */ - BRANCHB (brdisp); + BRANCHB_ALWAYS (brdisp); break; /* ACB instructions - op limit.rx,add.rx,index.mx,disp.bw @@ -2359,7 +2352,7 @@ for ( ;; ) { CC_IIZP_B (r); /* set cc's */ V_ADD_B (r, op1, op2); /* test for ovflo */ if ((op1 & BSIGN)? (SXTB (r) >= SXTB (op0)): (SXTB (r) <= SXTB (op0))) - BRANCHW (brdisp); + BRANCHW_ALWAYS (brdisp); break; case ACBW: @@ -2368,7 +2361,7 @@ for ( ;; ) { CC_IIZP_W (r); /* set cc's */ V_ADD_W (r, op1, op2); /* test for ovflo */ if ((op1 & WSIGN)? (SXTW (r) >= SXTW (op0)): (SXTW (r) <= SXTW (op0))) - BRANCHW (brdisp); + BRANCHW_ALWAYS (brdisp); break; case ACBL: @@ -2377,7 +2370,7 @@ for ( ;; ) { CC_IIZP_L (r); /* set cc's */ V_ADD_L (r, op1, op2); /* test for ovflo */ if ((op1 & LSIGN)? (r >= op0): (r <= op0)) - BRANCHW (brdisp); + BRANCHW_ALWAYS (brdisp); break; /* CASE instructions - casex sel.rx,base.rx,lim.rx @@ -2454,26 +2447,22 @@ for ( ;; ) { case BBSC: if (op_bb_x (opnd, 0, acc)) /* br if clr, set */ - BRANCHB (brdisp); + BRANCHB_ALWAYS (brdisp); break; case BBCS: if (!op_bb_x (opnd, 1, acc)) /* br if set, clr */ - BRANCHB (brdisp); + BRANCHB_ALWAYS (brdisp); break; case BLBS: - if (op0 & 1) { /* br if bit set */ + if (op0 & 1) /* br if bit set */ BRANCHB (brdisp); - CHECK_FOR_IDLE_LOOP; - } break; case BLBC: - if ((op0 & 1) == 0) { /* br if bit clear */ + if ((op0 & 1) == 0) /* br if bit clear */ BRANCHB (brdisp); - CHECK_FOR_IDLE_LOOP; - } break; /* Extract field instructions - ext?v pos.rl,size.rb,base.wb,dst.wl @@ -3532,7 +3521,7 @@ static struct os_idle os_tab[] = { { "OPENBSDOLD", VAX_IDLE_QUAD }, { "OPENBSD", VAX_IDLE_BSDNEW }, { "QUASIJARUS", VAX_IDLE_QUAD }, - { "32V", VAX_IDLE_QUAD }, + { "32V", VAX_IDLE_VMS }, { "ALL", VAX_IDLE_VMS|VAX_IDLE_ULTOLD|VAX_IDLE_ULT|VAX_IDLE_ULT1X|VAX_IDLE_QUAD|VAX_IDLE_BSDNEW }, { NULL, 0 } }; diff --git a/VAX/vax_defs.h b/VAX/vax_defs.h index 8e6a6577..eb553acf 100644 --- a/VAX/vax_defs.h +++ b/VAX/vax_defs.h @@ -585,10 +585,19 @@ enum opcodes { #define PCQ_MASK (PCQ_SIZE - 1) #define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = fault_PC #define GET_ISTR(d,l) d = get_istr (l, acc) -#define BRANCHB(d) PCQ_ENTRY, PC = PC + SXTB (d), FLUSH_ISTR -#define BRANCHW(d) PCQ_ENTRY, PC = PC + SXTW (d), FLUSH_ISTR -#define JUMP(d) PCQ_ENTRY, PC = (d), FLUSH_ISTR -#define CMODE_JUMP(d) PCQ_ENTRY, PC = (d) +#define CHECK_FOR_IDLE_LOOP if (PC == fault_PC) { /* to self? */ \ + if (PSL_GETIPL (PSL) == 0x1F) /* int locked out? */ \ + ABORT (STOP_LOOP); /* infinite loop */ \ + cpu_idle (); /* idle loop */ \ + } +/* 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) +/* 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) +#define JUMP(d) do {PCQ_ENTRY; PC = (d); FLUSH_ISTR; CHECK_FOR_IDLE_LOOP; } while (0) +#define CMODE_JUMP(d) do {PCQ_ENTRY; PC = (d); CHECK_FOR_IDLE_LOOP; } while (0) #define SETPC(d) PC = (d), FLUSH_ISTR #define FLUSH_ISTR ibcnt = 0, ppc = -1