{6. Jump Instructions} {File name: Jump.mc Description: PrincOps version 3.0 Jump microcode for Dandelion, Author: R. Garner (Based on Wildflower microcode by R. Levin), Created: April 10, 1979, Daniels, 21-Jun-83 15:52:52, Implement JD*, Daniels, 15-Jun-83 17:37:52, New Instruction Set, Sandman, November 9, 1981 8:10 AM, New Instruction Set, Last Edited: R. Garner, April 11, 1980 6:56 PM, Last Edited: Johnsson, August 27, 1980 4:49 PM} { Jn Jump n = 2-8 JB Jump Byte JW Jump Word CATCH Catch JEP Jump Equal Pair JEB Jump Equal Byte JEBB Jump Equal Byte Byte JNEP Jump Not Equal Pair JNEB Jump Not Equal Byte JNEBB Jump Not Equal Byte Byte JZn Jump Zero n = 3-4 JZB Jump Zero Byte JNZn Jump Not Zero n = 3-4 JNZB Jump Not Zero Byte JDEB Jump Double Equal Byte JDNEB Jump Double Not Equal Byte JLB Jump Less Byte JLEB Jump Less Equal Byte JGB Jump Greater Byte JGEB Jump Greater Equal Byte JULB Jump Unsigned Less Byte JULEB Jump Unsigned Less Equal Byte JUGB Jump Unsigned Greater Byte JUGEB Jump Unsigned Greater Equal Byte JIB Jump Indexed Byte JIW Jump Indexed Word JS Jump Stack } {Note: Update of the Map flag bits (which occurs first time page is touched) adds 2 clicks to the pagecross times given below} {***************************************************************************** Overview: The jump code is written assuming the jump will be taken and a page boundary will not be crossed. It also assumes the PC (in particular, the real page part) is always correct (see comments at Refill microcode). The jump instructions increment the PC before testing for any page faults. If the page we're jumping to is mapped out, then, after the page fault trap, we should execute the byte code we're jumping to instead of restarting the Jump instruction. Register Useage: L2[0-1] number of pops required 0 => 0; 1,2 => 1; 3 => 2 L2[0,2] PC increment L2[3] 0 L2 should be examined at the PageFault location (if L0=JRemap) to determine how to fixup the stack pointer. Note that the PC increment field is not used for Jn, JB, &JW since they always jump. *****************************************************************************} {L2 codes used to indicate stackP and PC fixups} Set[L2.Pop0IncrX, 0 {00xx}]; {will be 2 with Jn cross} {Jn, JB, JW} Set[L2.Pop1Incr1, 4 {0100}]; {JZn, JNZn} Set[L2.Pop1Incr2, 6 {0110}]; {JZB, JNZB, JEP, JNEP} Set[L2.Pop1Incr3, 0A {1010}]; {JEBB, JNEBB} Set[L2.Pop2Incr2, 0C {1100}]; {JEB,JNEB,J(/U)(L/LE/G/GE)B} Set[L2.Pop2Incr3, 0E {1110}]; {JIB, JIW} {6.1 Unconditional Jumps} {**************************************************************************** CATCH ****************************************************************************} @CATCH: MAR _ PC _ [rhPC, PC+1], push, GOTO[JnPos], c1, opcode[200'b]; {***************************************************************************** Jn, n=2-8 *****************************************************************************} @J2: MAR _ PC _ [rhPC, PC+1], push, GOTO[JnPos], c1,opcode[201'b]; @J3: MAR _ PC _ [rhPC, PC+1+PC16], push, GOTO[JnPos], c1,opcode[202'b]; @J4: MAR _ PC _ [rhPC, PC+2], push, GOTO[JnPos], c1,opcode[203'b]; @J5: MAR _ PC _ [rhPC, PC+2+PC16], push, GOTO[JnPos], c1,opcode[204'b]; @J6: MAR _ PC _ [rhPC, PC+3], push, GOTO[JnPos], c1,opcode[205'b]; @J7: MAR _ PC _ [rhPC, PC+3+PC16], push, GOTO[JnPos], c1,opcode[206'b]; @J8: MAR _ PC _ [rhPC, PC+4], push, GOTO[JnPos], c1,opcode[207'b]; {***************************************************************************** JB *****************************************************************************} @JB: L2 _ L2.Pop0IncrX, c1,opcode[210'b]; jb: T _ ib RShift1, XLDisp, GOTO[jT], c2; {***************************************************************************** JW *****************************************************************************} @JW: T _ ib, XLDisp, L2 _ L2.Pop0IncrX, c1,opcode[211'b]; jw: T _ T LRot8, push, BRANCH[jwPos, jwNeg, 1], c2; jwPos: T _ RShift1 (T or ib), SE_0, XLDisp, GOTO[jwtos], c3; jwNeg: T _ RShift1 (T or ib), SE_1, XLDisp, GOTO[jwtos], c3; jwtos: PC _ PC and 0FF, BRANCH[jwEven, jwOdd, 2], c1; jwEven: Q _ PC + T, GOTO[jwCross], c2; jwOdd: Q _ PC + T + PC16, GOTO[jwCross], c2; jwCross: PC _ Q, STK _ TOS, L0 _ L0.JRemap, GOTO[UpdatePC], c3; {***************************************************************************** JDEB *****************************************************************************} @JDEB: T _ STK, pop, c1,opcode[236'b]; [] _ STK xor TOS, ZeroBr, c2; TOS _ STK, pop, BRANCH[JDEBa, JDEBb], c3; JDEBa: Xbus _ 1, XLDisp, L2 _ L2.Pop2Incr2, GOTO[jc22], c1; JDEBb: [] _ STK xor T, NZeroBr, L2 _ L2.Pop2Incr2, GOTO[jc22], c1; {***************************************************************************** JDNEB *****************************************************************************} @JDNEB: T _ STK, pop, c1,opcode[237'b]; [] _ STK xor TOS, NZeroBr, c2; TOS _ STK, pop, BRANCH[JDNEBa, JDNEBb], c3; JDNEBa: Xbus _ 1, XLDisp, L2 _ L2.Pop2Incr2, GOTO[jc22], c1; JDNEBb: [] _ STK xor T, ZeroBr, L2 _ L2.Pop2Incr2, GOTO[jc22], c1; {***************************************************************************** JEP *****************************************************************************} @JEP: [] _ alpha.left xor TOS, NZeroBr, L2 _ L2.Pop1Incr2, c1,opcode[212'b]; jp: T _ alpha.right RShift1, XLDisp, BRANCH[jpT, jpF], c2; jpF: L2Disp, push, Xbus _ ib, CANCELBR[NoJump, 3], c3; jpT: T _ T + 2, BRANCH[jpEven, jpOdd, 2], c3; jpEven: MAR _ PC _ [rhPC, PC + T], push, Xbus _ ib, GOTO[JPos], c1; jpOdd: MAR _ PC _ [rhPC, PC + T + PC16], push, Xbus _ ib, GOTO[JPos], c1; {***************************************************************************** JEB *****************************************************************************} @JEB: [] _ STK xor TOS, NZeroBr, L2 _ L2.Pop2Incr2, c1,opcode[213'b]; jc22: T _ ib RShift1, XLDisp, BRANCH[jT, jF], c2; {***************************************************************************** JEBB *****************************************************************************} @JEBB: [] _ ib xor TOS, NZeroBr, L2 _ L2.Pop1Incr3, c1,opcode[214'b]; jc13: T _ ib RShift1, XLDisp, BRANCH[jT, jF], c2; {***************************************************************************** JNEP *****************************************************************************} @JNEP: [] _ alpha.left xor TOS, ZeroBr, L2 _ L2.Pop1Incr2, GOTO[jp], c1, opcode[215'b]; {***************************************************************************** JNEB *****************************************************************************} @JNEB: [] _ STK xor TOS, ZeroBr, L2 _ L2.Pop2Incr2, GOTO[jc22], c1, opcode[216'b]; {***************************************************************************** JNEBB *****************************************************************************} @JNEBB: [] _ ib xor TOS, ZeroBr, L2 _ L2.Pop1Incr3, GOTO[jc13], c1,opcode[217'b]; {***************************************************************************** JZn, n = 3-4 *****************************************************************************} @JZ3: [] _ TOS, NZeroBr, L2 _ L2.Pop1Incr1, c1,opcode[230'b]; jz3: T _ 3 RShift1, XLDisp, BRANCH[jT, jF], c2; @JZ4: [] _ TOS, NZeroBr, L2 _ L2.Pop1Incr1, c1,opcode[231'b]; jz4: T _ 4 RShift1, XLDisp, BRANCH[jT, jF], c2; {***************************************************************************** JZB *****************************************************************************} @JZB: [] _ TOS, NZeroBr, L2 _ L2.Pop1Incr2, c1,opcode[232'b]; jc12: T _ ib RShift1, XLDisp, BRANCH[jT, jF], c2; {***************************************************************************** JNZn, n = 3-4 *****************************************************************************} @JNZ3: [] _ TOS, ZeroBr, L2 _ L2.Pop1Incr1, GOTO[jz3], c1,opcode[233'b]; @JNZ4: [] _ TOS, ZeroBr, L2 _ L2.Pop1Incr1, GOTO[jz4], c1,opcode[234'b]; {***************************************************************************** JNZB *****************************************************************************} @JNZB: [] _ TOS, ZeroBr, L2 _ L2.Pop1Incr2, GOTO[jc12], c1,opcode[235'b]; {***************************************************************************** JLB *****************************************************************************} {Jump if jk : k-j is neg & no overflow OR k-j is pos & overflow} @JGB: T _ STK {T_j}, c1,opcode[222'b]; T _ TOS - T {T_k-j}, PgCrOvDisp, c2; Jg: T _ ~T, BRANCH[jNoOv, jOv, 2], c3; {***************************************************************************** JGEB *****************************************************************************} {Jump if j>=k : j-k is pos & no overflow OR j-k is neg & overflow} @JGEB: T _ STK {T_j}, c1,opcode[221'b]; T _ T - TOS {T_j-k}, PgCrOvDisp, GOTO[Jle], c2; {***************************************************************************** JLEB *****************************************************************************} {Jump if j<=k : k-j is pos & no overflow OR k-j is neg & overflow} @JLEB: T _ STK {T_j}, c1,opcode[223'b]; T _ TOS - T {T_k-j}, PgCrOvDisp, c2; Jle: BRANCH[jNoOv, jOv, 2], c3; jNoOv: [] _ T, NegBr, L2 _ L2.Pop2Incr2, GOTO[jc22], c1; jOv: [] _ ~T, NegBr, L2 _ L2.Pop2Incr2, GOTO[jc22], c1; {The Unsigned jumps place Carry into the sign bit and share the signed jump code} {***************************************************************************** JULB *****************************************************************************} {Jump if uu : no carry from v-u} @JUGB: T _ STK, c1,opcode[226'b]; T _ DARShift1 (TOS - T), GOTO[Jle], c2; {***************************************************************************** JUGEB *****************************************************************************} {Jump if u>=v : carry from u-v} @JUGEB: T _ STK, c1,opcode[225'b]; T _ DARShift1 (T - TOS), GOTO[Jg], c2; {***************************************************************************** JULEB *****************************************************************************} {Jump if u<=v : carry from v-u} @JULEB: T _ STK, c1,opcode[227'b]; T _ DARShift1 (TOS - T), GOTO[Jg], c2; {***************************************************************************** JIB *****************************************************************************} Set[L2.JIB, 0]; Set[L2.JIW, 4]; @JIB: T _ STK{index}, L2 _ L2.JIB, c1,opcode[240'b]; TT _ RShift1 T{index/2}, GOTO[jiCom], c2; {***************************************************************************** JIW *****************************************************************************} @JIW: T _ STK{index}, L2 _ L2.JIW, c1,opcode[241'b]; TT _ T{index}, GOTO[jiCom], c2; jiCom: [] _ T - TOS {index-limit}, CarryBr, c3; T _ ib, BRANCH[$, jiNoJump], c1; T _ T LRot8, L0_L0.JI, c2; T _ T or ib {base}, L1_L1.None, c3; T _ T + TT, c1; Q _ UvC{code base}, c2; rhTT _ UvChigh, c3; {Set the ibPtr to empty} Map _ Q _ [rhTT, Q + T], IBPtr_1, c1; Xbus _ ib, c2; Rx _ rhRx _ MD, XRefBr, c3; jiRedo: MAR _ [rhRx, Q+0], BRANCH[jiMapUD, $], c1, RLMFRet[L0.JI]; Xbus _ STK, XLDisp, L2Disp, c2; IB _ MD {ibFront_disp}, DISP3[jibL, 2], c3; jibL: T _ 0, L2_L2.Pop2Incr3, GOTO[ji], c1, at[2,8,jibL]; jibR: T _ 0, Xbus _ ib, L2_L2.Pop2Incr3, GOTO[ji], c1, at[3,8,jibL]; jiwL: T _ ib, XLDisp, L2_L2.Pop2Incr3, GOTO[ji], c1, at[6,8,jibL]; jiwR: T _ ib, XLDisp, L2_L2.Pop2Incr3, GOTO[ji], c1, at[7,8,jibL]; ji: T _ T LRot8, push, BRANCH[jwPos, jwNeg, 1], c2; jiMapUD: CALL[RLMapFix] {will return to jiRedo}, c2; jiNoJump: Xbus _ ib, PC _ PC+PC16, c2; Xbus _ L2.Pop2Incr3, XDisp, push, GOTO[NoJump], c3; {***************************************************************************** JS Jump Stack in Xfer *****************************************************************************} @JS: TT _ UvC, XC2npcDisp, push, c1, at[9,10,ESC1n]; PC _ TOS RShift1, IBPtr_1, Xbus_STK, XDisp, BRANCH[JSa,JSb,0E], c2; JSa: Q _ PC, Cin_pc16, BRANCH[JSc, JSd, 2], c3; JSb: Q _ PC, BRANCH[JSc, JSd, 2], c3; JSc: TT _ TT and ~0FF, GOTO[JSe], c1; JSd: TT _ TT and ~0FF, Cin_pc16, GOTO[JSe], c1; JSe: UvPCpage _ TT, L2_L2.Pop0IncrX, GOTO[jwCross], c2; {***************************************************************************** jump common code *****************************************************************************} {The abscence of a pending branch at jT causes a jump and the prescence causes the jump to be aborted. T contains the word offset and TT the word offset for backwards jumps + 1.} jT: TT _ 7F - T, DISP2[JPosEven], c3; jF: L2Disp, push {point to u}, CANCELBR[NoJump, 3], c3; {Fetch the first destination word, check for a page crossing, and prepare to save TOS into STK.} JPosEven: MAR _ PC _ [rhPC, PC + T], push, GOTO[JPos], c1, at[0,4,JPosEven]; JPosOdd: MAR _ PC _ [rhPC, PC + T + PC16], push, GOTO[JPos], c1, at[1,4,JPosEven]; JNegEven: MAR _ PC _ [rhPC, PC - TT - 1], push, GOTO[JNeg], c1, at[2,4,JPosEven]; JNegOdd: MAR _ PC _ [rhPC, PC - TT - PC16], push, GOTO[JNeg], c1, at[3,4,JPosEven]; {Dispatch on the stackP fixup (L2[0-1]) and the new value of pc16. Also save TOS into STK. Place the first destination word into IB, or in the case of a page cross, prepare to remap the PC as in a "Buffer Empty" refill. (see Refill.mc). If the jump doesn't page fault, reset uPCCross.} JPos: STK _ TOS, Xbus_0, L2Disp, XC2npcDisp, BRANCH[jPNoCross, jP1Cross, 1], c2; JNeg: STK _ TOS, Xbus_0, L2Disp, XC2npcDisp, BRANCH[jNNoCross, jN1Cross, 1], c2; JnPos: STK _ TOS, L2 _ L2.Pop0IncrX, Xbus_0, XC2npcDisp, DISP2[jnPNoCross], c2; jnPNoCross: IB _ MD, pop, DISP4[JPtr1Pop0, 2], c3, at[0,4,jnPNoCross]; jPNoCross: IB _ MD, pop, DISP4[JPtr1Pop0, 2], c3; jNNoCross: IB _ MD, pop, DISP4[JPtr1Pop0, 2], c3; {A page cross ocurred on the first destination word: goto the Refill page cross code. If a page fault occurs L2 encodes the required stack pointer fixup. The high half of Q contains the page displacement. The low half of PC points to the word of the destination page. pc16 is correct. Note that for all the jump "byte" instructions and Jn the page displacement in Q is either +1 or -1. For JW, Q is arbitrary. (See Refill.mc.) Control for no Map update will go: UpdatePCx (in Refill.mc), JCross (in Refill.mc), JRedo, JPtr1Pop0....} jnP1Cross: Q _ 0FF + 1, L0 _ L0.JRemap, CANCELBR[UpdatePC, 0F], c3, at[2,4,jnPNoCross]; jP1Cross: Q _ 0FF + 1, L0 _ L0.JRemap, CANCELBR[UpdatePC, 0F], c3; jN1Cross: Q _ ~0FF, L0 _ L0.JRemap, CANCELBR[UpdatePC, 0F], c3; {Fetch the second destination word, set the instruction buffer pointer, and prepare to load TOS. If a PageCross occurs, treat it like the "Buffer Not Empty" refill case. The Stack fixup code assumes that TOS has been saved into TOS for jumps which have no stack arguments (Jn, JB, JW). Note that the Stack at JPtr1Pop0 (etc..) should be identical to the Stack at entry to the particular Jump instruction, execpt TOS has been saved into STK. When control reaches RCross or NoRCross (in Refill.mc) the stack appears as if the jump instruction has finished. If there is a page fault (via RCross), there will be no stack fixup.} JPtr1Pop0: MAR _ [rhPC, PC + 1], IBPtr_1, push, GOTO[Jgo], c1, at[2,10,JPtr1Pop0]; JPtr1Pop1: MAR _ [rhPC, PC + 1], IBPtr_1, GOTO[Jgo], c1, at[6,10,JPtr1Pop0]; JPtr1Pop1x: MAR _ [rhPC, PC + 1], IBPtr_1, GOTO[Jgo], c1, at[0A,10,JPtr1Pop0]; JPtr1Pop2: MAR _ [rhPC, PC + 1], IBPtr_1, pop, GOTO[Jgo], c1, at[0E,10,JPtr1Pop0]; JPtr0Pop0: MAR _ [rhPC, PC + 1], IBPtr_0, push, GOTO[Jgo], c1, at[3,10,JPtr1Pop0]; JPtr0Pop1: MAR _ [rhPC, PC + 1], IBPtr_0, GOTO[Jgo], c1, at[7,10,JPtr1Pop0]; JPtr0Pop1x: MAR _ [rhPC, PC + 1], IBPtr_0, GOTO[Jgo], c1, at[0B,10,JPtr1Pop0]; JPtr0Pop2: MAR _ [rhPC, PC + 1], IBPtr_0, pop, GOTO[Jgo], c1, at[0F,10,JPtr1Pop0]; Jgo: TOS _ STK, AlwaysIBDisp, L0 _ L0.NERefill.Set, DISP2[NoRCross], c2; {Don't jump: Save TOS into STK and increment the PC and prepare to load TOS according to the Jump instruction which is encoded in L2. Note that Jn, JB, or JW do not come through NoJump since they always jump.} NoJump: STK _ TOS, pop, DISP4[jPop1Incr1, 1], c1; jPop1Incr1: PC _ PC+PC16, IBDisp, GOTO[SLa], c2, at[5,10,jPop1Incr1]; jPop1Incr2: PC _ PC+1, IBDisp, GOTO[SLa], c2, at[7,10,jPop1Incr1]; jPop1Incr3: PC _ PC+1+PC16, IBDisp, GOTO[SLa], c2, at[0B,10,jPop1Incr1]; jPop2Incr2: PC _ PC+1, IBDisp, pop, GOTO[SLa], c2, at[0D,10,jPop1Incr1]; jPop2Incr3: PC _ PC+1{+PC16 at jiNoJump}, IBDisp, pop, GOTO[SLa], c2, at[0F,10,jPop1Incr1];