*-----------------------------------------------------------
Title[Stack.mc...November 23, 1982  5:12 PM...Taft];
* Stack instructions (PrincOps, chapter 5)
*-----------------------------------------------------------
%

	CONTENTS, by order of occurence

Stack primitives
	REC		Recover
	REC2		Recover Two
	DIS		Discard
	DIS2		Discard Two
	EXCH		Exchange
	DEXCH		Double Exchange
	DUP		Duplicate
	DDUP		Double Duplicate
	EXDIS		Exchange Discard

Check instructions
	BNDCK		Bounds Check
	NILCKL		Nil Check Long

Unary operations
	NEG		Negate
	INC		Increment
	DINC		Double Increment
	ADDSB		Add Signed Byte
	DEC		Decrement
	DBL		Double
	DDBL		Double Double
	TRPL		Triple
	LINT		Lengthen Integer
	SHIFTSB		Shift Signed Byte

Logical operations
	AND		And
	DAND		Double And
	IOR		Inclusive Or
	DIOR		Double Inclusive Or
	XOR		Exclusive Or
	DXOR		Double Exclusive Or
	SHIFT		Shift
	DSHIFT		Double Shift
	ROTATE		Rotate

Arithmetic operations
	ADD		Add
	SUB		Subtract
	DADD		Double Add
	DSUB		Double Subtract
	ADC		Add Double to Cardinal
	ACD		Add Cardinal to Double
	MUL		Multiply
	DMUL		Double Multiply (not implemented)
	SDIV		Signed Divide
	UDIV		Unsigned Divide
	LUDIV		Long Unsigned Divide
	SDDIV		Signed Double Divide (not implemented)
	UDDIV		Unsigned Double Divide (not implemented)
	DCMP		Double Compare
	UDCMP		Unsigned Double Compare
%

TopLevel;

*-----------------------------------------------------------
IFUR[REC, 1];				* Recover
* SP ← SP+1;
* This is legal (to a maximum of two levels):
*	1. After instructions that only pop the stack (i.e., that don't
*	   push any results onto it), or
*	2. After instructions that explicitly leave results above TOS (e.g., DIV).
*-----------------------------------------------------------
	
	StkP+1, NextOpcode;


*-----------------------------------------------------------
IFUR[REC2, 1];				* Recover Two
* SP ← SP+2;
*-----------------------------------------------------------
	
	StkP+2, NextOpcode;


*-----------------------------------------------------------
IFUR[DIS, 1];				* Discard
* SP ← SP-1;
*-----------------------------------------------------------
	
	StkP-1, NextOpcode;


*-----------------------------------------------------------
IFUR[DIS2, 1];				* Discard Two
* SP ← SP-2;
*-----------------------------------------------------------
	
	StkP-2, NextOpcode;


*-----------------------------------------------------------
IFUR[EXCH, 1];				* Exchange
* v: UNSPECIFIED ← Pop[]; u: UNSPECIFIED ← Pop[]; Push[v]; Push[u];
*-----------------------------------------------------------

	T← Stack&-1, Call[StackSwap];
StackGetsQ:
	Stack← Q, NextOpcode;


*-----------------------------------------------------------
IFUR[DEXCH, 1];				* Double Exchange
* v: LONG UNSPECIFIED ← PopLong[]; u: LONG UNSPECIFIED ← PopLong[];
* PushLong[v]; PushLong[u];
*-----------------------------------------------------------

	T← Stack&-2, Call[StackSwap];
	T← Stack&-2;
	Stack&+2← T, Cnt← Stack&+2;
	Stack&+1← Cnt, Branch[StackGetsQ];

Subroutine;

StackSwap:
	Stack&+1← T, Q← Stack&+1, Return;

TopLevel;

*-----------------------------------------------------------
IFUR[DUP, 1];				* Duplicate
* u: UNSPECIFIED ← Pop[]; Push[u]; Push[u];
*-----------------------------------------------------------

	Stack+1← Stack&+1, NextOpcode;


*-----------------------------------------------------------
IFUR[DDUP, 1];				* Double Duplicate
* u: LONG UNSPECIFIED ← PopLong[]; PushLong[u]; PushLong[u];
*-----------------------------------------------------------

	T← Stack&-1;
	Stack+2← Stack&+2, Branch[ExitPushT];


*-----------------------------------------------------------
IFUR[EXDIS, 1];				* Exchange Discard
* u: UNSPECIFIED ← Pop[]; [] ← Pop[]; Push[u];
*-----------------------------------------------------------

	Stack-1← Stack&-1, NextOpcode;


*-----------------------------------------------------------
IFUR[BNDCK, 1];				* Bounds Check
* range: CARDINAL ← Pop[]; index: CARDINAL ← Pop[]; Push[index];
* IF index>=range THEN BoundsTrap[];
*-----------------------------------------------------------

	T← Stack&-1;
	PD← T-(Stack)-1;		* Carry← 1 iff index<range
	T← sBoundsTrap, DblBranch[DoFaultT, NoFaultF, Carry'];


*-----------------------------------------------------------
NewOp; ESCEntry[NILCKL],		* NIL Check Long
* p: LONG POINTER ← PopLong[]; PushLong[p]; IF p=NIL THEN PointerTrap[];
*-----------------------------------------------------------

	T← Stack&-1;
	PD← T OR (Stack&+1);
	T← sPointerTrap, DblBranch[DoFaultT, NoFaultF, ALU=0];
NoFaultF:
	NextOpcode;
DoFaultT:
	Branch[SavePCAndTrap];

*-----------------------------------------------------------
IFUR[NEG, 1, N[0]];			* Negate
* i: INTEGER ← Pop[]; Push[-i];
*-----------------------------------------------------------

	Stack← (ID)-(Stack), NextOpcode;


*-----------------------------------------------------------
IFUR[INC, 1, N[1]];			* Increment
* s: CARDINAL ← Pop[]; Push[s+1];
IFUR[ADDSB, 2, SignExtend];		* Add Signed Byte
* i: INTEGER ← Pop[]; Push[i+SignExtend[GetCodeByte[]]];
*-----------------------------------------------------------

	Stack← (ID)+(Stack), NextOpcode;


*-----------------------------------------------------------
IFUR[DINC, 1, N[1]];			* Double Increment
* s: LONG CARDINAL ← PopLong[]; PushLong[s+1];
*-----------------------------------------------------------

	T← ID, StkP-1, Branch[ADCTail];


*-----------------------------------------------------------
IFUR[DEC, 1];				* Decrement
* s: CARDINAL ← Pop[]; Push[s-1];
*-----------------------------------------------------------

	Stack← (Stack)-1, NextOpcode;


*-----------------------------------------------------------
IFUR[DBL, 1];				* Double
* u: UNSPECIFIED ← Pop[]; Push[Shift[u, 1]];
*-----------------------------------------------------------

	Stack← (Stack)+(Stack), NextOpcode;


*-----------------------------------------------------------
IFUR[DDBL, 1];				* Double Double
* u: LONG UNSPECIFIED ← PopLong[]; PushLong[LongShift[u, 1]];
*-----------------------------------------------------------

	T← Stack&-1;
	Stack&+1← (Stack&+1)+(Stack&+1), Branch[AddTail];


*-----------------------------------------------------------
IFUR[TRPL, 1];				* Triple
* s: CARDINAL ← Pop[]; Push[s*3];
*-----------------------------------------------------------

	T← (A← Stack) LSH 1, Branch[AddTail]; * Carry← 0

*-----------------------------------------------------------
NewOp; ESCEntry[LINT];			* Lengthen Integer
* i: INTEGER ← Pop[]; Push[i]; Push[IF i<0 THEN -1 ELSE 0];
*-----------------------------------------------------------

	T← RSH[Stack&+1, 17];
	Stack← (0S)-T, NextOpcode;


*-----------------------------------------------------------
IFUR[SHIFTSB, 2, SignExtend];		* Shift Signed Byte
* u: UNSPECIFIED ← Pop[]; shift: INTEGER ← SignExtend[GetCodeByte];
* IF shift NOT IN [-15..15] THEN ERROR;  -- asserted, not required to be checked
* Push[Shift[u, shift]];
*-----------------------------------------------------------

	T← ID, Branch[ShiftStackByT];


*-----------------------------------------------------------
IFUR[AND, 1];				* And
* v: UNSPECIFIED ← Pop[]; u: UNSPECIFIED ← Pop[]; Push[And[u, v]];
*-----------------------------------------------------------

	T← Stack&-1;
AndTail:
	Stack← (Stack) AND T, NextOpcode;


*-----------------------------------------------------------
NewOp; ESCEntry[DAND];			* Double And
* v: LONG UNSPECIFIED ← PopLong[]; u: LONG UNSPECIFIED ← PopLong[];
* PushLong[LongAnd[u, v]];
*-----------------------------------------------------------

	T← Stack&-1, Call[QGStackPop2];
	Stack&+1← (Stack&+1) AND Q, Branch[AndTail];


*-----------------------------------------------------------
IFUR[IOR, 1];				* Inclusive Or
* v: UNSPECIFIED ← Pop[]; u: UNSPECIFIED ← Pop[]; Push[Or[u, v]];
*-----------------------------------------------------------

	T← Stack&-1;
IorTail:
	Stack← (Stack) OR T, NextOpcode;


*-----------------------------------------------------------
NewOp; ESCEntry[DIOR];			* Double Inclusive Or
* v: LONG UNSPECIFIED ← PopLong[]; u: LONG UNSPECIFIED ← PopLong[];
* PushLong[LongOr[u, v]];
*-----------------------------------------------------------

	T← Stack&-1, Call[QGStackPop2];
	Stack&+1← (Stack&+1) OR Q, Branch[IorTail];

*-----------------------------------------------------------
NewOp; ESCEntry[XOR],			* Exclusive Or
* v: UNSPECIFIED ← Pop[]; u: UNSPECIFIED ← Pop[]; Push[Xor[u, v]];
*-----------------------------------------------------------

	T← Stack&-1;
XorTail:
	Stack← (Stack) XOR T, NextOpcode;


*-----------------------------------------------------------
NewOp; ESCEntry[DXOR];			* Double Exclusive Or
* v: LONG UNSPECIFIED ← PopLong[]; u: LONG UNSPECIFIED ← PopLong[];
* PushLong[LongXor[u, v]];
*-----------------------------------------------------------

	T← Stack&-1, Call[QGStackPop2];
	Stack&+1← (Stack&+1) XOR Q, Branch[XorTail];


*-----------------------------------------------------------
IFUR[SHIFT, 1];				* Shift
* shift: INTEGER ← Pop[]; u: UNSPECIFIED ← Pop[]; Push[Shift[u, shift]];
* Shifts left if shift>0, right if shift<0.
*-----------------------------------------------------------

	T← Stack&-1;

* If left shift (shift >= 0): LCY[T, R, shift mod 20B] -- T=0 in both cases
* If right shift (shift < 0): LCY[R, T, shift mod 20B]
ShiftStackByT:
	RTemp0← LSH[T, 10], Branch[.+2, ALU<0]; * Position shift to count field
	PD← (17S)-T, Branch[.+2];	* Test for shift > 15
	PD← (17S)+T;			* Test for shift < -15
	T← (RTemp0) XOR (20000C), Branch[ShiftGr15, ALU<0];
ShiftStackWithShCT:
	T← A0, ShC← T;
ShiftTail:
	Stack← ShiftNoMask[Stack];
RestoreStdShC:
	ShC← StdShC, NextOpcode;

* |Shift| > 15
ShiftGr15:
	Stack← A0, NextOpcode;

*-----------------------------------------------------------
NewOp; ESCEntry[DSHIFT],		* Double Shift
* shift: INTEGER ← Pop[]; u: LONG UNSPECIFIED ← PopLong[]; PushLong[LongShift[u, shift]];
*-----------------------------------------------------------

	RTemp0← T;			* Placement; ESCEntry: T = STK[StkP]
	T← T+(37C), StkP-2;		* See if shift IN [-37B..37B]
	PD← T-(77C);
	T← DPF[RTemp0, 4, 10],		* Position shift to ShC count field
		Branch[DShiftZero, Carry]; * Branch if out of range
	RTemp0← LSH[RTemp0, 13],	* Position 20 bit to sign
		Branch[DShiftRight, R<0]; * Branch if shift negative

* Left shift.  Set up ShC for LCY[T, R, shift MOD 20B]
	T← T OR (20000C);
	T← A0, ShC← T, RTemp0, DblBranch[DShL0to17, DShL20to37, R>=0];

* Right shift.  Set up ShC for LCY[R, T, shift MOD 20B]
DShiftRight:
	T← T OR (10000C), StkP+1;
	T← A0, ShC← T, RTemp0, DblBranch[DShR1to17, DShR20to37, R<0];

* Shift IN [0..17] (left shift).  LCY[T, R, shift MOD 20B].
* StkP addresses low-order word; T=0
DShL0to17:
	Stack&+1← ShiftNoMask[Stack&+1], Q← Stack&+1; * low← LCY[0, low, shift MOD 20B]
	T← Q, Branch[ShiftTail];	* T← low; high← LCY[low, high, shift MOD 20B]

* Shift IN [20..37] (left shift).  LCY[T, R, shift MOD 20B].
* StkP addresses low-order word
DShL20to37:
	T← Stack&+1← A0, Q← Stack&+1;	* low← 0
	Stack← Q, Branch[ShiftTail];	* high← low; high← LCY[0, low, shift MOD 20B]

* Shift IN [-1..-20] (right shift).  LCY[R, T, shift MOD 20B].
* StkP addresses high-order word; T=0
DShR1to17:
	Stack&-1← ShiftNoMask[Stack&-1], Q← Stack&-1; * high← LCY[high, 0, shift MOD 20B]
	T← Q;				* T← high
RShiftTail:
	Stack&+1← ShiftNoMask[Stack&+1], * low← LCY[low, high, shift MOD 20B]
		Branch[RestoreStdShC];

* Shift IN [-21..-37] (right shift).  LCY[R, T, shift MOD 20B].
* StkP addresses high-order word
DShR20to37:
	T← Stack&-1← A0, Q← Stack&-1;	* high← 0
	Stack← Q, Branch[RShiftTail];	* low← high; low← LCY[high, 0, shift MOD 20B]

* Shift NOT IN [-37B..37B].  Just set the answer to zero.
DShiftZero:
	Stack← T← A0, Branch[ExitPushT];


*-----------------------------------------------------------
NewOp; ESCEntry[ROTATE];		* Rotate
* rotate: INTEGER ← Pop[]; u: UNSPECIFIED ← Pop[]; Push[Rotate[u, shift]];
* Rotates left if shift>0, right if shift<0.
*-----------------------------------------------------------

* Set to perform LCY[R, R, shift mod 20B]
	T← DPF[Stack&-1, 4, 10], Branch[ShiftStackWithShCT];

*-----------------------------------------------------------
IFUR[ADD, 1];				* Add
* t: CARDINAL ← Pop[]; s: CARDINAL ← Pop[]; Push[s+t];
*-----------------------------------------------------------

	T← A← Stack&-1;			* Carry← 0 (so AddTail can be used by DADD)
AddTail:
	Stack← (Stack)+T, XorSavedCarry, NextOpcode;


*-----------------------------------------------------------
IFUR[SUB, 1];				* Subtract
* t: CARDINAL ← Pop[]; s: CARDINAL ← Pop[]; Push[s-t];
*-----------------------------------------------------------

	T← (Stack&-1)-(0C);		* Carry← 1 (so SubTail can be used by DSUB)
SubTail:
	Stack← (Stack)-T-1, XorSavedCarry, NextOpcode;


*-----------------------------------------------------------
IFUR[DADD, 1];				* Double Add
* t: LONG CARDINAL ← PopLong[]; s: LONG CARDINAL ← PopLong[]; PushLong[s+t];
*-----------------------------------------------------------

	T← Stack&-1, Call[QGStackPop2];
DAddTail:
	Stack&+1← (Stack&+1)+Q, Branch[AddTail];


*-----------------------------------------------------------
IFUR[DSUB, 1];				* Double Subtract
* t: LONG CARDINAL ← PopLong[]; s: LONG CARDINAL ← PopLong[]; PushLong[s-t];
*-----------------------------------------------------------

	T← Stack&-1, Call[QGStackPop2];
	Stack&+1← (Stack&+1)-Q, Branch[SubTail];


*-----------------------------------------------------------
IFUR[ADC, 1];				* Add Double to Cardinal
* t: CARDINAL ← Pop[]; s: LONG CARDINAL ← PopLong[]; PushLong[s+LONG[t]];
*-----------------------------------------------------------

	T← Stack&-2;
ADCTail:				* Here from DINC
	Stack&+1← (Stack&+1)+T;
	Stack← A← Stack, XorSavedCarry, NextOpcode;


*-----------------------------------------------------------
IFUR[ACD, 1];				* Add Cardinal to Double
* t: LONG CARDINAL ← PopLong[]; s: CARDINAL ← Pop[]; PushLong[LONG[s]+t];
*-----------------------------------------------------------

	T← Stack&-1;
	Stack&-1← A0, Q← Stack&-1, Branch[DAddTail];


*-----------------------------------------------------------
QGStackPop2:				* Executes "Q← Stack&-2"
* Common part of setup for several Double logical and arithmetic instructions.
*-----------------------------------------------------------
Subroutine;
	Q← Stack&-2, Return;
TopLevel;

*-----------------------------------------------------------
IFUR[MUL, 1];				* Multiply
* t: CARDINAL ← Pop[]; s: CARDINAL ← Pop[]; PushLong[LONG[s]*t]; [] ← Pop[];
* Note: computes 32-bit result and leaves high word above TOS.
*-----------------------------------------------------------

	Q← Stack&-1;
	T← Stack&+1, Call[MulSub];	* T,,Q ← Q*T
	Stack&-1← T, Branch[StackGetsQ],
		DispTable[1, 2, 2];	* Squash leftover Multiply dispatch


*-----------------------------------------------------------
ESCOpcodeUnimpl[DMUL];			* Double Multiply
* t: LONG CARDINAL ← PopLong[]; s: LONG CARDINAL ← PopLong[];
* PushLong[LONG[s]*t];
* Note: returns only low 32 bits of (potentially) 64-bit result.
*-----------------------------------------------------------


*-----------------------------------------------------------
MulSub:			* Unsigned 16-bit by 16-bit multiply subroutine
* Entry conditions:
*	T = multiplicand
*	Q = multiplier
* Exit conditions:
*	T = high-order 16 bits of product
*	Q = low-order 16 bits of product
* May leave a Q[14] dispatch pending, which must be squashed by the caller.
* Clobbers MulDivArg
*-----------------------------------------------------------
Subroutine;

	MulDivArg← Q;
	MulDivArg, Cnt← 16S, Branch[.+2, R odd];
	MulDivArg← A0, Multiply, Branch[M0];
	MulDivArg← A0, Multiply, Branch[M1];

*-----------------------------------------------------------
DispTable[4];

* here after Q[14] was 0 (no add) and continue
M0:	MulDivArg← (A← MulDivArg), Multiply, DblBranch[M0E, M0, Cnt=0&-1];
* here after Q[14] was 0 (no add) and exit
M0E:	MulDivArg← (A← MulDivArg), Multiply, Branch[MXIT0];

* here after Q[14] was 1 (add) and continue
M1:	MulDivArg← (MulDivArg)+T, Multiply, DblBranch[M0E, M0, Cnt=0&-1];
* here after Q[14] was 1 (add) and exit
	MulDivArg← (MulDivArg)+T, Multiply, Branch[MXIT0];
*-----------------------------------------------------------

* This squashes one Multiply dispatch, but there is still one pending.
MXIT0:	T← MulDivArg, DispTable[1, 2, 2], Return;

TopLevel;

*-----------------------------------------------------------
NewOp; ESCEntry[SDIV];			* Signed Divide
* k: INTEGER ← Pop[]; j: INTEGER ← Pop[];
* IF k=0 THEN DivZeroTrap[];
* Push[j/k]; Push[j MOD k]; [] ← Pop[];
*-----------------------------------------------------------

	MulDivArg← Stack&-1, Branch[.+2, R>=0];
	MulDivArg← (0S)-(MulDivArg);	* Divisor negative, make positive
	T← Stack&+1;
	RTemp0← (Stack&-1) XOR T, Branch[.+2, ALU>=0]; * Remember XOR of signs
	T← (0S)-T;			* Dividend negative
	T← A0, Q← T;

* DivSub computes [Q: quotient, T: remainder] ← (T,,Q) / MulDivArg
* It does not return but traps directly if an overflow occurs.
	Call[DivSub];

	Stack+1← T, Stack&+1, Branch[.+2, R>=0]; * Remainder should have sign of dividend
	Stack← (0S)-(Stack);
	T← Q, RTemp0, Branch[.+2, R>=0]; * Quotient sign should be XOR of operand signs
	T← (0S)-T;
	Stack-1← T, NextOpcode;


*-----------------------------------------------------------
NewOp; ESCEntry[UDIV],			* Unsigned Divide
* t: CARDINAL ← Pop[]; s: CARDINAL ← Pop[];
* IF t=0 THEN DivZeroTrap[];
* Push[s/t]; Push[s MOD t]; [] ← Pop[];
*-----------------------------------------------------------

	T← A0;
	MulDivArg← Stack&-1, Branch[DoLongUDiv];


*-----------------------------------------------------------
NewOp; ESCEntry[LUDIV];			* Long Unsigned Divide
* t: CARDINAL ← Pop[]; s: LONG CARDINAL ← PopLong[];
* IF t=0 THEN DivZeroTrap[];
* IF HighHalf[s]>=t THEN DivideCheckTrap[];
* Push[LowHalf[s/LONG[t]]; Push[LowHalf[s MOD LONG[t]]; [] ← Pop[];
*-----------------------------------------------------------

	MulDivArg← Stack&-1;
	T← Stack&-1;

* DivSub computes [Q: quotient, T: remainder] ← (T,,Q) / MulDivArg
* It does not return but traps directly if an overflow occurs.
DoLongUDiv:
	Q← Stack&+1, Call[DivSub];
	Stack&-1← T, Branch[StackGetsQ]; * Leave remainder above TOS


*-----------------------------------------------------------
ESCOpcodeUnimpl[SDDIV];			* Signed Double Divide
* k: LONG INTEGER ← PopLong[]; j: LONG INTEGER ← PopLong[];
* IF k=0 THEN DivZeroTrap[];
* PushLong[j/k]; PushLong[j MOD k]; [] ← PopLong;
*-----------------------------------------------------------


*-----------------------------------------------------------
ESCOpcodeUnimpl[UDDIV];			* Unsigned Double Divide
* t: LONG CARDINAL ← PopLong[]; s: LONG CARDINAL ← PopLong[];
* IF t=0 THEN DivZeroTrap[];
* PushLong[s/t]; PushLong[s MOD t]; [] ← PopLong;
*-----------------------------------------------------------

*-----------------------------------------------------------
DivSub:			 * Unsigned 32-bit by 16-bit divide
* Enter: T,,Q = dividend
*	MulDivArg = divisor
* Normal exit: T=remainder, Q=quotient 
* Failure: does not return but rather generates one of the following traps:
*	sDivZeroTrap	division by zero
*	sDivCheckTrap	high half of dividend >= divisor
* Clobbers MulDivArg, DivTemp
*-----------------------------------------------------------
Subroutine;

	PD← T-(MulDivArg);		* Trap if T >= MulDivArg (unsigned)
	PD← MulDivArg, Branch[DivTrap, Carry];
	Cnt← 17S, PD← T, Branch[Dneg, ALU<0];
	T← T-(MulDivArg), Divide, DblBranch[NormalExit, D3, Cnt=0&-1];
D2:
	T← T+(MulDivArg), Divide, Branch[NormalExit, Cnt=0&-1];
D3:
	Branch[D2, Carry'];
	T← T-(MulDivArg), Divide, Branch[D3, Cnt#0&-1];
NormalExit:
	Branch[DaddLabel, Carry'];
	T-(MulDivArg), Divide;
	T← T-(MulDivArg), DblBranch[FinalAdd, OKExit, ALU<0];
DaddLabel:
	T+(MulDivArg), Divide;
	T← T+(MulDivArg), Branch[FinalAdd, ALU<0];
OKExit:
	Return;
FinalAdd:
	T← T+(MulDivArg), Return;
Dneg:
	DivTemp← T+T, Branch[Dneg1, ALU<0];
Dneg0:
	T← A← T, Divide, Branch[Fudge2, Cnt=0&-1];
	DivTemp← T+T, DblBranch[Dneg1, Dneg0, R<0];
Dneg1:
	T← T-(MulDivArg), Divide, Branch[Fudge3, Cnt=0&-1];
Dneg3:
	PD← T, Branch[.+2, Carry'];
	DivTemp← T+T, DblBranch[Dneg1, Dneg0, ALU<0];
	T← T+(MulDivArg), Divide, Branch[Fudge4, Cnt=0&-1];
DnegG:
	PD← T, Branch[.+2, ALU>=0];
	T← T-(MulDivArg), CDivide, DblBranch[Fudge4, DnegG, Cnt=0&-1];
	DivTemp← T+T, DblBranch[Dneg1, Dneg0, ALU<0];
Fudge2:
	PD← T-(MulDivArg);
Fudge21:
	Branch[F23, Carry];
F22:
	PD← A← T, Divide, Return;
F23:
	PD← T-(MulDivArg), Divide, Branch[Fudge42];
Fudge3:
	PD← T-(MulDivArg), Branch[Fudge21, Carry];
	PD← A← T, CDivide, Branch[FinalAdd];
Fudge4:
	PD← T-(MulDivArg), Branch[.+2, ALU<0];
	DblBranch[F23, F22, Carry];
	PD← T-(MulDivArg), CDivide;
Fudge42:
	T← T-(MulDivArg), Return;

TopLevel;
DivTrap:
	Branch[.+2, ALU#0];
	T← sDivZeroTrap, Branch[SavePCAndTrap];
	T← sDivCheckTrap, Branch[SavePCAndTrap];

*-----------------------------------------------------------
IFUR[DCMP, 1];				* Double Compare
* t: LONG INTEGER ← PopLong[]; u: LONG INTEGER ← PopLong[];
* Push[SELECT TRUE FROM
*   s>t => 1,
*   s=t => 0,
*   s<t => -1,
*   ENDCASE];
*-----------------------------------------------------------

* Complement the signs of both 32-bit operands, then do an unsigned compare.
	T← (Stack&-2) XOR (100000C);
	Stack&+1← (Stack&+1) XOR (100000C), Branch[UnsignedComp1];


*-----------------------------------------------------------
IFUR[UDCMP, 1];				* Unsigned Double Compare
* t: LONG CARDINAL ← PopLong[]; u: LONG CARDINAL ← PopLong[];
* Push[SELECT TRUE FROM
*   s>t => 1,
*   s=t => 0,
*   s<t => -1,
*   ENDCASE];
*-----------------------------------------------------------

	T← Stack&-1;			* Compute s-t
UnsignedComp1:
	T← Stack&-2, Q← T;
	T← (Stack&+1)-T;
	Stack← (Stack)-Q-1, XorSavedCarry;

* Have carry out of last (high) subtraction iff s>=t
	T← (Stack&-1) OR T, Branch[.+2, Carry];
	Stack← T-T-1, NextOpcode;	* s<t, return -1

* T=0 iff s=t
	PD← T-1;			* Carry out unless T=0
	Stack← (ID)-1, XorSavedCarry, NextOpcode; * ID=1 here; return 0 or 1