ER[ARITH];

*I = 258

TARGET[ILC];

%INTEGER ARITHMETIC INSTRUCTIONS
TIMING:	ADD   M + R + 3
	ADDI  M + 1
	ADDM  M + R + 3 + W
	ADDB  M + R + 3 + W
	SUB   M + R + 4
	SUBI  M + 3
	SUBM  M + R + 3 + W
	SUBB  M + R + 3 + W
I = 6
%
ADDM:	MDR←Q←P+Q, WRESTART, SETOVPC01, GOTO[QTOMCHK];
ADDB:	LAC←MDR←Q←P+Q, WRESTART, SETOVPC01, GOTO[QTOMCHK];

SUB:	LAC←P-Q, SETOVPC01, GOTO[REMAPPC];
SUBM:	WRESTART;
	MDR←Q←P-Q, SETOVPC01, GOTO[QTOMCHK];
SUBB:	WRESTART, LAC←P-Q, GOTO[.-1];

DI[270,RARG,P+QA,SCRASH];	*ADD
DI[271,P+QA,SCRASH,SCRASH];	*ADDI
DI[272,RMWARG,ADDM,SCRASH];	*ADDM
DI[273,RMWARG,ADDB,SCRASH];	*ADDB
DI[274,RQARG,SUB,SCRASH];	*SUB
DI[275,IQARG,SUB,SCRASH];	*SUBI
DI[276,RMWQARG,SUBM,SCRASH];	*SUBM
DI[277,RMWQARG,SUBB,SCRASH];	*SUBB

%MULTIPLY BEGINS WITH ITS ARGUMENTS IN P AND Q AND RETURNS WITH ITS RESULT
IN PQ, SIGN OF ALU=SIGN OF RESULT.  THE RESULT IN PQ HAS THE SIGN IN
P[0] AND P[1] AND MAGNITUDE IN P[2,43]Q[0,43], EXCEPT WHEN BOTH ARGUMENTS
ARE 400000 000000 IN WHICH CASE P[0]=0 AND P[1]=1.

XMUL ENTERS MULLP WITH POSITIVE MULTIPLIER IN Q, POSITIVE MULTIPLICAND IN
LTEMP (EXCEPT THAT ARGS MAY BE 400000 000000).  DURING THE CALCULATION,
REGISTERS ARE USED AS FOLLOWS:
   G       TELLS WHETHER TO NEGATE THE RESULT
   LTEMP   MULTIPLICAND
   RTEMP   TAIL OF RESULT . HEAD OF MULTIPLIER
   P       HEAD OF RESULT
   Q       ALTERNATES BETWEEN LTEMP AND RTEMP
LOOP GOES 2+[X] TIMES AND PRODUCES A RESULT WHICH IS 2*[X] BITS IN MAGNITUDE.
TIMING = 4 + 2*[X+2] + (0 TO 5 DEPENDING ON ARGUMENT SIGNS)
I = 16
%

XMUL:	MDR←LTEMP←P, PQ RCY [0], BAMASK[0];
	RTEMP←Q, GOTO[.+3,ALU<0], Q←LTEMP;
	Q←RTEMP, GOTO[MULLP,ALU>=0], CLEARF[G];
	LTEMP←P-Q, Q←MDR, SETF[G], GOTO[MULLP];

	LTEMP←P-Q, Q←RTEMP, SETFB[G,ALU>=0], GOTO[MULLP,ALU>=0];
	Q←P-Q, P←LTEMP;
	GOTO[MULLP,ALU>=0], P←NULL, RTEMP←P;
*AC ARG = 400000 000000, MEMORY ARG < 0
	LTEMP←Q, Q←RTEMP, GOTO[MULLP,ALU>=0];
	SETF[OVF], GOTO[MULLP];

*P0←ALUC0 AND Q0←ALU0 DURING THE LOOP
	GOTO[.+3,X<0], DECX, (P+Q) ARSHC 1, Q←(RTEMP) RSH 1;
MULLP:	GOTO[.-1,Q ODD], RTEMP←Q, Q←LTEMP;
	GOTO[MULLP,X>=0], DECX, (P) ARSHC 1, Q←(RTEMP) RSH 1;
	RETURN[G=0], P;
	LTEMP←NOT P, P←NULL;
	Q←P-Q, P←LTEMP, DGOTO[INCP];
RALUZ:	RETURN[ALU#0], P;

%ROUTINES FOR MUL AND IMUL.
TIMING:	IMUL   M + R + 7 + MULTIPLY TIME + 1 IF RES<0
	IMULI  M + 5 + MULTIPLY TIME + 1 IF RES<0
	IMULM  M + R + 8 + MULTIPLY TIME + W + 1 IF RES<0
	IMULB  M + R + 8 + MULTIPLY TIME + W + 1 IF RES<0
	MUL    M + R + 8 + MULTIPLY TIME
	MULI   M + 6 + MULTIPLY TIME
	MULM   M + R + 8 + MULTIPLY TIME + W
	MULB   M + R + 9 + MULTIPLY TIME + W
%
%MUL LEAVES THE SIGN IN P[0] AND Q[0] AND THE MAGNITUDE IN P[1,43]Q[1,43]
OVF IS SET ONLY WHEN BOTH ARGUMENTS ARE 400000 000000.
I = 4
%
MUL:	X←42S, CALL[XMUL];
	PQ LCY [1], 2P;
	Q←(NOT Q) U (400000 000000S), GOTO[QNQ,ALU>=0];
	Q←(NOT Q) U (400000 000000S), RETURN;


%IMUL LEAVES THE LOW 44 BITS OF THE RESULT IN P AND SETS
OVF IF THE MAGNITUDE OF THE RESULT IS GREATER THAN 43 BITS.
I = 7
%
IMUL:	X←42S, CALL[XMUL];
	GOTO[.+3,ALU>=0], P;
	P+1, P←(Q) U (400000 000000S), DGOTO[.+3];
	SETFC[OVF,ALU#0], B←NOT Q, RETURN[ALU#0];
	BQ, PQ RCY [44], SAMASK[43], GOTO[.+2,ALU#0];
	RETURN[B>=0];
	SETF[OVF], RETURN;


*I = 5
RBACS:	LAC←P, INCAC, GOTO[QTOAC];
RMBAC:	LAC←Q←P, P←BQ, INCAC;
RMBAC1:	LAC←P, MAPVA←P←STEMP, ACFS, GOTO[WREFQ];
PTOACM: LAC←Q←P, MAPVA←P←STEMP, ACFS, GOTO[WREFQ];
RESTOM: Q←P, MAPVA←P←STEMP, ACFS, GOTO[WREFQ];

DI[220,RARG,IMUL,PTOAC];	*IMUL
DI[221,IMUL,PTOAC,SCRASH];	*IMULI
DI[222,RARG,IMUL,RESTOM];	*IMULM
DI[223,RARG,IMUL,PTOACM];	*IMULB
DI[224,RARG,MUL,RBACS];		*MUL
DI[225,MUL,RBACS,SCRASH];	*MULI
DI[226,RARG,MUL,RESTOM];	*MULM
DI[227,RARG,MUL,RMBAC];		*MULB

%DIVIDE ROUTINE
AT CALL TO IDIV: P CONTAINS THE DIVISOR (E OR [E]) AND Q CONTAINS THE
RIGHT-HALF OF THE DIVIDEND.  THE LEFT HALF OF THE DIVIDEND IS 0 (Q>=0) OR
-1 (Q<0).

AT CALL TO DIV:  P CONTAINS THE DIVISOR, Q THE TOP HALF OF THE DIVIDEND,
AND AC POINTS TO THE TOP HALF OF THE DIVIDEND.  THE SECOND WORD OF THE
DIVIDEND IS IN AC+1 AND ITS SIGN IS IGNORED.

IF MAG. OF THE FIRST WORD OF THE DIVIDEND IS >= MAG. OF THE DIVISOR,
THEN OVERFLOW AND NO DIVIDE OCCUR, EXCEPT WHEN BOTH OF THESE WORDS ARE -1.
IN THAT CASE OVERFLOW AND NO DIVIDE OCCURS ONLY IF THE SECOND WORD OF THE
DIVIDEND (NOT INCLUDING THE SIGN) IS 0.  IN OTHER WORDS, NO DIVIDE OCCURS
ONLY WHEN THE QUOTIENT WILL NOT FIT IN ONE WORD.  AFTER NO DIVIDE CHECKS,
ENTRY IS MADE TO "DIVPE" IF THE SIGNS OF THE DIVIDEND AND DIVISOR ARE
DIFFERENT OR TO "DIVME" IF THE SIGNS ARE THE SAME.  ARGUMENTS ARE AS FOLLOWS:
   NO. BITS OF MAGNITUDE TO BE COMPUTED IN X
   DIVISOR IN RTEMP;
   LEFT HALF OF DIVIDEND IN P[0,43];
   RIGHT-HALF OF DIVIDEND IN Q[0,42], GARBAGE IN Q[43];
   H = NOT SIGN OF DIVIDEND, G = 1.
DURING THE CALCULATION "RTEMP" HOLDS THE DIVISOR, P THE LEFT HALF OF THE
REMAINING DIVIDEND, AND "LTEMP" THE TAIL OF THE DIVIDEND CONCATENATED
WITH THE BITS OF QUOTIENT COMPUTED SO FAR.  AT THE END OF THE CALCULATION,
THE NUMBER IN P WILL BE A SIMPLE FUNCTION OF THE REMAINDER AND THE NUMBER
IN Q A SIMPLE FUNCTION OF THE QUOTIENT.  NOTE THAT 43 ITERATIONS
OF THE LOOP LCY THE DIVIDEND AND BRING A NEW BIT OF PSEUDO-QUOTIENT INTO Q,
BUT THE FINAL STEP LCY'S THE LAST BIT OF PSEUDO-QUOTIENT INTO Q WITHOUT
LCYING THE PSEUDO-REMAINDER IN P.  THE POST CORRECTION REQUIRED TO CONVERT
THE PSEUDO NUMBERS INTO REAL REMAINDER AND QUOTIENT DEPENDS ON THE SIGNS
OF THE DIVISOR (S) AND DIVIDEND (D) AS FOLLOWS:
   S  D  G  H  ENTRY  POST CORRECTIONS
   +  +  1  1  DIVME  REMAINDER=P, QUOTIENT=Q
   +  -  1  0  DIVPE  IF P+S=0, THEN REMAINDER=0, QUOTIENT=Q, ELSE
                      REMAINDER=P, QUOTIENT=Q+1
   -  -  1  0  DIVME  IF P-S=0, THEN REMAINDER=0, QUOTIENT=-Q, ELSE
                      REMAINDER=P, QUOTIENT=-Q-1=NOT Q
   -  +  1  1  DIVPE  REMAINDER=P, QUOTIENT=-Q
THE FLOATING POINT DIVIDE ROUTINE "FDVX" ENTERS AT "DIVME" OR "DIVPE"
WITH THE FIRST 8 OR 9 BITS OF PSEUDO-QUOTIENT ALREADY COMPUTED.

AT RETURN:  THE QUOTIENT IS LEFT IN Q AND REMAINDER IN P.
THE REMAINDER HAS THE SAME SIGN AS THE DIVIDEND.
Q35ALUG CAUSES Q35←(ALU0#G) ON Q LSH 1.  LDPALUH PREVENTS LOADING P WHEN
ALU0 = H.
TIMING = M + R + W + 8 + 36*3 + (1 IF DIVIDEND NEGATIVE) EXCEPT THAT
       = M + R + 6 FOR NO DIVIDE CONDITION ON IDIV (DIVISOR = 0)
       OR ON DIV (MAG. DIVISOR < MAG. L.H. OF DIVIDEND)
I = 41
%
MC[OVF&NODIV,OVF,NODIV];

	PQ LCY [1], Q LSH 1, Q35ALUG;
DIVPE:	LTEMP←Q, Q←RTEMP, DECX;
	GOTO[.-2,X>=0], P←P+Q, LDPALUH, Q←LTEMP;
	Q LSH 1, Q35ALUG, LTEMP←P, P←NULL, GOTO[.+2,H=0];
	Q←P-Q, P←LTEMP, RETURN;         *SIGN S = 1, SIGN D =0 HERE
	P←LTEMP, Q←RTEMP, MDR←Q, A1, DGOTO[.+1];
	P+Q, SAMASK[0], Q←MDR, RETURN[ALU=0];
	Q←P+Q+1, P←LTEMP, RETURN;

	PQ LCY [1], Q LSH 1, Q35ALUG;
DIVME:	LTEMP←Q, Q←RTEMP, DECX;
	GOTO[.-2,X>=0], P←P-Q, LDPALUH, Q←LTEMP;
	Q LSH 1, Q35ALUG, RETURN[H=1], MDR←P;  *SIGN S = SIGN D =0
	LTEMP←NOT Q, Q←RTEMP;   *SIGN S = SIGN D =1
	P-Q, P←NULL, Q←LTEMP;
	Q←P+Q+1, RETURN[ALU=0];
	Q←LTEMP, P←MDR, RETURN;

*FOR BYTE LISP, NODIV CASE RESULTS IN QUOTIENT=DIVIDEND, REMAINDER=0
DIVOVF:	SETSF[MD2&G], DGOTO[REMAPPC];
	P←A0, Q←LTEMP, RETURN[G=1];

DIV:	SETF[G];
	RTEMP←P, X←43S, P←LAC, INCAC, DGOTO[IDIV0];
	GOTO[DIV1,ALU>=0], Q←LAC, DECAC, NOT P;

IDIV:	AQ, X←43S;
	RTEMP←P, P←NULL, SETF[G], GOTO[IDIV1,ALU<0];
	GOTO[DIV1,ALU>=0], NOT P;

*GOTO IDIV0 WITH DIVD IN PQ, SIGN ALU = NOT SIGN DIVD, DIVS < 0 IN RTEMP
IDIV0:	Q LSH 1, GOTO[DIV2,ALU<0], Q35ALUG; *GARBAGE BIT INTO Q35=1
*FALL THROUGH FOR BOTH DIVD AND DIVS < 0.  OVF&NODIV WILL OCCUR WHEN DIVS =
*LEADING WORD OF DIVD ONLY IF NEITHER WORD OF DIVIDEND (NOT COUNTING SIGN OF
*WORD 2) IS -1
	NOT P AND NOT Q, CLEARF[H];
	LTEMP←Q, Q←RTEMP, DGOTO[DIV5,ALU=0];
	P-Q, Q←LTEMP, DGOTO[DIVME];
	SETFC[OVF&NODIV,ALU<=0], GOTO[DIVOVF,ALU<=0];

*TOP HALF OF DIVIDEND = 0 OR -1
DIV5:	SETFC[OVF&NODIV,ALU<0], GOTO[DIVOVF,ALU<0];

*POSITIVE DIVS (IN RTEMP) COMES HERE, DIVD IN PQ, SIGN ALU=NOT SIGN DIVD
DIV1:	Q LSH 1, SETFB[H,ALU<0], GOTO[DIV3,ALU<0], NOT P;
	LTEMP←Q, Q←RTEMP, DGOTO[DIV5,ALU=0];
	P+Q, Q←LTEMP, DGOTO[DIVPE];
	SETFC[OVF&NODIV,ALU<=0], GOTO[DIVOVF,ALU<=0];

*NEG. DIVISOR, POSITIVE DIVIDEND COMES HERE
DIV2:	LTEMP←Q, Q←RTEMP, SETF[H];
	P+Q, Q←LTEMP, DGOTO[DIVPE];
DIV4:	SETFC[OVF&NODIV,ALU>=0], GOTO[DIVOVF,ALU>=0];

*POS. DIVISOR, POS. DIVIDEND
DIV3:	LTEMP←Q, Q←RTEMP, DGOTO[DIV4];
	P-Q, Q←LTEMP, DGOTO[DIVME];

IDIV1:	A0, GOTO[DIV1,ALU>=0], P←-1S;
	GOTO[IDIV0], NOT P;

%FINISHING ROUTINES FOR DIVIDE AND TWO OF THE FLOATING POINT FINISHING
ROUTINES.
I = 5
%
NORML:	PQ RCY [1], Q RSH 1, ASHOVF, CALL[DNORM]; *ASHOVF CAUSES Q[0]←P[43]
SRBAC:	LAC←Q, INCAC, GOTO[PTOAC]; *QUOTIENT TO AC, REMAINDER TO AC+1

RNDM:	CALL[RND];
SRTOM:	MAPVA←P←STEMP, ACFS, GOTO[WREFQ];

SRMBAC: LAC←Q, INCAC, GOTO[RMBAC1];

DI[230,RARG,IDIV,SRBAC];	*IDIV
DI[231,IDIV,SRBAC,SCRASH];	*IDIVI
DI[232,RARG,IDIV,SRTOM];	*IDIVM
DI[233,RARG,IDIV,SRMBAC];	*IDIVB
DI[234,RARG,DIV,SRBAC];		*DIV
DI[235,DIV,SRBAC,SCRASH];	*DIVI
DI[236,RARG,DIV,SRTOM];		*DIVM
DI[237,RARG,DIV,SRMBAC];	*DIVB

%FLOATING POINT NUMBERS
POSITIVE FLOATING POINT NUMBERS HAVE THE FORM:
   B[0]=0    SIGN
   B[1,8]    EXPONENT
   B[9,35]   FRACTION
A NORMALIZED POSITIVE FLOATING POINT NUMBER HAS A "1" IN THE LEADING BIT
OF THE FRACTION.  THE CONVENTIONAL INTERPRETATION OF THE NUMBERS IS WITH
THE NUMBER 201 400000000 REPRESENTING THE VALUE 1.  IN OTHER WORDS THE
EXPONENT IS EXCESS 200.  A NEGATIVE NUMBER IS REPRESENTED BY THE TWO'S COMPLEMENT
OF ITS POSITIVE FORM (INCLUDING THE EXPONENT).

THE LEFT HALF OF A DOUBLE PRECISION NUMBER IS THE SAME FORM AS A SINGLE
PRECISION NUMBER.  HOWEVER, THE SIGN OF THE SECOND WORD IS IGNORED BY THE
HARDWARE, THE EXPONENT IS 33 LESS THAN THE POSITIVE FORM OF THE EXPONENT
IN THE FIRST WORD, AND THE FRACTION IN B[11,43] CONTINUES THE FRACTION
BEGUN IN B[11,43] OF THE FIRST WORD AND IS UNROUNDED, EXCEPT THAT IT IS LEFT 0
IF ITS EXPONENT OVERFLOWS OR UNDERFLOWS OR IF THE FRACTION IS 0.
NOTE THAT THE SIGN AND EXPONENT OF THE SECOND WORD IN A DOUBLE
PRECISION FLOATING POINT NUMBER ARE IN POSITIVE FORM EVEN THOUGH THE FRACTION
MAY CONTINUE THE NEGATIVE FORM BEGUN IN THE FIRST WORD.  THE ESOTERICA
BEHIND THIS PECULIAR FORMAT IS UNKNOWN.

* NOTE THAT THE DOUBLE PRECISION HARDWARE FOR THE KI-10
HAS A MORE REASONABLE FORMAT.  NAMELY, THE FRACTION IS CONTINUED
IN B[1,43] OF THE SECOND WORD.

ROUNDING IS AWAY FROM 0.

ONE VIRTUE OF THIS FLOATING POINT FORMAT IS THAT NUMBER COMPARISONS
MAY BE MADE USING THE SAME COMPARE INSTRUCTIONS AS FOR INTEGER ARITHMETIC.
ANOTHER VIRTUE IS THAT THE NEGATIVE OF A NORMALIZED NUMBER IS NORMALIZED.
HOWEVER, NOTE THAT THE NORMALIZED FORM OF FLOATING POINT NUMBERS WASTES
ONE BIT BY REQUIRING THE LEADING BIT OF FRACTION TO BE THE COMPLEMENT
OF THE SIGN (-1*2↑N IS AN EXCEPTION).
%


MC[OVF&FOVF&FUNF, OVF, FOVF, FUNF];
SM[OVF&FOVF,IP[440000 000000S]];  ***

%DOUBLE-FLOATING-NEGATE PERFORMS THE TWO'S COMPLEMENT OF THE NUMBER
CONSISTING OF AC AND [E][11,43].  SIGN AND EXPONENT OF [E] ARE
UNCHANGED.
TIMING = M + R + W + 4
I = 5
%
DFN:	Q←777 777777S, LAC←NOT Q;
	P AND Q, WRESTART;
	GOTO[.+2,ALU=0], P←P#Q, INHINT;  *COMPLEMENT FRACTION
	MDR←Q←P+1, GOTO[QTOMCHK];
*[E] UNCHANGED WHEN ITS FRACTION IS 0.  CARRY GOES INTO B[43] OF THE 1ST WORD.
	P←LAC, Q←1S, GOTO[P+QA]; *NO POSSIBILITY OF OVERFLOW


%FLOATING SCALE ACCEPTS E IN P AND AC IN Q.  IT SCALES THE EXPONENT OF AC
BY THE NUMBER CONSISTING OF E[22] AND E[34,43] AND NORMALIZES THE RESULT.
WIND UP WITH EXPONENT IN RPGRT3, FRACTION IN P, AND 0 IN Q FOR
NORMALIZATION ROUTINES.
TIMING = M + 6 + (1 IF E<0) + TIME FOR NORMALIZATION
I = 8
%
FSC:	YSHIFT←P, CLEARF[G];    *Y GETS E[22], E[34,43]
	P←Y, GOTO[.+2,Y>=0], AQ;
	P←(Y) U (777777 777000S), AQ;
	FSPLIT←Q, P←-1L, SAMASK[33], RPGRT3←P, GOTO[FSCP,ALU>=0];
	LTEMP←NOT P OR Q, P←RPGRT3, Q←(Y) U (777777 777000S);
*WANT P + NOT Q = P-Q-1;
	RPGRT3←P-Q-1, P←LTEMP, Q←NULL, RETURN, FRZBALUBC;

FSCP:	LTEMP←P AND Q, P←RPGRT3, Q←Y;
	RPGRT3←P+Q, P←LTEMP, Q←NULL, RETURN, FRZBALUBC;

%"FSET" PUTS THE FLOATING POINT NUMBERS IN P AND IN LAC INTO STANDARD FORM:
   SIGNED FRACTIONS INTO RTEMP [FROM P] AND LTEMP [FROM AC];
   EXCESS-200 EXPONENTS IN Q AND IN RPGRT3 [FROM P] AND IN P [FROM AC].
FSPLIT←P SHOULD ACCOMPANY CALL.
THE ARGUMENT IN P IS NEGATED IF H = 1 AT CALL (FOR SUBTRACT).
SIGN ALU = SIGN AC = SIGN LTEMP AT RETURN.
TIMING = 5 + (1 IF AC<0) + (1 IF P MUST BE NEGATED) CYCLES
I = 12
%
FSET:
*! MAXC1 ONLY
	PQ RCY [0];	*FOR Y BRANCH BUG.
*!
	Q←777 777777S, GOTO[FPNEG,Y<0];
	RTEMP←P AND Q, P←Y, Q←LAC;
	RPGRT3←P, FSPLIT←Q, GOTO[FSETN,H=1];
FSET1:	P←777 777777S, GOTO[FQNEG,Y<0], Q←LAC;
FSETN1: LTEMP←P AND Q, P←Y, Q←RPGRT3, RETURN;

FPNEG:	RTEMP←P OR NOT Q, P←(Y) U (777777 777000S), Q←LAC;
	RPGRT3←NOT P, FSPLIT←Q, GOTO[FSET1,H=0];
FSETN:	Q←RTEMP, P←A0;
	RTEMP←P-Q, P←777 777777S, Q←LAC, GOTO[FSETN1,Y>=0];
FQNEG:	LTEMP←NOT P OR Q, Q←(Y) U (777777 777000S);
	Q←RPGRT3, P←NOT Q, RETURN, FRZBALUBC;


%"NORM" BEGINS NORMALIZING A FLOATING POINT NUMBER.

AT CALL:  FRACTION THROUGH ALU, PQ CONTAINS THE FRACTION SUCH THAT P[1,7] = P[0]
(IN OTHER WORDS, TO PRODUCE THE FINAL NORMALIZED RESULT IT WILL BE NECESSARY
TO SHIFT THE FRACTION 1 RIGHT, NONE, OR ANY NUMBER OF PLACES LEFT, BUT NEVER
MORE THAN 1 RIGHT.).  RPGRT3 CONTAINS THE EXPONENT.

AT RETURN:  PQ CONTAINS THE FRACTION SHIFTED 1 LEFT OF THE NORMALIZED
POSITION.  (P+1) ARSHC 1 WILL THEN GIVE THE CORRECT ROUNDED RESULT
OR PQ RCY [1] WILL GIVE THE CORRECT UNROUNDED RESULT.  THE PROPER
EXPONENT WILL BE [RPGRT3] + [Y] + 1.  G=1 IF THE RESULT MUST BE NEGATED
TIMING = 4 + (1 IF FRACTION < 0) + (3 IF 1ST WORD OF FRACTION = 0 OR -1)
         + 1/NORMALIZE STEP
I = 13
%
NORM:	GOTO[NORMN,ALU<0], FRZBALUBC, Q←(NOT Q) U (777S); *NULLIFY 9 BITS
NORMP:	GOTO[NORM1,ALU#0], FRZBALUBC, Q←NOT Q, Y←NULL, SETSF[G];
**"NORMN" AND "NORM1" ARE AFTER "FMP"
*GET HERE IF FRACTION OR NOT FRACTION IS 0 IN THE FIRST WORD
	QQ RCY [10], AMASK[34];
NORMZ0:	LTEMP←P, P←RPGRT3, Q←33S;
NORMZ1:	RPGRT3←P-Q-1, P←LTEMP, Q←Y←NULL, GOTO[NORM1,ALU#0], FRZBALUBC;
	RPGRT3←P←Q←A0, Y←-1S, RETURN;

%"SNORM" AND "RND" BEGIN WHERE "NORM" FINISHES.  "SNORM" LEAVES A SINGLE
PRECISION RESULT IN Q, "RND" A ROUNDED SINGLE PRECISION RESULT IN Q.
SNORM TIMING = 9 CYCLES + 1 IF Y>=0 +1 IF NEG. AND 2ND FRAC=0
RND TIMING = 7 + 1 IF NEG. + 3 IF ROUNDING OVERFLOWS
I = 16
%
SNORM:	PQ RCY [1], Q RSH 1, ASHOVF;
	AQ, DGOTO[SNOR2,Y>=0];
	SETFB[H,ALU=0], CALL[RETN,ALU=0];
RND2:	LTEMP←P, P←RPGRT3, Q←(Y) U (777777 777000S);
SNOR1:	RPGRT3←P←P+Q+1, Q←377S, GOTO[RND1,ALU8=1];
	P AND NOT Q, SETFC[OVF&FOVF&FUNF,ALU<0];
RND4:	SETFC[OVF&FOVF,ALU#0], Q←P AND Q, P←NULL;
	PQ RCY [11], Q←LTEMP, GOTO[UPQ,G=0];
	Q←P←NOT P AND NOT Q, RETURN[H=0];
SNEGP:	Q←P+1, P←NULL, RETURN;

RND:	(P+1) ARSHC 1, GOTO[RND2,Y<0], SETF[H];
SNOR2:	LTEMP←P, P←RPGRT3, GOTO[SNOR1], Q←Y;  *[Y] = 0 HERE BUT NO MATTER

*HERE IFF ROUNDING OVERFLOWS SO THAT THE NUMBER BECOMES UNNORMALIZED.
RND1:	P←LTEMP, RPGRT3←P+1;
	(P) ARSHC 1, SETFC[OVF&FOVF&FUNF,ALU<0], DGOTO[RND4,ALU<0];
	LTEMP←P, P←RPGRT3;
	P AND NOT Q, GOTO[RND4];

%ROUTINE TO LEAVE DOUBLE PRECISION RESULT IN PQ.  BEGINS WHERE "NORM"
FINISHES.  WIND UP WITH SIGNIFICANT WORD IN Q, INSIGNIFICANT IN P.
THE INSIGNIFICANT RESULT IS ZEROED WHENEVER EITHER THE FRACTION IS 0 OR THE
EXPONENT UNDERFLOWS OR OVERFLOWS.  THE FRACTION IS UNROUNDED.
TIMING = 12 - (1 IF 2ND FRAC=0) + (1 IF NEG.) + (1 IF 2ND EXP OVERFLOWS)
I = 19
%
DNORM:	LPGRT3←NOT Q, GOTO[.+2,Y<0];
	LTEMP←P, P←RPGRT3, Q←Y, GOTO[.+2];
	LTEMP←P, P←RPGRT3, Q←(Y) U (777777 777000S);
	RPGRT3←P←P+Q+1, Q←377S;
	P AND NOT Q, SETFC[OVF&FOVF&FUNF,ALU<0];
	SETFC[OVF&FOVF,ALU#0], Q←P AND Q, P←NULL;
	PQ RCY [11], Q←LTEMP, GOTO[DNORM1,G=0];
*NEGATE THE NO.
	RTEMP←NOT P AND NOT Q, P←LPGRT3, Q←777S;
	P←P OR Q;
	LPGRT3←P+1, P←RPGRT3, Q←33S;
	GOTO[DNORM3,ALU=0], Q←P←P-Q, SAMASK[10];
DNORM4:	P#Q, GOTO[DNORM5,ALU>=0], P←LPGRT3;
DNORM2:	Q←RTEMP, P←NULL, RETURN; *2ND WORD'S EXPONENT UNDERFLOWED OR FRACTION 0

DNORM5:	PQ RCY [11], Q←RTEMP, RETURN[ALU=0];
ZEROP:	P←NULL, FRZBALUBC, RETURN; *2ND WORD'S EXPONENT OVERFLOWED

*HERE IF 2'S COMP. OF 2ND FRAC=0
DNORM3:	P←RTEMP, GOTO[SNEGP];

*NOT 2ND WORD OF FRAC IN LPGRT3, EXP OF 1ST WORD IN P, FRAC IN Q
DNORM1:	RTEMP←P OR Q, P←LPGRT3, Q←777777 777000S;
	LPGRT3←NOT P AND Q, P←RPGRT3, Q←33S, DGOTO[DNORM4];
	P←Q←P-Q, SAMASK[10], GOTO[DNORM2,ALU=0];

%FINISHING ROUTINES FOR FLOATING POINT (NORML AND RNDM ARE BACK WITH THE
DIVIDE FINISHING ROUTINES
I = 10
%
NORMA:	CALL[SNORM];
QTOAC:	LAC←Q, ENDM;
NORMM:	CALL[SNORM];
	P←MAPVA←STEMP, ACFS, GOTO[WREFQ];
NORMB:	CALL[SNORM];
	LAC←Q, P←MAPVA←STEMP, ACFS, GOTO[WREFQ];
RNDA:	CALL[RND];
	LAC←Q, ENDM;
RNDB:	CALL[RND];
	LAC←Q, P←MAPVA←STEMP, ACFS, GOTO[WREFQ];

%"FAD", "FSB", AND "UFA" BEGIN WITH MEMORY ARGUMENT IN P AND AC IN Q.
THEY PUT THE ARGUMENTS INTO STANDARD FLOATING POINT MICROFORM WITH
"FSET".  "FSB" NEGATES THE MEMORY ARGUMENT (IN THE FSET ROUTINE).
WIND UP WITH EXPONENT IN RPGRT3 AND FRACTION IN P AND Q FOR NORMALIZATION
ROUTINE, AND GOTO "NORM" FOR "FAD" AND "FSB".  "UFA" FALLS THROUGH,
NORMALIZES THE RESULT IFF THE ADDITION OVERFLOWS INTO THE EXPONENT
FIELD.  THE RESULT IS LEFT IN AC+1.
TIMING = 4 TO 9 + "FSET" TIME + (5 IF EXPONENT DIFF. > 44)
	+ (NORMALIZATION TIME FOR "FAD" AND "FSB")
	+ (3 + (4 IF FRACTION OVERFLOWS) FOR "UFA")
I = 35
%
FSB:	SETF[H], CALL[FSET], FSPLIT←P;
	Y←P-Q, GOTO[FAD1];

UFA:	SETF[K];
FAD:	CLEARF[H], CALL[FSET], FSPLIT←P;
	Y←P-Q, GOTO[FAD1];

%AT THIS POINT Y CONTAINS THE AMOUNT WHICH THE FRACTION IN RTEMP
MUST BE RCYED (IF Y>=0) OR - THE AMOUNT WHICH THE FRACTION IN LTEMP
MUST BE RCYED (Y<0).  H=0 FOR "UFA" BUT H=1 FOR "FAD" AND "FSB".
THE EXPONENT IS RPGRT3 IF Y<0 ELSE RPGRT3+Y.
%
FAD1:	GOTO[FAD2,Y<0], NEGY, Q←LTEMP, P←RTEMP;
	RTEMP←Q, NEGY, GOTO[.+2,Y<0]; *GO IF Y#0
	LPGRT3←A0, GOTO[FAD4]; *NO FRACTION SHIFTING REQUIRED
	LTEMP←P, P←RPGRT3, Q←Y;
	RPGRT3←P+Q, Q←LTEMP;
*HERE WITH ARG TO BE RCYED IN Q, OTHER ARG IN RTEMP, EXPONENT IN
*RPGRT3 AND RCY COUNT IN Y.  GET THE 2ND FRACTION WORD FOR ARG BEING RCY'ED
FAD2:	0Q RCY [Y], STEMP1←Q;

*HAVE RCY COUNT IN Y, TRAILING FRACTION WORD OF RESULT IN P, ARG NOT BEING
*RCY'ED IN RTEMP, EXPONENT IN RPGRT3, H=1 IF CYCLE COUNT OVERFLOWED, SIGN B=
*SIGN OF ARG BEING RCY'ED, ARG BEING RCY'D IN Q
	LPGRT3←P, P←Q, GOTO[.+2,B>=0], Q←NULL;
	LTEMP←Q←A1, GOTO[FAD3,H=1];
*CAN'T PUT LTEMP←A0 HERE BECAUSE Y MIGHT SELECT LB
	PQ RCY [Y], Q←RTEMP, GOTO[FAD3A,H=1];

*NOW HAVE 2ND WORD OF FRACTION IN LPGRT3, EXPONENT IN RPGRT3, AND THE SUM OF
*P AND Q IS THE FIRST WORD OF FRACTION
FAD4:	P←P+Q, Q←LPGRT3, CLEARF[G], GOTO[NORM,K=0];

*FALL THROUGH HERE ONLY FOR "UFA"
	INCAC, GOTO[UFAN,ALU<0], LTEMP←P, Q←RPGRT3, P←NULL;
	GOTO[SETZ,ALU=0], FRZBALUBC, PQ RCY [11], Q←LTEMP;
	LAC←P OR Q, Q RSH 1, GOTO[REMAPPC,ALU8=0];
UFANO:	LTEMP←Q, P←RPGRT3;
	P←Q←P+1, SAMASK[10], DGOTO[.+3,ALU<0];
	P#Q, 0Q RCY [11], Q←LTEMP, DGOTO[.+3];
	LAC←P OR Q, ENDM[ALU=0];
	LAC←NOT P AND Q, ENDM[ALU=0];
	SETF[OVF&FOVF], GOTO[REMAP1];

UFAN:	PQ RCY [11], FRZBALUBC, Q←LTEMP;
	LAC←NOT P AND Q, Q RSH 1, GOTO[REMAPPC,ALU8=1];
	Q←(Q) U (400000 000000S), GOTO[UFANO];

*FRACTION CYCLED MORE THAN 77
FAD5:	LPGRT3←Q←A0, P←RTEMP, GOTO[FAD4];

*HERE WITH -1 IN LTEMP, ARG TO RCY IN STEMP1, RCY COUNT IN Y > 44,
*OTHER ARG IN RTEMP, EXPONENT IN RPGRT3.
FAD3A:	LTEMP←A0, P←Y, Q←44R, GOTO[.+2]; *POS. FRACTION
FAD3:	P←Y, Q←44R; *NEG. FRACTION
	Q←P-Q, P←34S;
	Y←Q, P-Q, Q←LTEMP;
	P←STEMP1, GOTO[FAD5,ALU<0];
	PQ RCY [Y];
	LPGRT3←P, P←RTEMP, GOTO[FAD4];

DI[140,RARG,FAD,NORMA];	*FAD
DI[141,RARG,FAD,NORML];	*FADL
DI[142,RARG,FAD,NORMM];	*FADM
DI[143,RARG,FAD,NORMB];	*FADB
DI[144,RARG,FAD,RNDA];	*FADR
DI[145,ESWAP,FAD,RNDA];	*FADRI
DI[146,RARG,FAD,RNDM];	*FADRM
DI[147,RARG,FAD,RNDB];	*FADRB

DI[150,RARG,FSB,NORMA];	*FSB
DI[151,RARG,FSB,NORML];	*FSBL
DI[152,RARG,FSB,NORMM];	*FSBM
DI[153,RARG,FSB,NORMB];	*FSBB
DI[154,RARG,FSB,RNDA];	*FSBR
DI[155,ESWAP,FSB,RNDA];	*FSBRI
DI[156,RARG,FSB,RNDM];	*FSBRM
DI[157,RARG,FSB,RNDB];	*FSBRB
DI[130,RARG,UFA,REMAPPC];	*UFA
DI[131,RMWARG,DFN,SCRASH];	*DFN
DI[132,FSC,NORM,NORMA];	*FSC

%"FMP" USES THE INTEGER MULTIPLY LOOP TO COMPUTE A 66-BIT MAG. RESULT
IF BOTH MULTIPLIER AND MULTIPLICAND ARE NORMALIZED, THE RESULT WILL
CONTAIN THE SIGN BIT IN P[1,11] AND NOT SIGN IN P[12], AND THE REST OF THE
FRACTION IN P[13,43], Q[0,33].  HENCE THE SUM OF THE EXPONENTS - 200
IS THE FINAL EXPONENT.
THE MULTIPLY SETUP REQUIRES 34 - 2 IN X, FRACTIONS IN P AND Q.
TIMING = 5 + "FSET" TIME + MULTIPLY TIME + "NORM" TIME
I = 5
%
FMP:	CLEARF[H], FSPLIT←P, CALL[FSET];
	P←P+Q+1, Q←200S, DGOTO[32];
	RPGRT3←P-Q, Q←LTEMP, X←NPC, GOTO[.+1];
	P←RTEMP, CALL[XMUL];
	Q←(NOT Q) U (377S), FRZBALUBC, GOTO[NORMP,ALU>=0];

*COME HERE ORDINARILY FROM "NORM".
*WORK WITH NEGATIVE OF NUMBER IF IT IS NEGATIVE
NORMN:	LTEMP←NOT P, SETF[G], P←Y←NULL;
	GOTO[NORMZN,ALU=0], P←LTEMP, Q←P+Q+1;
	P, GOTO[.+3,ALU#0];
	P←P+1, CALL[.+3];	*HANDLE 776000 000000 CASE
	P;
NORM1:	PQ LCY [1], Q LSH 1, DECY, GOTO[.,ALU8=0], 2P;
	RETURN, PQ RCY [1], Q RSH 1, ASHOVF, INCY;

*HERE IF LEADING WORD OF NEG. FRAC. IS -1, 2'S COMP OF 2ND WORD
*IN Q, 0 IN Y
NORMZN:	GOTO[NORMZ0,ALU#0], QQ RCY [10], AMASK[34], Q←1000 000000S;
	LTEMP←Q, P←RPGRT3, Q←32S, GOTO[NORMZ1];

DI[160,RARG,FMP,NORMA];	*FMP
DI[161,RARG,FMP,NORML];	*FMPL
DI[162,RARG,FMP,NORMM];	*FMPM
DI[163,RARG,FMP,NORMB];	*FMPB
DI[164,RARG,FMP,RNDA];	*FMPR
DI[165,ESWAP,FMP,RNDA];	*FMPRI
DI[166,RARG,FMP,RNDM];	*FMPRM
DI[167,RARG,FMP,RNDB];	*FMPRB

%FDVR COMPUTES A 28-BIT IN MAGNITUDE QUOTIENT (ONE EXTRA BIT FOR
ROUNDING).  OVERFLOW, FLOATING OVERFLOW, AND NO DIVIDE WILL BE SET AND
NO CHANGES TO OPERANDS WILL OCCUR IF THE MAGNITUDE OF THE FRACTION 
IN AC >= 2*THAT OF THE MEMORY OPERAND.  AC IS DIVIDED BY THE MEMORY
OPERAND.
TIMING	= 6 + TIME[FSET + FDVX + NORM]
	= 18 + 3*28 + (2 IF ITHER DIVD OR DIVS <0)
	+ (2 IF DIVS FRAC < DIVD FRAC)

FDV COMPUTES A 27-BIT MAGNITUDE QUOTIENT AND DOESN'T ROUND.
OTHERWISE IT IS THE SAME AS FDVR.
TIMING	= 6 + TIME[FSET + FDVX + NORM]
	= 18 + 3*27 + (2 IF EITHER DIVD OR DIVS < 0)
	+ (2 IF DIVS FRAC < DIVD FRAC)

FDVL USES AC AND AC+1 AS THE DIVIDEND AND LEAVES THE 27-BIT QUOTIENT
IN AC AND 27-BIT REMAINDER IN AC+1.  THE EXPONENT OF THE REMAINDER
IS 26 LESS THAN THE EXPONENT OF THE DIVIDEND IF THE DIVIDEND FRACTION
IS GREATER EQUAL TO THE DIVISOR FRACTION, OTHERWISE 27 LESS.  THE
REMAINDER IS SET TO 0 IF IT UNDERFLOWS.
TIMING	= 16 + TIME[FSET + FDVX + 2*NORM + SNORM]
	= M + R + 39 + 3*27 + (2 IF EITHER ARG < 0) + (1 IF DIVD < 0)
I = 27
%
MC[OVF&FOVF&NODIV,OVF,FOVF,NODIV];

FDVR:	CLEARF[H], FSPLIT←P, CALL[FSET];
	RPGRT3←P-Q-1, X←33S, DGOTO[FDVR1];
	MDR←377S, LPGRT3←A0, Q←RTEMP, CALL[FDVX], INCX;

FDV:	CLEARF[H], FSPLIT←P, CALL[FSET];
	RPGRT3←P-Q, X←33S;
	MDR←777S, LPGRT3←A0, Q←RTEMP, CALL[FDVX];
*FDVX RETURNS WITH QUOTIENT IN Q, REMAINDER IN P, RPGRT3 UNCHANGED
FDVR1:	P←RPGRT3, LTEMP←Q, Q←200S;
	RPGRT3←P+Q+J, P←LTEMP, Q←NULL;
FDVL0:	P, GOTO[NORM];

FDVL:	CLEARF[H], FSPLIT←P, CALL[FSET];
	LPGRT←P-Q, X←Q←33S, INCAC, DGOTO[SNORM];
	RPGRT←P-Q, P←LPGRT, Q←200S, CALL[.+1];
	RPGRT3←P+Q, Q←LAC, P←NULL, DECAC;
	PQ RCY [33], MDR←777S, Q←RTEMP;
	LPGRT3←P, CALL[FDVX];
	LPGRT2←P, P←RPGRT3, SETFB[10S,J=1]; *LPGRT2←REMAINDER
	RPGRT3←P+J, P←Q, Q←NULL, GOTO[FDVL0];

*NORM RETURNS TO SNORM WHICH RETURNS HERE
FDVL1:	LAC←Q, P←RPGRT, SETFB[J,K=1];
	Q←P+J, P←377S, DGOTO[FDVL2,J=0];
	NOT P AND Q, PQ RCY [11], Q←LPGRT2;
	Q RSH 1, AQ, INCAC, GOTO[SETZ,ALU#0];
	GOTO[.+3,ALU>=0], FRZBALUBC;
	Q←(Q) U (400000 000000S), FRZBALUBC, GOTO[.+2];
FDVL2:	GOTO[SETZ,ALU#0], AQ, INCAC; *JUMP ON UNDERFLOW
	RETURN[ALU>0], FRZBALUBC, LAC←P OR Q;
	LAC←NOT P AND Q, ENDM[ALU<0];
SETZ:	LAC←A0, ENDM;	*REMAINDER UNDERFLOWED

%FDVX ACCEPTS NO. MAGNITUDE BITS IN X, MASK OF LEADING ONES IN MDR
(44-[X] LEADING 1'S), DIVS FRAC IN Q, LH OF DIVD FRAC IN LTEMP,
RH OF DIVD FRAC IN LPGRT3.
SETUP FOR "DIVME" AND "DIVPE" REQUIRES NO. MAGNITUDE BITS IN X,
DIVISOR IN RTEMP, LEFT-HALF OF DIVIDEND IN P (AC FRACTION FROM "FSET"),
RIGHT-HALF OF DIVIDEND (LEFT-JUSTIFIED) FOLLOWED BY 8 (FOR FDVR) OR 9
(FOR FDV) 0'S OR 1'S (DEPENDING ON ARGUMENT SIGNS) IN Q, G = 1, AND
H = NOT SIGN OF DIVIDEND.  "DIVME" IS ENTERED FOR SIGN OF DIVIDEND
= SIGN OF DIVISOR, ELSE "DIVPE" IS ENTERED.
TIMING = 5 + (2 IF MAG. DIVS < MAG. DIVD) + 3 * [X]
I = 23
%
FDVX:	P←LTEMP, SETF[G], RTEMP←Q;
	P, GOTO[FDVP,ALU>=0], CLEARF[J];
	SETFB[H,ALU>=0], GOTO[FDVMP,ALU>=0], P+Q;
*DIVIDEND AND DIVISOR BOTH NEGATIVE
	P-Q, P←LPGRT3, Q LSH 1;
	P←LTEMP, GOTO[.+2,ALU<=0], MDR←(P) U (MDR);
	Q←MDR, GOTO[DIVME];
	P-Q, DGOTO[DIVME], SETF[J];
	SETFC[OVF&FOVF&NODIV,ALU<=0], GOTO[REMAPPC, ALU<=0], RTEMP←Q, Q←MDR;

*DIVIDEND POSITIVE, DIVISOR NEGATIVE
FDVMP:	Q LSH 1, GOTO[.+2,ALU>=0];
	Q←LPGRT3, GOTO[DIVPE];
	P+Q, DGOTO[DIVPE], SETF[J];
	SETFC[OVF&FOVF&NODIV,ALU>=0], GOTO[REMAPPC,ALU>=0], RTEMP←Q, Q←LPGRT3;

*DIVISOR POSITIVE
FDVP:	P-Q, SETFB[H,ALU>=0], GOTO[FDVPP,ALU>=0];
*DIVISOR POSITIVE, DIVIDEND NEGATIVE
	P+Q, Q LSH 1, P←LPGRT3, STEMP1←MDR;
	MDR←(STEMP1) U (P), P←LTEMP, GOTO[.+2,ALU<=0];
	Q←MDR, GOTO[DIVPE];
	P+Q, SETF[J], DGOTO[DIVPE];
	SETFC[OVF&FOVF&NODIV,ALU<=0], GOTO[REMAPPC,ALU<=0], RTEMP←Q, Q←MDR;

*DIVIDEND AND DIVISOR BOTH POSITIVE
FDVPP:	Q LSH 1, GOTO[.+2,ALU>=0];
	Q←LPGRT3, GOTO[DIVME];
	P-Q, SETF[J], DGOTO[DIVME];
	SETFC[OVF&FOVF&NODIV,ALU>=0], GOTO[REMAPPC,ALU>=0], RTEMP←Q, Q←LPGRT3;

DI[170,RARG,FDV,NORMA];	*FDV
DI[171,RARG,FDVL,FDVL1];*FDVL
DI[172,RARG,FDV,NORMM];	*FDVM
DI[173,RARG,FDV,NORMB];	*FDVB
DI[174,RARG,FDVR,RNDA];	*FDVR
DI[175,ESWAP,FDVR,RNDA];*FDVRI
DI[176,RARG,FDVR,RNDM];	*FDVRM
DI[177,RARG,FDVR,RNDB];	*FDVRB