*----------------------------------------------------------- Title[Jump.mc...November 7, 1982 3:32 PM...Taft]; * Jump instructions (PrincOps, chapter 6) *----------------------------------------------------------- % CONTENTS, by order of occurence Unconditional jumps Jn Jump n JB Jump Byte JW Jump Word JS Jump Stack CATCH Catch Equality jumps JZn Jump Zero n JNZn Jump Not Zero n JZB Jump Zero Byte JNZB Jump Not Zero Byte JEB Jump Equal Byte JNEB Jump Not Equal Byte JEP Jump Equal Pair JNEP Jump Not Equal Pair JEBB Jump Equal Byte Byte JNEBB Jump Not Equal Byte Byte Signed jumps JLB Jump Less Byte JLEB Jump Less Equal Byte JGB Jump Greater Byte JGEB Jump Greater Equal Byte Unsigned jumps JULB Jump Unsigned Less Byte JULEB Jump Unsigned Less Equal Byte JUGB Jump Unsigned Greater Byte JUGEB Jump Unsigned Greater Equal Byte Indexed jumps JIB Jump Indexed Byte JIW Jump Indexed Word Commonly-used exit sequences JumpRelativeT Jump T bytes relative to the current PC SetPCAndJump Restart IFU with new PC in T Subroutines StackPopMinusT Executes PD← (Stack&-1)-T % TopLevel; *----------------------------------------------------------- IFUR[J2, 2]; * (regular opcodes are faster than jumps) IFUJ[J3, 1, Disp[3]]; * Jump n IFUJ[J4, 1, Disp[4]]; IFUJ[J6, 1, Disp[6]]; IFUJ[J8, 1, Disp[10]]; * PC ← savedPC + n; IFUJ[JB, 2, SignExtend]; * Jump Byte * PC ← savedPC + SignExtend[GetCodeByte[]]; IFUR[CATCH, 2]; * Catch * [] ← GetCodeByte[]; *----------------------------------------------------------- NextOpcode; *----------------------------------------------------------- IFUP[JW, 3]; * Jump Word * PC ← savedPC + GetCodeWord[]; *----------------------------------------------------------- T← ShiftRMask[RTemp0], RisID; * LSH[ID, 10] T← (ID) OR T, Branch[JumpRelativeT]; * T← alpha,,beta *----------------------------------------------------------- NewOp; ESCEntry[JS]; * Jump Stack * PC ← Pop[]; *----------------------------------------------------------- PCF← Stack&-1, Branch[ExitJump]; *----------------------------------------------------------- IFUR[JZ3, 1, N[3]]; * Jump Zero n IFUR[JZ4, 1, N[4]]; * data: UNSPECIFIED ← Pop[]; IF data=0 THEN PC ← savedPC + n; IFUR[JZB, 2, SignExtend]; * Jump Zero Byte * data: UNSPECIFIED ← Pop[]; disp: BYTE ← GetCodeByte[]; * IF data=0 THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- PD← Stack&-1, Branch[JETest]; *----------------------------------------------------------- IFUR[JNZ3, 1, N[3]]; * Jump Not Zero n IFUR[JNZ4, 1, N[4]]; * data: UNSPECIFIED ← Pop[]; IF data#0 THEN PC ← savedPC + n; IFUR[JNZB, 2, SignExtend]; * Jump Not Zero Byte * data: UNSPECIFIED ← Pop[]; disp: BYTE ← GetCodeByte[]; * IF data#0 THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- PD← Stack&-1, Branch[JNETest]; *----------------------------------------------------------- IFUR[JEB, 2, SignExtend]; * Jump Equal Byte * v: UNSPECIFIED ← Pop[]; u: UNSPECIFIED ← Pop[]; disp: BYTE ← GetCodeByte[]; * IF u=v THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- T← Stack&-1, Call[StackPopMinusT]; JETest: T← (ID)-(PCX')-1, DblBranch[JNewT, JContF, ALU=0]; JNewT: PCF← T, Branch[ExitJump]; JContF: NextOpcode; *----------------------------------------------------------- IFUR[JNEB, 2, SignExtend]; * Jump Not Equal Byte * v: UNSPECIFIED ← Pop[]; u: UNSPECIFIED ← Pop[]; disp: BYTE ← GetCodeByte[]; * IF u#v THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- T← Stack&-1, Call[StackPopMinusT]; JNETest: T← (ID)-(PCX')-1, DblBranch[JNewF, JContT, ALU#0]; JNewF: PCF← T, Branch[ExitJump]; JContT: NextOpcode; *----------------------------------------------------------- IFUR[JEP, 2, PackedAlpha]; * Jump Equal Pair * data: UNSPECIFIED ← Pop[]; pair: NibblePair ← GetCodeByte[]; * IF data=pair.left THEN PC ← savedPC + pair.right + 4; *----------------------------------------------------------- PD← (ID)#(Stack&-1); T← (ID)-(PCX')-1, Branch[.+2, ALU=0]; NextOpcode; T← T+(4C), Branch[SetPCAndJump]; *----------------------------------------------------------- IFUR[JNEP, 2, PackedAlpha]; * Jump Not Equal Pair * data: UNSPECIFIED ← Pop[]; pair: NibblePair ← GetCodeByte[]; * IF data#pair.left THEN PC ← savedPC + pair.right + 4; *----------------------------------------------------------- PD← (ID)#(Stack&-1); T← (ID)-(PCX')-1, Branch[.+2, ALU#0]; NextOpcode; T← T+(4C), Branch[SetPCAndJump]; *----------------------------------------------------------- IFUR[JEBB, 3]; * Jump Equal Byte Byte * data: UNSPECIFIED ← Pop[]; byte: UNSPECIFIED ← GetCodeByte[]; * disp: UNSPECIFIED ← GetCodeByte[]; * IF data=byte THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- PD← (ID)#(Stack&-1); T← (ID)-(200C), Branch[.+2, ALU=0]; NextOpcode; * Note: must SignExtend[disp] manually, as disp is the beta byte and the * hardware sign-extension works only on the alpha byte. T← T XOR (177600C), Branch[JumpRelativeT]; *----------------------------------------------------------- IFUR[JNEBB, 3]; * Jump Not Equal Byte Byte * data: UNSPECIFIED ← Pop[]; byte: UNSPECIFIED ← GetCodeByte[]; * disp: UNSPECIFIED ← GetCodeByte[]; * IF data#byte THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- PD← (ID)#(Stack&-1); T← (ID)-(200C), Branch[.+2, ALU#0]; NextOpcode; * Note: must SignExtend[disp] manually, as disp is the beta byte and the * hardware sign-extension works only on the alpha byte. T← T XOR (177600C), Branch[JumpRelativeT]; *----------------------------------------------------------- IFUR[JLB, 2, SignExtend]; * Jump Less Byte * disp: BYTE ← GetCodeByte[]; * k: INTEGER ← Pop[]; j: INTEGER ← Pop[]; * IF j<k THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- T← (Stack&-1)-(0C), Branch[JLEBTail]; * Carry← 1 *----------------------------------------------------------- IFUR[JLEB, 2, SignExtend]; * Jump Less Equal Byte * disp: BYTE ← GetCodeByte[]; * k: INTEGER ← Pop[]; j: INTEGER ← Pop[]; * IF j<=k THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- T← A← Stack&-1; * Carry← 0 JLEBTail: PD← T-(Stack&-1), XorSavedCarry, Branch[SignedIneqTest]; *----------------------------------------------------------- IFUR[JGB, 2, SignExtend, N[1]]; * Jump Greater Byte * disp: BYTE ← GetCodeByte[]; * k: INTEGER ← Pop[]; j: INTEGER ← Pop[]; * IF j>k THEN PC ← savedPC + SignExtend[disp]; IFUR[JGEB, 2, SignExtend, N[0]]; * Jump Greater Equal Byte * disp: BYTE ← GetCodeByte[]; * k: INTEGER ← Pop[]; j: INTEGER ← Pop[]; * IF j>=k THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- PD← (ID)-1, Q← Stack&-1; * Carry← 1 for JGB, 0 for JGEB PD← (Stack&-1)-Q, XorSavedCarry; SignedIneqTest: Q← PCX', Branch[.+2, ALU<0]; T← (ID)-Q-1, DblBranch[JNewT, JContF, Overflow']; T← (ID)-Q-1, DblBranch[JContT, JNewF, Overflow']; *----------------------------------------------------------- IFUR[JULB, 2, SignExtend]; * Jump Unsigned Less Byte * disp: BYTE ← GetCodeByte[]; * v: CARDINAL ← Pop[]; u: CARDINAL ← Pop[]; * IF u<v THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- T← (Stack&-1)-(0C), Branch[JULEBTail]; * Carry← 1 *----------------------------------------------------------- IFUR[JULEB, 2, SignExtend]; * Jump Unsigned Less Equal Byte * disp: BYTE ← GetCodeByte[]; * v: CARDINAL ← Pop[]; u: CARDINAL ← Pop[]; * IF u<v THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- T← A← Stack&-1; * Carry← 0 JULEBTail: PD← T-(Stack&-1), XorSavedCarry, Branch[UnsignedIneqTest]; *----------------------------------------------------------- IFUR[JUGB, 2, SignExtend, N[1]]; * Jump Unsigned Greater Byte * disp: BYTE ← GetCodeByte[]; * v: CARDINAL ← Pop[]; u: CARDINAL ← Pop[]; * IF u<v THEN PC ← savedPC + SignExtend[disp]; IFUR[JUGEB, 2, SignExtend, N[0]]; * Jump Unsigned Greater Equal Byte * disp: BYTE ← GetCodeByte[]; * v: CARDINAL ← Pop[]; u: CARDINAL ← Pop[]; * IF u<v THEN PC ← savedPC + SignExtend[disp]; *----------------------------------------------------------- PD← (ID)-1, Q← Stack&-1; * Carry← 1 for JUGB, 0 for JUGEB PD← (Stack&-1)-Q, XorSavedCarry; UnsignedIneqTest: T← (ID)-(PCX')-1, DblBranch[JContT, JNewF, Carry']; *----------------------------------------------------------- IFUR[JIB, 3, MemBase[CB], N[0]]; * Jump Indexed Byte * base: CARDINAL ← GetCodeWord[]; * limit: CARDINAL ← Pop[]; index: CARDINAL ← Pop[]; * IF index<limit THEN { * disp: BytePair ← ReadCode[base+index/2]; * PC ← savedPC + (IF (index MOD 2)=0 THEN disp.left ELSE disp.right)}; IFUR[JIW, 3, MemBase[CB], N[1]]; * Jump Indexed Word * base: CARDINAL ← GetCodeWord[]; * limit: CARDINAL ← Pop[]; index: CARDINAL ← Pop[]; * IF index<limit THEN { * disp: CARDINAL ← ReadCode[base+index]; * PC ← savedPC + disp}; *----------------------------------------------------------- T← Stack&-1, Call[StackPopMinusT]; * Note that N will distinguish JIB (0) from JIW (1). RTemp0← ID, Branch[JIBWInRange, Carry']; * RTemp0← N * Out of range, fall through to the next opcode. A← ID, Branch[JContF]; * Consume alpha before IFUJump * In range, evaluate the indexed jump. JIBWInRange: T← ShiftRMask[StackNoUfl&+1], RIsID; * LSH[ID, 10] T← RTemp0← (ID) OR T, * T← alpha,,beta DblBranch[JIWFetch, JIBFetch, R odd]; JIBFetch: T← (Stack) RSH 1; T← (RTemp0)+T, Call[FetchGetsT]; * T← base + index/2 T← MD, Stack&-1, Branch[.+2, R odd]; T← RSH[T, 10], Branch[JumpRelativeT]; * Left (even) byte T← T AND (377C), Branch[JumpRelativeT]; * Right (odd) byte JIWFetch: T← T+(Stack&-1), Call[FetchGetsT]; * T← base+index T← MD, Branch[JumpRelativeT]; *----------------------------------------------------------- JumpRelativeT: * Jump T bytes relative to the current PC *----------------------------------------------------------- T← T-(PCX')-1, Branch[SetPCAndJump]; *----------------------------------------------------------- SetPCAndJump: * Restart IFU with new PC in T *----------------------------------------------------------- PCF← T, Global; ExitJump: Branch[@J2]; * Nop required by hardware *----------------------------------------------------------- StackPopMinusT: * Executes PD← (Stack&-1)-T *----------------------------------------------------------- Subroutine; PD← (Stack&-1)-T, Return;