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