{<>klamath>SModeledRUM>FloatCompare.mc created: T.Tokunaga 6-Mar-85 10:09:19 Last edited: T.Tokunaga 21-Mar-85 14:31:25 modification for move to bank0 Last edited: T.Tokunaga 21-Mar-85 13:23:18 rename for moving to bank0 Last edited: T.Tokunaga 7-Mar-85 11:16:52 rechange the entry point cycle (c2) Last edited: T.Tokunaga 7-Mar-85 11:04:25 change the entry point cycle (c3) } {Entry point, uArg2Hi,,uArg2Lo have Argument, temp2Low,,Temp3Low have Receiver L2 has the return link entry c2, return c1} floatCompare: uFloatMinus _ temp2Low, c2; Q _ 0FF + 1, c3; PPort _ ~Q, c1; { bus direction is BX --> X} FloatMode.RN.PI.IEEE, FloatFLOW, c2; FloatAB _ uArg2Hi, c3; { high half of argument } FloatAB _ uArg2Lo, c1; {low half of argument} FloatA _ uFloatMinus, FLAMinusB, c2; { high half of reciever, and operation} FloatA _ temp3Low LRot0, c3; {low half of receiver} FloatStartFlow, c1; uArg1Hi _ temp2Low, c2; {save high half of receiver} uArg1Lo _ temp3Low, c3; {save low half of reciever} Noop, c1; FloatUnloadS, Float.M, c2; FloatUnloadS, Float.L, c3; Q _ PPort, c1; { get status} temp2Low _ FloatResult, c2; { get high half of result} temp3Low _ FloatResult, c3; { get low half of result} getResult: [] _ Q, YDisp, c1; Q _ temp1Low xor ~temp1Low, DISP4[fppCompareStatus,1], c2; { Q _ all 1} PPort _ Q,GOTO[fppCompareOK], c3, at[0F,10,fppCompareStatus]; { OK } PPort _ Q,GOTO[fppCompareINX], c3, at[0D,10,fppCompareStatus]; { inexact result: normal - non-normal } { PPort _ Q,GOTO[fppCompareUN], c3, at[0B,10,fppCompareStatus]; }{ underflow -- never occur} { PPort _ Q,GOTO[fppCompareUNINX], c3, at[09,10,fppCompareStatus];} { underflow + inexact result -- never occur} { PPort _ Q,GOTO[fppCompareUNUSED], c3, at[07,10,fppCompareStatus]; }{ unused -- never occur} PPort _ Q,GOTO[fppCompareOF], c3, at[05,10,fppCompareStatus]; { overflow } PPort _ Q,GOTO[checkInfinity], c3, at[03,10,fppCompareStatus]; { invalid operand } { PPort _ Q,GOTO[fppCompareDIN], c3, at[01,10,fppCompareStatus]; }{ Dinormalized -- never occur} fppCompareOK: L1 _ L1.checkResultType, c1; Noop, c2; CALL[checkFloatType], c3; { check the tyoe of result } { at return, floatTemp has some data, flotTemp = 0 --> result = zero --> receiver = argument floatTemp = 1 --> result = normal (including the non-normal) ---> depend on result's sign floatTemp = 2 --> result = infinty --> check the receiver, argument} [] _ floatTemp, YDisp, c1, at[L1.checkResultType, 10, checkFloatType-return]; temp2Low _ uArg1Hi, DISP4[resultType,0C], c2; floatTemp _ 0, L2Disp, GOTO[TrueOrFalse], c3, at[0C,10, resultType]; { Zero } temp1Low _ temp1Low and 1, ZeroBr, GOTO[checkRecSign], c3, at[0D,10, resultType]; { Normal} {I suppose that infinity mode is projective, if you want to use the affine mode, you modify the statement wrotten below, GOTO[checkInfinity] ---> GOTO[activateNewMethod]} GOTO[checkInfinity], c3, at[0E,10,resultType]; { infinity } { at[0F, 10, resultType} checkRecSign: BRANCH[argGreater, recGreater], c1; recGreater: floatTemp _ 1, c2; {Receiver > argument } L2Disp, GOTO[TrueOrFalse], c3; argGreater: floatTemp _ floatTemp xor ~floatTemp, c2; L2Disp, GOTO[TrueOrFalse], c3; checkInfinity: temp2Low _ uArg1Hi, c1; {restorethe highhalf of receiver} temp3Low _ uArg1Lo, L1 _ L1.checkInfinity, c2; CALL[checkFloatType], c3; checkInfinity1: [] _ floatTemp xor 2, ZeroBr, c1, at[L1.checkInfinity,10, checkFloatType-return]; temp2Low _ uArg2Hi, BRANCH[ $, recInfinity], c2; GOTO[activateNewMethodInBank0], c3; { Zero or Normal - Infinity --> unorder in projective mode} recInfinity: L1 _ L1.checkInfinity1, c3; recInfinity1: temp3Low _ uArg2Lo, c1; Noop, c2; CALL[checkFloatType], c3; recInfinity2: [] _ floatTemp xor 2, ZeroBr, c1, at[L1.checkInfinity1, 10, checkFloatType-return]; BRANCH[$, infAndInf], c2; GOTO[activateNewMethodInBank0], c3; { Infinity - Zero or normal --> unordered in projective mode} infAndInf: floatTemp _ 0, L2Disp, GOTO[TrueOrFalse], c3; { Equal } TrueOrFalse: RET[floatCompare-ret], c1; fppCompareINX: GOTO[checkSign1], c1; { temp2Low = result of subtraction } fppCompareOF: temp2Low _ uArg1Hi, c1; checkSign1: temp3Low _ 80, c2; temp3Low _ temp3Low LRot8, c3; { to check the receiver's sign } [] _ temp2Low and temp3Low, ZeroBr, c1; { actually check the receiver's sign} BRANCH[recMinus , recPlus], c2; recPlus: floatTemp _ 1, L2Disp, GOTO[TrueOrFalse], c3; { floatTemp _ 1 : receiver > argument } recMinus: floatTemp _ floatTemp xor ~floatTemp, L2Disp, GOTO[TrueOrFalse], c3; {floatTemp _ -1 } { This Subroutine is used for checking the type of floating number. Entry point: temp2Low,,temp3Low have floating number to be checked. L1 has return address. Entry c1, Return c3; Retrun point: floatTemp has the value respectively Zero : 0 Normal or denormalized number: 1 Infinity: 2 NAN: 3 Also, the component of floating number is stored in temp1Low,temp2Low,temp3Low separately. ** in fixed pitch, -- font: Gatch,system ** 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 temp1Low: E E E E E E E E - - - - - - - S temp2Low: - - - - - - - - - F F F F F F F temp3Low: F F F F F F F F F F F F F F F F } checkFloatType: Q _ ~0FF, c1; { Q = 0FF00 } temp1Low _ temp2Low LRot1, c2; {High half of temp1Low is Exponent} floatTemp _ temp1Low and Q, c3; { Exponent } temp1Low _ temp1Low and 1, c1; { Sign } [] _ floatTemp, ZeroBr, c2; { low byte of uSign is Exponent , Exponent = 0 ??} [] _ floatTemp xor Q, ZeroBr, BRANCH[$, exp1Zero], c3; { exponent = 255'd check ??} temp2Low _ temp2Low and 07F, BRANCH[$,infOrNan], c1; temp1Low _ temp1Low or floatTemp, L1Disp, c2; floatTemp _ floatNormal, RET[checkFloatType-return], c3; {checkFloatType-ret: Noop, c1; checkFloatType-ret1: L1Disp, c2; RET[checkFloatType-return], c3; } infOrNan: temp2Low _ temp2Low and 07F, c2; [] _ temp3Low, ZeroBr, c3; { check low half of fractional part } [] _ temp2Low, ZeroBr, BRANCH[$, recFracLowZero0], c1; temp1Low _ temp1Low or floatTemp, CANCELBR[nan1], L1Disp, c2; nan1: floatTemp _ floatNan, {GOTO[checkFloatType-ret]}RET[checkFloatType-return], c3; recFracLowZero0: temp1Low _ temp1Low or floatTemp, BRANCH[nan, infinity], L1Disp, c2; nan: floatTemp _ floatNan, RET[checkFloatType-return]{GOTO[checkFloatType-ret]}, c3; {Nan} infinity: floatTemp _ floatInfinity, RET[checkFloatType-return] {GOTO[checkFloatType-ret]}, c3; {infinity} exp1Zero: { Receiver's Exponent = 0, it means Normal zero , or denormalized number } temp1Low _ floatTemp or temp1Low, CANCELBR[$], c1; { sign and exponent bit of receiver } temp2Low _ temp2Low and 07F, c2; { high half } [] _ temp3Low, ZeroBr, c3; { check lowhalf of fraction } [] _ temp2Low, ZeroBr, BRANCH[$, recFracLowZero1], c1; { check high half } CANCELBR[denormalizedNumber1], L1Disp , c2; denormalizedNumber1: floatTemp _ floatNormal, RET[checkFloatType-return],{GOTO[checkFloatType-ret], }c3; recFracLowZero1: L1Disp, BRANCH[denormalizedNumber, receiverZero], c2; denormalizedNumber: floatTemp _ floatNormal, RET[checkFloatType-return], {GOTO[checkFloatType-ret],} c3; {denormalized number} receiverZero: floatTemp _ floatZero, RET[checkFloatType-return],{GOTO[checkFloatType-ret],} c3; { Zero }