*-----------------------------------------------------------
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;