{<>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 }