{File name: NLispFPTBase.mc Last edited by cal 21-Oct-83 11:57:59 Last edited by Sturgis 15-Sep-83 16:40:30 Descrition: Floating point code for Lisp {modified from Cedar fpt code} Created by H. Sturgis } {*********************************************************************************************** De normalization code enter with T, ~Q holding the 32 bit quantity, L0 prepared for return, TT holding shift count (note that Q is negated) contents of TT is destroyed De normalized result is in T, Q Q[15] is a sticky bit ***********************************************************************************************} DeNormC1: c1; DeNormC2: c2; DeNormC3: TT _ -TT - 1, c3; DeNormA: TT _ TT + 1, NZeroBr, c1; Ybus _ Q and 1, ZeroBr, BRANCH[DeNormA1, $], c2; T _ DRShift1 T, SE _ 0, BRANCH[DeNormA, DeNormB], c3; DeNormA1: {stcky bit is 0} Q _ ~Q, L0Disp, CANCELBR[$], c3; RET[DeNormRets], c1; {sticky bit will be 1} DeNormB: TT _ TT + 1, NZeroBr, c1; BRANCH[DeNormB1, $], c2; T _ DRShift1 T, SE _ 0, GOTO[DeNormB], c3; DeNormB1: {stcky bit is 1} Q _ ~Q, L0Disp, c3; Q _ Q or 1, RET[DeNormRets], c1; {**************************************************************************** division code This procedure calls unpack2 to break the arguments up into components Sign1 Exp1 HighHalf1 LowHalf1 Sign2 Exp2 HighHalf2 LowHalf2 where the high halves have 16 bits and the lowhalves have 8 bits ****************************************************************************} {the arguments are now unpacked} T _ uExp1, c2, at[L2.Fquot, 10, FptPrepRet]; TT _ uExp2, c3; T _ T - TT, c1; T _ T + 127'd, {re bias exponent} c2; uExp1 _ T, c3; TT _ uSign1, c1; Q _ uSign2, c2; uSign1 _ TT xor Q, c3; uDivCount _ divCount, {save a non temporary R reg} c1; uDivResult _ divResult, {save a non temporary R reg} c2; {now load the operands, right shifted by 1 bit to allow room to shift left during the divide loop, also test for zero divisor} divisorHigh _ uHighHalf2, ZeroBr, c3; Q _ uLowHalf2, ZeroBr, BRANCH[FptDivB, FptDivA], c1; FptDivA: Q _ ~Q, BRANCH[$, FptDivZero], c2; divisorHigh _ DRShift1 divisorHigh, SE _ 0, GOTO[FptDivC], c3; FptDivB: Q _ ~Q, CANCELBR[$], c2; divisorHigh _ DRShift1 divisorHigh, SE _ 0, GOTO[FptDivC], c3; FptDivC: divisorLow _ ~Q, c1; T _ uHighHalf1, c2; Q _ ~ uLowHalf1, c3; T _ DRShift1 T, SE _ 0, c1; Q _ ~Q, L0 _ L0.div2, c2; {as per Ed Tafts Dorado code, we will do a total of 26 iterations, 24 for quotient bits, + 2 guard bits. They are done by first doing 16 iterations, then 10 iterations} divCount _ 16'd, CALL[FptDivLoopC1], c3; uHighHalf1 _ divResult, c2, at[L0.div2, 10, FptDivLoopRets]; T _ DLShift1 T, SE _ 1, {puts a 0 into Q.15} L0 _ L0.div3, {remainder did not get its last left shift} c3; divCount _ 10'd, CALL[FptDivLoopC2], c1; divResult _ divResult LRot4, c2, at[L0.div3, 10, FptDivLoopRets]; [] _ T or Q, NZeroBr, c3; divResult _ LShift1 (divResult), SE _ 0, BRANCH[FptDivD, FptDivE], c1; {now we install the correct sticky bit} FptDivD: divResult _ LShift1 (divResult), SE _ 0, GOTO[FptDivF], c2; FptDivE: divResult _ LShift1 (divResult), SE _ 1, GOTO[FptDivF], c2; FptDivF: uLowHalf1 _ divResult , GOTO[FptDivExit], c3; {divide by zero} FptDivZero: divCount _ uDivCount, {restore a non temporary R reg} c3; divResult _ uDivResult, {restore a non temporary R reg} c1; GOTO[FPTrapsC3], c2; FptDivExit: divCount _ uDivCount, {restore a non temporary R reg} c1; divResult _ uDivResult, {restore a non temporary R reg} c2; uStickyBit _ 0, GOTO[RePackC1], c3; {*********************************************************************************************** divide loop dividend in divisor in bit count in divCount, performs bitCOunt subtractions return point in L0 will accumulate bits in divResult will hold the remainder ***********************************************************************************************} FptDivLoopC1: c1; FptDivLoopC2: c2; FptDivLoopC3: divResult _ 0, GOTO[FptDivSubA], c3; {in this part of the loop the contents of are positive} FptDivSub: {delay} c2; divResult _ LShift1 (divResult), SE _ 1, c3; FptDivSubA: Q _ Q-divisorLow, CarryBr, c1; divCount _ divCount-1, ZeroBr, BRANCH[FptDivSub1, FptDivSub0], c2; FptDivSub0: T _ T-divisorHigh, CarryBr, BRANCH[$, FptDivSubExit1], c3; T _ DLShift1 T, SE _ 1, {puts a 0 into Q.15} BRANCH[FptDivAdd, FptDivSub], c1; FptDivSub1: T _ T-divisorHigh-1, CarryBr, BRANCH[$ , FptDivSubExit2], c3; T _ DLShift1 T, SE _ 1, {puts a 0 into Q.15} BRANCH[FptDivAdd, FptDivSub], c1; FptDivSubExit1: BRANCH[FptDivAddExit, FptDivSubExit], c1; FptDivSubExit2: BRANCH[FptDivAddExit, FptDivSubExit], c1; FptDivSubExit: divResult _ LShift1 (divResult), SE _ 1, GOTO[FptDivLoopExit], c2; {in this part of the loop the contents of are negative (in 2's complement)} FptDivAdd: {delay} c2; divResult _ LShift1 (divResult), SE _ 0, c3; Q _ Q+divisorLow, CarryBr, c1; divCount _ divCount-1, ZeroBr, BRANCH[FptDivAdd0, FptDivAdd1], c2; FptDivAdd0: T _ T+divisorHigh, CarryBr, BRANCH[$, FptDivAddExit1], c3; T _ DLShift1 T, SE _ 1, {puts a 0 into Q.15} BRANCH[FptDivAdd, FptDivSub], c1; FptDivAdd1: T _ T+divisorHigh+1, CarryBr, BRANCH[$, FptDivAddExit2], c3; T _ DLShift1 T, SE _ 1, {puts a 0 into Q.15} BRANCH[FptDivAdd, FptDivSub], c1; FptDivAddExit1: BRANCH[FptDivAddExit, FptDivSubExit], c1; FptDivAddExit2: BRANCH[FptDivAddExit, FptDivSubExit], c1; {we have subtracted one too many times, so add back in to get correct remainder} FptDivAddExit: divResult _ LShift1 (divResult), SE _ 0, c2; Q _ Q + divisorLow, CarryBr, c3; {delay} BRANCH[FptDivAX0, FptDivAX1], c1; FptDivAX1: T _ T + divisorHigh + 1, GOTO[FptDivLoopExit], c2; FptDivAX0: T _ T + divisorHigh, GOTO[FptDivLoopExit], c2; FptDivLoopExit: L0Disp, c3; RET[FptDivLoopRets], c1; { E N D }