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