{File: <>*>*>FloatPrimitives.mc

Created by Toru Tokunaga  25-Feb-85 19:45:19
This file includes all primitves concerning with floating point operation.
  
Edit History:
Toru Tokunaga  26-Jun-85 14:23:02	
Toru Tokunaga  25-Apr-85 21:44:52	Correct the timesTwoPower Primitive
Toru Tokunaga   9-Apr-85 10:25:48	return linkage change for otMap1Bank0
Toru Tokunaga 	9-Apr-85  8:50:08	finish debugging( truncate, fractionPart, exponent, timesTwoPower)
Toru Tokunaga   8-Apr-85 21:18:11 	finish the all coding(truncate, fractionPart, exponent, timesTwoPower)
Toru Tokunaga   5-Apr-85 20:03:43	add the table for  primitive No.52 ~ 54
Toru Tokunaga   5-Apr-85 15:02:01	add floatTruncated primitive
Toru Tokunaga   2-Apr-85 16:07:55 	If FPP status = ~OK or ~InExact   --> primitive fail
Toru Tokunaga   1-Apr-85 16:50:22 	add float division primitive
Toru Tokunaga  21-Mar-85 14:18:56	modification for moving this microcode from bank1 to bank0
Toru Tokunaga   8-Mar-85 14:30:36	correct stack ACCESS, stackLow + 1 --> stackLow - 1;
Toru Tokunaga   7-Mar-85 17:51:57	if SmallInt > 0 --> Q ←0, otherwise Q ← 0FFFF  in primitiveAsFloat
Toru Tokunaga   7-Mar-85 15:06:03	make base of bank2 and bank3 in this file
Toru Tokunaga   5-Mar-85 20:41:52	add the Floating comparison Primitive
Toru Tokunaga  26-Feb-85 16:55:13	Add Asfloat Primitve

}

	L4 ← unaryMessage,		GOTO[primitiveAsFloat], 	c3, at[ 8, 10, bank2InBank0];{AsFloat }
	temp1Low ← floatAdd,		GOTO[floatBinaryMessage],	c3, at[ 9, 10, bank2InBank0];{floatAdd}
	temp1Low ← floatSub,		GOTO[floatBinaryMessage],	c3, at[0A, 10, bank2InBank0];{floatSubtract}
	
	temp1Low ← floatLessThan,	GOTO[floatBinaryMessage],	c3, at[0b, 10, bank2InBank0];{floatLessThan}
	temp1Low ← floatGreaterThan, 	GOTO[floatBinaryMessage],	c3, at[0c, 10, bank2InBank0];{floatGreaterThan}
	temp1Low ← floatLessOrEqual, 	GOTO[floatBinaryMessage],	c3, at[0d, 10, bank2InBank0];{floatLessOrEqual}
	temp1Low ← floatGreaterOrEqual,	GOTO[floatBinaryMessage],	c3, at[0e, 10, bank2InBank0];{floatGreaterOrEqual}
	temp1Low ← floatEqual,		GOTO[floatBinaryMessage],	c3, at[0f, 10, bank2InBank0];{floatEqual}
	temp1Low ← floatNotEqual,	GOTO[floatBinaryMessage],	c3, at[ 0, 10, bank3InBank0];{floatEqual}
	
	temp1Low ← floatMultiply,	GOTO[floatBinaryMessage],	c3, at[ 1, 10, bank3InBank0];{floatMultiply}
	temp1Low ← floatDivide,		GOTO[floatBinaryMessage],	c3, at[ 2, 10, bank3InBank0];{float divide}
	temp1Low ← floatTruncated,	GOTO[floatUnaryMessage], 	c3, at[ 3, 10, bank3InBank0];{float Truncated}
	temp1Low ← floatFractional,	GOTO[floatUnaryMessage], 	c3, at[ 4, 10, bank3InBank0];{fractional part}
	temp1Low ← floatExponent,	GOTO[floatUnaryMessage], 	c3, at[ 5, 10, bank3InBank0];{exponent }
	L4 ← binaryMessage,		GOTO[primitiveTimesTwoPower], 	c3, at[ 6, 10, bank3InBank0];{ floatTwotimes }

{ L4 indicates that the message is binary message or unary message }
floatUnaryMessage:
	MAR ← [stackHigh, stackLow + 0], L1 ← getUnaryFloatReceiver,		c1; 
	uPPsave ← temp1Low,							c2; { save the indicator for what kind of primitive }
	otLow ← MD, CALL[otMapBank0],						c3; { get Oop & to get the real address of Object }
	
	temp1Low ← temp1Low + firstFieldOfObject,	c1, at[getUnaryFloatReceiver, 10, otMapBank0-return];
	L4 ← unaryMessage,				c2; { indicate this primitive =  unarymessage }
	Q ← 0FF + 1,					c3; { preparation for float truncated Primitive }
	
	MAR ← [temp1High, temp1Low + 0],		c1;
	temp1Low ← temp1Low + 1,CANCELBR[$,2],		c2;
	temp2Low ← MD,					c3; { get the  high half of floating point }
	
	MAR ← [temp1High, temp1Low + 0],			c1;
	Xbus ← uPPsave, XDisp,	CANCELBR[$,2],			c2; { dispatching for what kind of primitive in unarymessage }
	temp3Low ← MD,	DISP4[whatKindOfUnaryPrimitive, 0C],	c3; { get the low half of flaoting point }

floatBinaryMessage:
	L4 ← binaryMessage,		c1;
	uPPsave ← temp1Low,		c2; { save temp1Low indicating the actual operation (i.e. + - / * etc}
	GOTO[floatBinary],		c3; {  }
{
Since floating operation needs two number(receiver,argument),the routine described below  common  for operation for floating arithmetic , etc 
 At entry point,  L4 has indicator of distinguishing the message pattern (ie: 0 -> UnaryMessage, 1 -> BinaryMessage)
   and temp1Low has what kind of primitive we execute 
 }
 
floatBinary:
	MAR ← [stackHigh, stackLow + 0] , L2 ← getFloatClass	c1; { read argument  }
	temp2Low ← classFloatPointer, 				c2; { temp2Low has Oop of the FloatCalss to check whether argument's class is floatClass}
	otLow ← MD,  XDisp, CALL[getClassBank0],		c3; { to check the smallinteger or Oop  -- commonroutines.mc}
		
	[] ← temp3Low - temp2Low, ZeroBr,					c1,  at[getFloatClass, 10, getClassBank0-return]; { Class is Float ??}
	temp1Low ← temp1Low + firstFieldOfObject, BRANCH[notFloatClass,$], 	c2; { Point the receiver of real object area -- no header }
	Noop, 									c3; { temp1High,,temp1Low has the address of object }
	
	MAR ← [temp1High, temp1Low + 0],		c1; { get the Floating number  -- Argument } 
	temp1Low ← temp1Low + 1,			c2;	
	temp2Low ← MD,					c3; { High half of Floaitng number}

	MAR ← [temp1High, temp1Low + 0],		c1;
	stackLow ← stackLow - 1,			c2; { to get Receiver's Oop }
	temp3Low ← MD,	L1 ← getFloatReceiver,		c3; { Low half of Floating number } 
   	

	MAR ← [stackHigh, stackLow + 0],		c1; { to get Oop of receiver}
	uArg2Hi ← temp2Low, 				c2; { save high half of argument }
	otLow ← MD,	CALL[otMapBank0],			c3; 

	temp1Low ← temp1Low + firstFieldOfObject, 	c1, at[getFloatReceiver, 10, otMapBank0-return];
	stackLow ← stackLow + 1,			c2; { reset the stack pointer }
	Q ← 0FF,					c3; {  prepare for Float Divide operation }
	  	
getFloatNumberHigh:		
	MAR ← [temp1High, temp1Low + 0 ],  		c1; { get the Float number}
	temp1Low ← temp1Low + 1, 			c2;
	temp2Low ← MD,					c3; { get high half (16bits) }
  
	
	MAR ← [temp1High, temp1Low + 0],		c1; 
	uArg2Lo ← temp3Low, CANCELBR[$,2],		c2; { save lowhalf of  argument }
	temp3Low ← MD, 					c3; { get low half (16 bits) }
	
	Xbus ← uPPsave, XDisp,		c1;
	DISP4[whatKindOfBinaryPrimitive],	c2;
		
	 GOTO[startFloatOperation],	c3,	at[ 0, 10, whatKindOfBinaryPrimitive]; { FloatAdd }
	 GOTO[startFloatOperation],	c3,	at[ 1, 10, whatKindOfBinaryPrimitive]; { FloatSubtract }
{						at[ 2, 10, whatKindOfBinaryPrimitive]; { FloatLessThan }
						at[ 3, 10, whatKindOfBinaryPrimitive]; { FloatGreaterThan }
						at[ 4, 10, whatKindOfBinaryPrimitive]; { FloatLessThanOrEqual }
						at[ 5, 10, whatKindOfBinaryPrimitive]; { FloatGreaterThanOrEqual }
						at[ 6, 10, whatKindOfBinaryPrimitive]; { FloatEqual }
						at[ 7, 10, whatKindOfBinaryPrimitive]; { FloatNotEqual } }
	 GOTO[startFloatOperation],	c3,	at[ 8, 10, whatKindOfBinaryPrimitive]; { FloatMultiply }
{						at[ 9, 10, whatKindOfBinaryPrimitive]; } { FloatDivide }
		
{ So far, we do not use  }
{						at[ 0A, 10, whatKindOfBinaryPrimitive]; 
						at[ 0B, 10, whatKindOfBinaryPrimitive];
						at[ 0C, 10, whatKindOfBinaryPrimitive];
						at[ 0D, 10, whatKindOfBinaryPrimitive];
						at[ 0E, 10, whatKindOfBinaryPrimitive];
						at[ 0F, 10, whatKindOfBinaryPrimitive]; }

startFloatOperation:
	Q ← 0FF + 1,			c1; { to get the FPP status }	
	PPort ← ~Q,			c2; { bus direction = input mode }
	Noop,{Q ← uFloatMode,}	 	c3; {}
	
	Xbus ← uPPsave, XDisp,					c1; { }
	FloatMode.RN.PI.IEEE, FloatFLOW, DISP4[FloatOp],	c2; { Dispatch to prepare something for each float primitive operation,
							and If operation is Arithmetic(+ - *) Come back to FloatArithCommon --- see below} 

FloatArithCommon:
	FloatA ← temp3Low LRot0,		c1;
	FloatStartFlow,				c2;  
	temp3Low ← classFloatPointer,		c3; {wait}
	
	uClassToInstantiate ← temp3Low,		c1;
	temp3Low ← 2,				c2; { Object size except header }
	FloatUnloadS,	Float.M,		c3; { to get the result of high half(16 bits)}
	
	FloatUnloadS,	Float.L,	c1; { to get the result of low half(16 bits)}
		
nowGetResult:
       	Q ← PPort, 			c2; { Get the Status : note -- real state is complemented }
	uNewValHi ← FloatResult,  	c3; { actually get the result of highhalf}
	
	uNewValLo ← FloatResult					c1; { actually get the result of lowhalf }
	uFloatComResult ← Q,	 YDisp, 			c2; { Check status  }
	Q  ← temp1Low xor ~temp1Low, DISP4[FPPStatus, 1],  	c3; {Q = all 1}
		
{ You may think that it is waste of the control store, if you think so, please delete this dipatch table.  I think it is very useful to debug the microcode. }		
ok:
	PPort ← Q, GOTO[FPOK], 			c1, at[0F, 10, FPPStatus];	{ Status OK!!  Bus direction is BXbus <-- Xbus  :: DEFAULT}
inexact:	
	PPort ← Q, GOTO[FPOK],			c1, at[0D, 10, FPPStatus];	{ Inexact occur }
unf:	
	PPort ← Q, GOTO[floatPrimitiveFail2],	c1, at[0B, 10, FPPStatus];	{ Underflow }
unfinex:	
	PPort ← Q, GOTO[floatPrimitiveFail2],	c1, at[09, 10, FPPStatus];	{ Underflow + Inexact }
unused:	
	PPort ← Q, GOTO[floatPrimitiveFail2],	c1, at[07, 10, FPPStatus];	{ Unused  }
ovf:	
	PPort ← Q, GOTO[floatPrimitiveFail2],	c1, at[05, 10, FPPStatus];	{ Overflow }
invalid:	
	PPort ← Q, GOTO[floatPrimitiveFail2],	c1, at[03, 10, FPPStatus];	{ Invalid operand }
denormal:	
	PPort ← Q, GOTO[FPOK],			c1, at[01, 10, FPPStatus];	{ Denormalized operand  }
	

FPOK:
	temp3High ← creatingFloatInstance,	c2;	{the return link for creating the instance in temp3High}
	CALL[createInstanceWithWordsInBank0],	c3;

{ Now, we have the object body pointed by temp1High,,temp1Low and new Oop stored in otLow}


retrunFromCreate:
	L1 ← floatReturn,		c1,	at[creatingFloatInstance,	10,  createInstanceInBank0-return];
	Noop,				c2;
{ otLow must have the Oop and  temp1High,temp1Low will have the  first address of object }
	CALL[otMapBank0],		c3; 
	
returnFromCreate2:
	temp1Low ← temp1Low + firstFieldOfObject,		c1,at[floatReturn, 10, otMapBank0-return];
	Noop,			c2;
	Noop,			c3;
				
	MAR ← [temp1High,temp1Low + 0],				c1; { store the highhalf of the Float number }
	MDR ← uNewValHi, CANCELBR[$,2], LOOPHOLE[wok],		c2;
	temp1Low ← temp1Low + 1,				c3;
		
	MAR ← [temp1High, temp1Low + 0],			c1; { store the lowhalf of the float number  } 
	MDR ← uNewValLo, CANCELBR[$,2],  LOOPHOLE[wok],	L4Disp,	c2; { L4 has unary or binary }
	temp1Low ← nilPointer, BRANCH[unaryMessageReturn,binaryMessageReturn, 0E],	c3; {floatTemp has already have the same value as uNewObject}



compareReturn:
	Noop, 		c2;
	temp1Low ← nilPointer,GOTO[binaryMessageReturn],	c3;

unaryMessageReturn:		
	MAR ← [stackHigh, stackLow + 0],	c1; { store the Oop of the float number to stack}
	MDR ← floatTemp,			c2;
	GOTO[nextByteCodeInBank0],		c3; { go to bank1 & dispatch to next bytecode } 

binaryMessageReturn:
	MAR ← [stackHigh, stackLow + 0], 			c1;
	MDR ← temp1Low,						c2; {floatTemp must have nilPointer}
	stackLow ← stackLow - 1, GOTO[unaryMessageReturn],	c3;
		

notFloatClass:
	CANCELBR[floatPrimitiveFail1],		c3; { since stackLow will increase by 1 at destination }



{ Floationg primitive fail }	
floatPrimitiveFail1:
	Noop,					c1;	
floatPrimitiveFail2:
	Noop,					c2; 
floatPrimitiveFail3:
	temp1Low ← 1, GOTO[saveSmalltalkStateBank0],{GOTO[activateNewMethodInBank0],}		c3;	    
			
{=== begin: primitive 40 - AsFloat ===}
primitiveAsFloat:
	MAR ← [stackHigh, stackLow + 0] ,		c1; {start read receiver}
	Q ← 0, 						c2; {used for High 8 bit of smallinteger}
	temp1Low ← MD,	XDisp,				c3; {get and check the receiver is smallInteger}

primitiveAsFloat1:		
	[] ← temp1Low LRot0, XHDisp,	{ Determine sign of Receiver} BRANCH[PrimFailAsFloat,$,0E],		c1;
	temp3High ← creatingFloatInstance, BRANCH[positiveInteger,negativeInteger, 2],	c2; { return link for createInstanceWithWords}
positiveInteger:
	uFloat ← Q,    { since positive, high 16bits = all 0}		c3;
	temp1Low ← RShift1 temp1Low,	SE ← 0,	GOTO[startFloat],	c1; { adjust to real positive smallinteger }
negativeInteger:
	uFloat ← ~Q,  { since negative, high 16bits = all 1}		c3;
	temp1Low ← RShift1 temp1Low,	SE ← 1,	GOTO[startFloat]	c1; { adjust to real negative smallinteger }
		
startFloat:
	{ In this routine, I never check the status of Floating point Processor }
	FloatMode.RN.PI.IEEE, FloatFLOW,		c2;{ Round to nearest, Projective mode, IEEE }
	FloatA ← uFloat, FLFloatA,			c3;{  high half }
		
	FloatA ← temp1Low LRot0,			c1;{ Low 16bits }
	FloatStartFlow,					c2;
	temp3Low ← classFloatPointer,			c3;
		
	uClassToInstantiate ← temp3Low,		c1;
	temp3Low ← 2,				c2; { number of needed words for Floating point object }
	FloatUnloadS, Float.M,	c3;	{ to Load High half of the floating point  and set the retrun address for creating the instance in temp3High}
		
	FloatUnloadS, Float.L,				c1;	{ to load low half of the floaing point}
	uNewValHi ← FloatResult,			c2;	{ load the high result  }
	
	uNewValLo ← FloatResult,      CALL[createInstanceWithWordsInBank0],	c3;	{ load the Low result & GO!! Create Floating Point Instance -- Memorymanglement.mc  }
	
    { At return, otLow and uNewObject have the Oop of new created instance, and uNewValHi,,uNewValLo have the 32bits Floating point number}
		
PrimFailAsFloat:
	CANCELBR[floatPrimitiveFail3],		c2; { primitive fail and since stackLow will increase by 1 at destination }
			
{=== end: primitive 40 - AsFloat ===}

		
{=== begin: primitive 41 - FloatAdd ===}

primitiveFloatAdd:
	uFloatPlus ← temp2Low ,	c3,	at[floatAdd, 10, FloatOp];{ use ufloatPlus, why?  -- see MI format for floating point processor}
	FloatAB ← uArg2Hi,		c1;
		
	FloatAB ← uArg2Lo,		c2;
	FloatA ← uFloatPlus, FLPlus, GOTO[FloatArithCommon],	c3;
				
{=== end: primitive 41 - FloatAdd ===}
{=== begin: primitive 42 - FloatSubtract ===}

primitiveFloatSubtract:
	uFloatMinus ← temp2Low,		c3,  at[floatSub, 10, FloatOp]; { use ufloatMinus, why ? -- see MI format for floating point processor}
	FloatAB ← uArg2Hi,		c1;
	
	FloatAB ← uArg2Lo,		c2;
	FloatA ← uFloatMinus, FLAMinusB, GOTO[FloatArithCommon],	c3;
		
{=== end: primitive 42 - FloatSubtract ===}
{=== begin: primitive 43 - FloatLessThan ===}

primitiveFloatLessThan:
	L2 ← L2.floatLessThan,	c3,	at[floatLessThan, 10, whatKindOfBinaryPrimitive];
	CALL[floatCompare],	c1;
	
	[] ← floatTemp, NegBr,		c2,  at[L2.floatLessThan, 10, floatCompare-ret];
	BRANCH[lessThanFalse, lessThanTrue],			c3;
lessThanFalse:
	floatTemp ← falsePointer, GOTO[compareReturn],	c1;
lessThanTrue:
	floatTemp ← truePointer,  GOTO[compareReturn],	c1;
{=== end: primitive 43 - FloatLessThan ===}
{=== begin: primitive 44 - FloatGreaterThan ===}

primitiveFloatGreaterThan:
	L2 ← L2.floatGreaterThan, 	c3,   at[floatGreaterThan, 10, whatKindOfBinaryPrimitive];
	CALL[floatCompare],		c1;
	
	[] ← floatTemp xor 1, ZeroBr,	c2,   at[ L2.floatGreaterThan, 10, floatCompare-ret];
	BRANCH[greaterThanFalse, greaterThanTrue],	c3;
greaterThanTrue:
	floatTemp ← truePointer,   GOTO[compareReturn],		c1;
greaterThanFalse:
	floatTemp ← falsePointer,   GOTO[compareReturn]	,	c1;	
		
{=== end: primitive 44 - FloatGreaterThan ===}
{=== begin: primitive 45 - FloatLessOrEqual ===}

primitiveFloatLessOrEqual:
	L2 ← L2.floatLessOrEqual,    c3,   at[floatLessOrEqual, 10, whatKindOfBinaryPrimitive];
	CALL[floatCompare],	c1;
	
	[] ← floatTemp xor 1,  ZeroBr,	c2,   at[ L2.floatLessOrEqual, 10, floatCompare-ret];
   	BRANCH[lessOrEqualTrue, lessOrEqualFalse],	c3;
lessOrEqualTrue:
	floatTemp ← truePointer,   GOTO[compareReturn],		c1;
lessOrEqualFalse:
	floatTemp ← falsePointer,   GOTO[compareReturn],	c1;
		
{=== end: primitive 45 - FloatLessOrEqual ===}
{=== begin: primitive 46 - FloatGreaterOrEqual ===}

primitiveFloatGreaterOrEqual:
	L2 ← L2.floatGreaterOrEqual, 	c3,   at[floatGreaterOrEqual, 10, whatKindOfBinaryPrimitive];
	CALL[floatCompare],	c1;
	
	[] ← floatTemp, NegBr,	c2,   at[L2.floatGreaterOrEqual, 10, floatCompare-ret];
	BRANCH[greaterOrEqualTrue, greaterOrEqualFalse],	c3;
greaterOrEqualTrue:
	floatTemp ← truePointer,   GOTO[compareReturn],		c1;
greaterOrEqualFalse:
	floatTemp ← falsePointer,   GOTO[compareReturn],	c1;
	
		
{=== end: primitive 46 - FloatGreaterOrEqual ===}
{=== begin: primitive 47 - FloatEqual ===}

primitiveFloatEqual:
	L2 ← L2.floatEqual,  	c3,   at[floatEqual, 10, whatKindOfBinaryPrimitive];
	CALL[floatCompare],	c1;
	
	[] ← floatTemp, ZeroBr, 	c2,   at[L2.floatEqual, 10, floatCompare-ret];
	BRANCH[equalFalse, equalTrue],		c3;
equalTrue:
	floatTemp ← truePointer,   GOTO[compareReturn],	c1;
equalFalse:
	floatTemp ← falsePointer,  GOTO[compareReturn],	c1;
		
	
		
{=== end: primitive 47 - FloatEqual ===}
{=== begin: primitive 48 -  FloatNotEqual ===}

primitiveFloatNotEqual:
	L2 ← L2.floatNotEqual,   	c3,   at[floatNotEqual, 10, whatKindOfBinaryPrimitive];
	CALL[floatCompare],		c1;
	
	[] ← floatTemp, ZeroBr,		c2,   at[L2.floatNotEqual, 10, floatCompare-ret];
	BRANCH[notEqualTrue, notEqualFalse],		c3;
notEqualTrue:
	floatTemp ← truePointer,   GOTO[compareReturn],   c1;
notEqualFalse:
	floatTemp ← falsePointer,   GOTO[compareReturn],   c1;
	
		
{=== end: primitive 48 - FloatNotEqual ===}
{=== begin: primitive 49 - FloatMultiply ===}

primitiveFloatMultiply:
	uFloatMultiply ← temp2Low,	c3,  at[floatMultiply, 10, FloatOp];
	
	FloatAB ← uArg2Hi,		c1;
	FloatAB ← uArg2Lo,			c2;
	FloatA ← uFloatMultiply, FLTimes.A.B,  	c3;
	
	FloatA ← temp3Low LRot0,			c1;
	FloatStartFlow,				c2;
	temp3Low ← classFloatPointer,		c3;
	
	uClassToInstantiate ← temp3Low,		c1;
	temp3Low ← 2,				c2;
	FloatUnloadP, Float.M,			c3;
	
        FloatUnloadP, Float.L, GOTO[nowGetResult],	c1;
		
{=== end: pimitive 49 - FloatMultiply ===}

{=== begin: primitive 50 - FloatDivide ===}

primitiveFloatDivide:
{at this point, Q = 0FF, temp2Low,,temp3Low have the receiver's value, and uArg2Hi,uArg2Lo havethe argument value}
	uArg1Hi ← temp2Low,		c3,   at[ 9, 10, whatKindOfBinaryPrimitive];  { FloatDivide }

	uArg1Lo ← temp3Low,		c1;	{ uArg1High,,uArg1Low have Receiver }
	L1 ← L1.checkReceiver,		c2;
	CALL[checkFloatType],		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
} 

Go1:	
	Ybus ← floatTemp xor floatNan, ZeroBr,		c1,  at[ L1.checkReceiver, 10, checkFloatType-return];	{ to check if receiver = NAN }
	uFloatComResult ← floatTemp, BRANCH[$, receiverIsNan],	c2;
	floatTemp ← temp1Low and 1,				c3; 
	
	uSign1 ← floatTemp,			c1; { uSign1 = receiver's sign }
	Q ← 0FF,				c2;
	temp1Low ← (temp1Low LRot8) and Q,	c3;  { receiver's Exponent }
	
	uExp1 ← temp1Low,			c1;
	temp2Low ← temp2Low LRot8,		c2;
	floatTemp ← (temp3Low LRot8) and Q,	c3;
	
	floatTemp ← temp2Low or floatTemp,	c1; {  High 16 bit of fractional part -- except leading  bit }
	uHighHalf1 ← floatTemp,			c2;
	floatTemp ← temp3Low LRot8,		c3;
	
	Q ← ~Q,					c1;
	floatTemp ← floatTemp and Q,		c2;
	uLowHalf1 ← floatTemp,			c3; { Low 8 bit of fractional part }
	
	temp2Low ← uArg2Hi,				c1;
	temp3Low ← uArg2Lo, L1 ← L1.checkArgument,	c2;
	CALL[checkFloatType],				c3; { check argument TYPE}
Go8:	
	Ybus ← floatTemp xor floatNan, ZeroBr,			c1,  at[L1.checkArgument, 10, checkFloatType-return];
	floatTemp ← (LShift1 floatTemp),SE ← 0, BRANCH[$, argumentIsNan],	c2;	
	floatTemp ← LShift1 floatTemp ,  SE ← 0, 				c3;	
	
	floatTemp ← floatTemp or uFloatComResult,	c1;
	[] ← floatTemp, YDisp,				c2;
	Q ← 0FF,DISP4[floatDivideType],			c3; { Q : to make  NAN }

{According to IEEE standard, NAN must be returned in case of 0.0 / 0.0 operation, but Mesa coded primitive create the ZERO Division } 	
	GOTO[zeroDivision], 			         c1,at[ 0, 10, floatDivideType];  { 0.0 / 0.0 }{primitive Fail - Zero Division }
	GOTO[zeroDivision],			         c1,at[ 1, 10, floatDivideType];  { W   / 0.0 }{primitive Fail - Zero Division }
	temp1Low ← temp1Low and 1, GOTO[returnInf1],     c1,at[ 2, 10, floatDivideType];  { INF / 0.0 }{return INF(receiver:check sign)}
{							    at[ 3, 10, floatDivideType];} { NAN / 0.0 }{return NAN}
	temp3Low ← uSign1, GOTO[returnZero],		 c1,at[ 4, 10, floatDivideType];  { 0.0 / W   }{return Zero(check sign)}
	floatTemp ← temp1Low LRot8,GOTO[prepareDivide],  c1,at[ 5, 10, floatDivideType];  { W   / W   }{to check exponent of argument }
	temp1Low ← temp1Low and 1,GOTO[returnInf1],	 c1,at[ 6, 10, floatDivideType];  { INF / W   }{return INF(receiver:check sign)}
{							    at[ 7, 10, floatDivideType];} { NAN / W   }{return NAN}
	temp3Low ← uSign1, GOTO[returnZero], 		 c1,at[ 8, 10, floatDivideType];  { 0.0 / INF }{return Zero(check sign)}
	temp3Low ← uSign1, GOTO[returnZero], 		 c1,at[ 9, 10, floatDivideType];  { W   / INF }{return Zero(check sign)}
	floatTemp ← floatNan,GOTO[returnNan],		 c1,at[0A, 10, floatDivideType];  { INF / INF }{return NAN}
{							    at[0B, 10, floatDivideType];} { NAN / INF }{return NAN}
{							    at[0C, 10, floatDivideType];} { 0.0 / NAN }{return NAN}
{							    at[0D, 10, floatDivideType];} { W   / NAN }{return NAN}
{							    at[0E, 10, floatDivideType];} { INF / NAN }{return NAN}
{							    at[0F, 10, floatDivideType];} { NAN / NAN }{return NAN}


{------ preparing for returning Nan -----------}		
receiverIsNan:
	floatTemp ← floatNan,GOTO[returnNan1],	c3; { to make a Nan : fractional high part}
argumentIsNan:
	floatTemp ← floatNan,			c3; { to make a Nan : fractional high part}
returnNan1:
	Q ← 0FF,GOTO[returnNan],		c1; { to make a Nan : exponent }
	
returnNan:
{floatTemp = floatNan, Q = 0FF }
	temp1Low ← Q,				c2; { exponent part = 0FF }
	temp3Low ← uSign1, GOTO[finalPack],	c3; { packing  to make 32 bit floating point format }
	
zeroDivision:
	GOTO[floatPrimitiveFail3],		c2;

returnInf1:
{ floatTemp has the argument's sign xor receiver's sign,and  Q = 0FF }
	temp3Low ← floatTemp,			c2; { store the new sign }
	temp1Low ← Q,				c3; { exponent for infinity }
	
	floatTemp ← floatTemp xor floatTemp,	c1; {  make high half of fractional part ZERO }
	Q ← floatTemp,				c2; { make low half of fractional part }
	GOTO[finalPack],			c3;
	
returnZero:
	temp3Low ← temp1Low xor temp3Low,	c2; 
	temp3Low ← temp3Low and 1,		c3; { new Sign }
	temp1Low ← 0,				c1; { clear exponent }
	
	floatTemp ←  0,				c2; { clear high half of fractional part }
	Q ← 0,GOTO[finalPack],			c3; { clear low half of fractional part }
	
{dePack the floating point number  uSign2,uExp2, uHighHalf2, uLowhalf2 } 
prepareDivide:
	floatTemp ← floatTemp and Q, ZeroBr,		c2; {check argument's exponent = 0  , Q = 0FF} 
	uExp2 ← floatTemp, BRANCH[argNormal, $],	c3;  { store exponent part }
	
{According to IEEE standards, return value must be NAN in this case.  If I return the Nan, 
it  make system trouble, so I ask help to Molasses in this case }

	GOTO[floatPrimitiveFail2],	c1; { if argment = denormalized number then return the NAN }

argNormal:
	floatTemp ← temp1Low and 1,			c1; { Sign bit }
	uSign2 ← floatTemp,				c2; {sign of argument}
	temp2Low ← temp2Low or 80, 			c3; {leading bit = 1 for argument}
argNormal1:
	floatTemp ← ~Q,					c1;	
	floatTemp ← temp3Low and floatTemp,		c2;
	floatTemp ← temp2Low or floatTemp,		c3;
	
	floatTemp ← floatTemp LRot8,			c1; { high half of fractional part -- argument  }
	uHighHalf2 ← floatTemp,				c2;
	temp3Low ← temp3Low LRot8,			c3;
	
	temp3Low ← temp3Low and ~0FF,			c1;
	uLowHalf2 ← temp3Low,				c2; { low half of fractional part -- argument : Low byte = 0 }
	[] ← uExp1 and Q,  ZeroBr,			c3; { check receiver's exponent = 0 }
	
argNormal3:	
	temp1Low ← uHighHalf1, BRANCH[$,  doDivide],		c1;
	temp2Low ← 80,						c2; { to make leading bit =1 for receiver }
	floatTemp ← temp2Low LRot8,				c3;
argNormal6:	
	temp1Low ← temp1Low or floatTemp, 			c1;	 {receiver's leading bit = 1 }
	uHighHalf1 ← temp1Low,	GOTO[doDivide0],		c2;
	
 { Now,	Receiver = uSign1, uExp1, uHighHalf1,uLowHalf1 ... Argument = uSign2, uExp2, uHighHalf2,uLowHalf2 }
	
doDivide:
	Noop,						c2;  
doDivide0:						
	uSaveHomeLow ← homeLow,				c3;  { to use the homeLow-register for dividing loop }
	
	temp2Low ← uExp1,				c1;
	temp1Low ← uExp2,				c2;
	temp2Low ← temp2Low - temp1Low,			c3;
	
	temp2Low ← temp2Low + 127'd,			c1;  	{ re-bias }
	uExp1 ← temp2Low,				c2;	{ result of exponent is stored in uExp1 }
	floatTemp ← uSign1,				c3;
	
	Q ← uSign2,					c1;
	uSign1 ← floatTemp xor Q,			c2; 	{ result of sign is stored in uSign1 }
	divisorHigh ← uHighHalf2,  			c3;
	
	Q ← ~uLowHalf2,					c1;
	divisorHigh ← DRShift1 divisorHigh, SE ← 0, 	c2;  { loads the operand and 1 right shiftto allow room shift left during divide loop}
	divisorLow ← ~Q,				c3;
	
	floatT ← uHighHalf1,				c1;
	Q ← ~uLowHalf1,					c2; { loads the operand and 1 right shiftto allow room shift left during divide loop}
	floatT ← DRShift1 floatT, SE ← 0,		c3;

{As per Ed Tafts Drado codem we will fo a total 26 iterations, 24 for quatinent, 2 guards bit. They are done by first doing 16 iterations, then 10 iterations}
doDivide6:	
	Q ← ~Q,  L3 ← L3.divide1,			c1;
	divCount ← 16'd, CALL[fptDivideLoopC3],		c2;  { 16 times loop }
	
	uHighHalf1 ← divResult,		c2,  at[L3.divide1, 10, fptDivLoopRets];
	floatT ← DLShift1 floatT, SE ← 1,{Q.15 ← 0} L3 ← L3.divide2, 	c3; {remainder did not get its last left shift}
doDivide7:	
	divCount ← 10'd,	CALL[fptDivideLoopC2],		c1;  { 10 times loop }
	
	divResult ← divResult LRot4,	c2,  at[L3.divide2, 10, fptDivLoopRets];
	[] ← floatT or Q, NZeroBr,	c3;
doDivide8:	
	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;
	
fptDivExit:
	homeLow ← uSaveHomeLow,			c1;	{ restore the  homeLow }
	uStickyBit ← 0, 			c2;

rePackC3:
	floatTemp ← uHighHalf1,			c3;
	
	Q ← uLowHalf1,				c1;
	
{nominal value = (-1)↑uSighn1 * <floatTemp[0].floatTemp[1],,,Q[7]>*2↑(uExp1 - 127)}

	temp1Low ← uExp1, 				c2;
	temp1Low ← temp1Low - 2,			c3;
	
	Ybus ← temp1Low, NegBr,				c1; { check exponent  = 1}

{nominal value = (-1)↑uSign1* <floatTemp[0].floatTemp[1],,Q[7]> *2↑(temp1Low +2 -127)}

normLoop:
	Ybus ← floatTemp, NegBr, BRANCH[$, lowExp],		c2;
	temp1Low ← temp1Low - 1,NegBr, BRANCH[$, normed],	c3;
	floatTemp ← DLShift1 floatTemp, SE ← 1, BRANCH[normLoop, smallNumber],	c1;
	
{At normed: nominal value = (-1)↑uSign1*<floatTemp[0].floatTemp[1],,Q[7]>*2↑(temp1Low=3-127) and floatTemp[0]=1,
therefore nominal exponent = temp1Low + 2, and nominal fraction = floatTemp[1],,Q[7]}

{At smallNumber: nominal value = (-1)↑uSign1*<floatTemp[0].floatTemp[1],,Q[7]>*2↑(temp1Low+2-127) and floatTemp = -1,
therefore niminal fraction = floatTemp[1],,Q[7]. and nominal exponent= 1 if floatTemp[0]=1, else 0, 
i.e. -- niminal exponent = floatTemp[0]}

{At LowExp: nominal value = (-1)↑uSign1*<floatTemp[0].floatTemp[1]..Q[7]>*2↑(temp1Low+2-127) and temp1Low < 0}

{we will shift right one bit , and add 1 to temp1Low, until temp1low = -1, then go to small number}
{Note: this cose is very painful for an exponent of 1, maybe I should avoid arriving here under those conditions?}



lowExp:
	temp2Low ← 25'd, CANCELBR[$],			c3;
	
	Ybus ← temp1Low + temp2Low, NegBr,		c1;
	temp2Low ← 1,  BRANCH[$, veryLowExp],		c2;
	Q ← ~Q, L3 ← L3.rePack1,			c3; { to allow for complementing on right shifts }
	
	temp1Low ← -temp1Low - 1, CALL[deNormC2],	c1;
veryLowExp:
	GOTO[floatPrimitiveFail1],		c3;	

smallNumberC1:
	Noop,			c1,  at[L3.rePack1, 10, deNormRets];
smallNumber:
	temp1Low ← RRot1 1,				c2;
	temp1Low ← LRot1 (temp1Low and floatTemp),	c3;{ temp1Low ← nominal exponent = floatTemp[0]}
	
	temp2Low ← RRot1 1, 				c1; 
	floatTemp ← floatTemp or temp2Low,		c2;{ floatTemp[0] ← 1}
	temp1Low ← temp1Low - 3, GOTO[normed],		c3;{normed wants temp1Low to hold nominal exponent - 3} 

{ nominal value = (-1)↑uSign1*<floatTemp[0].floatTemp[1],,..>*2↑(temp1Low+3-127) and floatTemp[0]=1,
therefore nominal exponent = temp1Low + 2, and nominal fraction = floatTemp[1]..Q[7]}
{also entered from smallnumber, arranged so that nominal Fracrion =<floatTemp[1]....>, floatTemp[0] = 1, and nominal exponent = temp1Low = 3}

normed: 
	CANCELBR[$],			c1;
	
{******************************** rounding code **************************
enter with 
	L3  -- return link,
	uSticky  prepared
	data <floatTemp,Q>

if inexact result , will generate trap, or set sticky register bit, depending on contents of sticky register
**************************************************************************}

round:
	Ybus ← uStickyBit, NZeroBr,			c2;
	temp2Low ← 377'b, BRANCH[roundA, roundB],	c3;
	
roundA:
	GOTO[roundC],				c1;
roundB:
	Q ← Q or 1, GOTO[roundC],		c1;

roundC:	
	Ybus ← Q and temp2Low,  ZeroBr,	c2;
	temp2Low ← 200'b, BRANCH[inExact, roundExit1],		c3;
	
{now We round to nearest }
inExact:
	Q ← Q + temp2Low,	CarryBr,			c1;
	temp2Low ← 177'b, BRANCH[$, inExact1],		c2;
	Ybus ← Q and temp2Low, ZeroBr,			c3;
	
	temp2Low ← LShift1 200'b, SE ← 0, BRANCH[roundExit2, $],	c1;
	Q ← Q and ~temp2Low, GOTO[roundExit],				c2; {Q[7] ← 0}	
	
{round off carried across word boundary }
inExact1:
	floatTemp ← floatTemp + 1, CarryBr,	c3; { overflow Branch since floatTemp[0]=1}
	
	BRANCH[roundExit2A, $],				c1;
	temp1Low ← temp1Low + 1,  GOTO[roundExit],	c2; { round off overflowed, adjust exponent }

roundExit2A:
	GOTO[roundExit],		c2;
	
roundExit1:
	Noop,		c1;
roundExit2:
	Noop,		c2;
roundExit:
	Noop,		c3;

{Now, we check for overflow and underflow }

	temp1Low ← temp1Low + 3,		c1;
	temp2Low ← 376'b,			c2;
	Ybus ← temp2Low - temp1Low, NegBr,	c3; { branch if temp1Low >= 377'B}
	
	Ybus ← temp1Low, ZeroBr,BRANCH[$, overFlowOccur],	c1;
	BRANCH[$,  underFlowOccur],				c2;
	temp3Low ← uSign1,GOTO[finalPack],			c3; { temp3Low has the final sign }
	
overFlowOccur:
	CANCELBR[floatPrimitiveFail3],			c2;
underFlowOccur:
	GOTO[floatPrimitiveFail1],			c3;

{sign = temp3Low, exponent = temp1Low,  fractional part = floatTemp[1]...Q[7], floatTemp[0] = 1}	

finalPack:
	temp2Low ← 0FF,				c1;
	Q ← Q and ~ temp2Low,			c2;  { bottom  8 bits of final result }
	temp2Low ← floatTemp and temp2Low,	c3;  { next 8 bits of final result }
	
	temp2Low ← temp2Low or Q,		c1;
	temp2Low ← temp2Low LRot8,		c2;  { Low half of fractional part }
	uNewValLo ← temp2Low,			c3;  { store }
	
	temp1Low ← temp1Low LRot8,		c1;
	temp1Low ← RRot1(temp1Low or temp3Low),	c2; { sign,exponent part}
	floatTemp ← floatTemp LRot8,		c3;
	
	floatTemp ← floatTemp and 7F,		c1; { create high 7 bits of fractinal part }
	uNewValHi ← temp1Low or floatTemp,	c2; { High half of fractional part }
	Noop,					c3; 

finalPack5:	
	Noop,			c1;
	temp3Low ← classFloatPointer,		c2;
	uClassToInstantiate ← temp3Low,		c3; { Oop of floatClass }
finalPack7:
	temp3Low ← 2,				c1; { object size  = 2 }
	temp3High ← creatingFloatInstance,	c2; { return link for createInstance }
	CALL[createInstanceWithWordsInBank0],	c3; { Go ! }
	
	
{=== end: primitive 50 - FloatDivide ===}
{=== begin: primitive 51 - Truncated ===}
primitiveTruncated:				{ float Truncated primitive}
{Q = 100'x,  temp2Low = high half, temp3Low = Low half }
	uFloatFix ← temp2Low,			c1, at[ 0D, 10, whatKindOfUnaryPrimitive]; 
	PPort ← ~Q,				c2; { to get the FPP status }
	FloatMode.RZ.PI.IEEE, FloatFLOW,	c3;
	
     	FloatA ← uFloatFix, FLFixA,		c1; { High half & function }
	FloatA ← temp3Low LRot0,		c2; { low half }
	FloatNop,				c3;
	
	temp1Low ←  0C0,				c1;
	temp1Low ← temp1Low LRot8,			c2; { temp1Low  ← 0C00  : to check the range}
	floatTemp ← floatTemp xor ~floatTemp,		c3; { floatTemp ← FFFF  : to check the range}
	
	FloatUnloadS, Float.M,			c1; { to get high 8 bit of 24 bits integer }
	FloatUnloadS, Float.L,			c2; { to get Low 16 bit of 24 bits integer }
	Q ← PPort,				c3; { get the FPP status }
	
	temp2Low ← FloatResult,			c1;
	temp3Low ← FloatResult,			c2;
	[] ← Q,	YDisp,				c3; { dispatching by FPP Status }
	
	Q ← temp1Low xor ~ temp1Low, DISP4[FPPStatusFix,1],			c1;
	
fixOk:
	PPort ← Q, GOTO[checkRange],		c2, at[0F, 10, FPPStatusFix]; { status OK }
	PPort ← Q, GOTO[checkRange],		c2, at[0D, 10, FPPStatusFix]; {inexact occur: this case is  for truncating the denormalized number }
	PPort ← Q, GOTO[floatPrimitiveFail3],	c2, at[0B, 10, FPPStatusFix]; { Underflow }
	PPort ← Q, GOTO[floatPrimitiveFail3],	c2, at[09, 10, FPPStatusFix]; { Underflow + Inexact }
	PPort ← Q, GOTO[floatPrimitiveFail3],	c2, at[07, 10, FPPStatusFix]; { Unused  }
	PPort ← Q, GOTO[floatPrimitiveFail3],	c2, at[05, 10, FPPStatusFix]; { Overflow }
	PPort ← Q, GOTO[floatPrimitiveFail3], 	c2, at[03, 10, FPPStatusFix]; { Invalid operand  }
	PPort ← Q, GOTO[floatPrimitiveFail3],	c2, at[01, 10, FPPStatusFix]; { Denormalized operand at multiply  }
	
checkRange:
	{ checking the fix number is in smallinteger's range }
	[] ← temp2Low, NegBr,			c3;
	
	BRANCH[fixedNumberPlus, fixedNumberMinus],			c1;
	
fixedNumberPlus: 
	[] ← temp2Low and  floatTemp,	ZeroBr,		c2;
	[] ← temp3Low and temp1Low, ZeroBr, BRANCH[outOfRange1, $],	c3;
	
	temp3Low ← LShift1 temp3Low, SE ← 1, BRANCH[outOfRange2, $],	c1; { create the smallinteger }
	GOTO[finishFix],						c2;
	
fixedNumberMinus:
	[] ← temp2Low xor floatTemp, ZeroBr,		c2;
	uSaveStackLow ← temp3Low and temp1Low, BRANCH[outOfRange3, $],	c3;
	
	[] ← temp1Low xor uSaveStackLow, ZeroBr,			c1;
	temp3Low ← LShift1 temp3Low, SE ← 1, BRANCH[outOfRange4, $],	c2; { create the smallinteger }
finishFix:
	floatTemp ← temp3Low,	GOTO[unaryMessageReturn],		c3;

							
outOfRange1:
	CANCELBR[floatPrimitiveFail2],		c1;
outOfRange2:
	GOTO[floatPrimitiveFail3],		c2;
outOfRange3:
	CANCELBR[floatPrimitiveFail2],		c1;	
outOfRange4:
	GOTO[floatPrimitiveFail1],		c3;						
	
{=== end: primitive 51 - Truncated ===}
{=== begin: primitive 52 -  FractionalPart ===}
primitiveFractionPart:
{ temp2Low, temp3Low has the Floating Number }
	temp1Low ← LRot1 temp2Low,		c1, at[0E, 10, whatKindOfUnaryPrimitive];
	floatTemp ← temp1Low and 1,		c2; { sign }
	uSign1 ← floatTemp,			c3; { save sign }
fractionPart1:	
	temp1Low ← temp1Low and ~0FF,		c1;
	temp1Low ← temp1Low LRot8,		c2; { Low byte = exponent}
        floatTemp ← temp1Low xor 0FF, 		c3; 
fractionPart2:	
	[] ← floatTemp, ZeroBr,						c1; { check Nan or Inf }
	floatTemp  ← temp1Low,	BRANCH[$, fractionPartNanOrInf],	c2;
	temp1Low ← temp1Low - 7F, 					c3;  
fractionPart3:	
	[] ← temp1Low, NegBr,						c1; { minus the bias  it means count for shift }
	Q ← temp3Low, BRANCH[$, returnJustReceiver],		c2; { Q has low half of the fractional part}
	temp3Low ← temp2Low and 7F,				c3; { high 7 bit of the fractional part}
	
fractionPart4:	
	temp1Low ←  temp1Low + 1,				c1; { create the shift counter }

fractionPartShiftLoop:	
	temp3Low ← DLShift1 temp3Low, SE ← 1, {Q.15 ← 0}, 	c2; { Left shift the fractional part }
	floatTemp ← floatTemp - 1,				c3; { decrement the exponent }
	
fractionPartShiftLoop1:	
	temp1Low ← temp1Low - 1, ZeroBr,			c1; { check shift counter }
	temp2Low ← 0FF, BRANCH[$, finishShift],			c2; { temp2Low isused after shift operation is finished}
	Noop,							c3;
	
fractionPartShiftLoop2:	
	GOTO[fractionPartShiftLoop],				c1;
	
finishShift:
	temp3Low ← temp3Low and temp2Low, 	c3;
finishShift1:	
	[] ← temp3Low or Q, ZeroBr,				c1; { check fractional part = 0 }
	temp1Low ← 80, BRANCH[$, returnValueZero], 		c2;
normalizeLoop:
	[] ← temp3Low and temp1Low,	ZeroBr,			c3;
	
	floatTemp ← floatTemp - 1, BRANCH[finishNormalize, $],			c1;
	temp3Low ← DLShift1 temp3Low, SE ← 1,{Q.15 ← 0}, GOTO[normalizeLoop],   c2;
	
finishNormalize:
	floatTemp ← floatTemp + 1,		c2;	
	floatTemp ← floatTemp LRot8,  		c3; { expponent }
	
	floatTemp ← floatTemp or uSign1,	c1; { or the sign }
	temp1Low ← RRot1 floatTemp,		c2;
	temp3Low ← temp3Low and 7F,		c3; { implict leading bit = 0}
	
	uNewValHi ← temp1Low or temp3Low,	c1; { high half of the floating point number }
	uNewValLo ← Q,	GOTO[returnResult3],	c2;	
		
returnValueZero:
	uNewValHi ← temp1Low xor temp1Low,				c3;
	uNewValLo ← temp1Low xor temp1Low, GOTO[returnResult2], 	c1; { creating the normal zero }
	
returnJustReceiver:
	uNewValHi ← temp2Low,					c3;
	uNewValLo ← temp3Low,	GOTO[returnResult2],		c1;
	
returnResult2:
	Noop,			c2;
returnResult3:
	temp3High ← creatingFloatInstance,			c3;
	
	temp3Low ← classFloatPointer,				c1;
	uClassToInstantiate ← temp3Low,				c2;
	temp3Low ← 2, CALL[createInstanceWithWordsInBank0],	c3;		
fractionPartNanOrInf:
	CANCELBR[floatPrimitiveFail1],		c3;		
{=== end: primitive 52 - FractionalPart ===}
{=== begin: primitive 53 - Exponent ===}
{
 definition:  return the exponent value as a smallinteger. 
floating point number = normal Zero then return the -1
If receiver = Infinity or Nan  then  PrimitiveFail 
}
primitiveExponent:
	floatTemp ← 7F,						c1, at[0F, 10, whatKindOfUnaryPrimitive];
	floatTemp ← floatTemp LRot8,				c2;  {7F00} 
	floatTemp ← floatTemp or 0FF,				c3;  {make  7FFF}
	
primitiveExponent1:	
	floatTemp ← temp2Low and floatTemp, 			c1; { ignore sign}
	[] ← temp3Low or floatTemp, ZeroBr, 			c2; { check normal zero or not }
	BRANCH[notNormalZero, normalZero],			c3;

normalZero:
	floatTemp ← floatTemp xor ~floatTemp , GOTO[exponentReturnResult1],		c1; { make the smallinteger (-1) }	
	

notNormalZero:	
	temp2Low ← LRot1 temp2Low,						c1;
        temp2Low ← temp2Low and ~0FF,						c2; {high byte is exponent }
	floatTemp ← temp2Low xor ~0FF, 						c3; 
	
	[] ← floatTemp, ZeroBr,						c1; { check exponent = 0FF : Nan or Infinity }
	temp2Low ← temp2Low LRot8, BRANCH[$, exponentNanOrInf],				c2;
	temp2Low ← temp2Low - 7F,						c3; {NET =  minus the bias from gross exponent }

		
exponentReturnResult:
	floatTemp ← LShift1 temp2Low, SE ← 1,			c1;
exponentReturnResult1:
	Noop,							c2;
	GOTO[unaryMessageReturn],				c3;

exponentNanOrInf:
	GOTO[floatPrimitiveFail1],						c3;
		
{=== endL Primitive 53 - Exponent ===}
{=== begin: primitive 54 -  TimesTwoPower ===}
 primitiveTimesTwoPower:
 	MAR ← [stackHigh, stackLow + 0],			c1; { point the argument }
	Noop,							c2;
	temp1Low ← MD, XDisp,					c3; { get argument  and check that argument = smallinteger }
	
	[] ← temp1Low LRot0, XHDisp,  {Determine the sign }BRANCH[primFailTimesTwoPower, $, 0E],	c1;
	stackLow ← stackLow - 1, BRANCH[positiveInteger1, negativeInteger1, 2],				c2; { point the receiver }
	
positiveInteger1:
 	temp1Low  ← RShift1 temp1Low, SE ← 0,	GOTO[getReceiver],		c3;
negativeInteger1:
	temp1Low ← RShift1 temp1Low, SE ← 1,					c3; 
	
getReceiver:
 	MAR ← [stackHigh,  stackLow + 0], L1 ← getTimesTwoPowerReceiver,	c1;
	uArg2Lo ← temp1Low,							c2; { save the argument  value }
	otLow ← MD, CALL[otMap1Bank0],						c3;
getReceiver1:	
	temp1Low ← temp1Low + firstFieldOfObject,		c1, at[getTimesTwoPowerReceiver, 10, otMap1Bank0-return];
	stackLow ← stackLow + 1,				c2; { reset the stack pointer }
	Q ← 0FF,						c3;
getReceiver2:
	MAR ← [temp1High, temp1Low + 0],	c1;
	temp1Low ← temp1Low + 1,		c2;
	temp2Low ← MD,				c3; { get high half of the floating point  number  and check 0}
getReceiver3:	
	MAR ← [temp1High,  temp1Low + 0], 	c1;
	floatTemp ← uArg2Lo,			c2; { load the value for adding the exponent }
	temp3Low ← MD,				c3; { get low half of the floating  point number }
getReciever3X:
	temp1Low ← 7F,			c1;
	temp1Low ← temp1Low LRot8,	c2;
	temp1Low ← temp1Low or 0FF,	c3; { to neglect the sign }
getReceiver3XX:
	[] ← temp1Low and temp2Low,ZeroBr,					c1;
	[] ← temp3Low,ZeroBr, BRANCH[hHalfNonZero, hHalfZero],	c2;
hHalfZero:
	uNewValLo ← temp1Low xor temp1Low, BRANCH[lHalfNonZero, resultZero],	c3;
resultZero:
	uNewValHi ← temp1Low xor temp1Low, GOTO[storeResult],		c1;

hHalfNonZero:
	CANCELBR[getReceiver4],			c3;

lHalfNonZero:
	temp1Low ← LRot1 temp2Low,GOTO[getReceiver4X],	c1; { high byte is exponent }
getReceiver4:
	temp1Low ← LRot1 temp2Low,			c1;  { high byte is exponent }
	
getReceiver4X:
	temp1Low ← temp1Low LRot8,		c2;
	temp1Low ← temp1Low and Q,		c3; { temp1Low has exponent }
getReceiver5:	
	[] ← temp1Low xor Q,	ZeroBr,						c1;{ chedk Nan or Inf }
	temp1Low ← temp1Low + floatTemp,NegBr,BRANCH[$, timesTwoPowerNanOrInf],	c2; { Add & check Low boundary}
	Ybus ← temp1Low - Q,NegBr, BRANCH[$, exponentTooSmall],			c3; { check high boundary }
getReceiver7:	
	uNewValLo ← temp3Low,	BRANCH[exponentTooLarge, $],	c1; { Low half of the floating point number }
	temp1Low ← temp1Low LRot8,				c2; { high byte is exponent }
	temp2Low ← LRot1 temp2Low,				c3;
getReceiver8:
	temp2Low ← temp2Low and 0FF,				c1; { clear the exponent part }	
	temp1Low ← temp1Low or temp2Low ,			c2; { new exponent value is ored  }
	temp1Low ← RRot1 temp1Low,				c3; { finish the high half of the floating point }
getReceiver9:	
	uNewValHi ← temp1Low,					c1; { get the high half of the result }
storeResult:
	temp3High ← creatingFloatInstance,			c2; { returnlink for createInstance }
	temp3Low ← classFloatPointer,				c3;
	
	uClassToInstantiate ← temp3Low,				c1; { class pointer for newly created object }
	temp3Low ← 2, 						c2; { temp3Low has the  actual size, to create the floating point object}
	CALL[createInstanceWithWordsInBank0],			c3;

primFailTimesTwoPower:
	CANCELBR[floatPrimitiveFail3],			c2;	
timesTwoPowerNanOrInf:
	CANCELBR[floatPrimitiveFail1],			c3;

exponentTooSmall:
	CANCELBR[floatPrimitiveFail2],		c1;
	
exponentTooLarge:
	GOTO[floatPrimitiveFail3],		c2;			
{=== end: primitive 54 - TimesTwoPower ===}