{File name LFAM.mc
Description:  DandeLion InterLisp Emulator LispFloatArray
Author: Charnley
Last modified: Charnley              28-Jun-84 11:37:59
Created:   8-Jun-84 10:04:55
}

{	(MAGIC S2 S1 D Kount)   op = 373'b  alpha = 4

	S1  --  pointer to first source complex number
	S2  --  pointert to last source complex number
	D   --  pointer to first dest complex number

	within the loop
	S1  =  S1init + 4*(Kount - 1)  {alpha, gamma}
	S2  =  S2init - 4*(Kount - 1)    {beta, delta}
	D   =   Dinit + 8*(Kount - 1)  {D.0, D.1, D.2, D.3}

		D(n.0)  ←  S1(n.0) + S2(-n.0)  {alpha + beta}
		D(n.1)  ←  S1(n.1) - S2(-n.1)    {delta - gamma}
		D(n.2)  ←  S1(n.1) + S2(-n.1)  {delta + gamma}
		D(n.3)  ←  S1(n.0) - S2(-n.0)    {alpha - beta}

	S1, S2, and D are quadword alligned
}

{	INNER LOOP FLOAT SEQUENCE 

	 B ← alpha
	 A ← beta [add] [unload]
	XXXXX  D.2 ← RESULT (delta+gamma)
	 A ← beta [sub] [unload]
	XXXXX  D.1 ← RESULT (delta-gamma)
	 B ← delta [unload]
	--------------------------------        LOOP START
	D.0 ← RESULT (alpha+beta)
	 A ← gamma [add] [unload]
	D.3 ← RESULT (alpha-beta)
	 A ← gamma [sub]
	 B ← alpha
	 A ← beta [add] [unload]
	D.2 ← RESULT (delta+gamma)
	 A ← beta [sub] [unload]
	D.1 ← RESULT (delta-gamma)
	 B ← delta [unload]
	--------------------------------       LOOP END
	D.0 ← RESULT (alpha+beta)
	 A ← gamma [add] [unload]
	D.3 ← RESULT (alpha-beta)
	--------------------------------
	 A ← gamma [sub]
	XXXXX  B ← alpha
	XXXXX  A ← beta [add] [unload]
	D.2 ← RESULT (delta+gamma)
	XXXXX  A ← beta [sub] [unload]
	D.1 ← RESULT (delta-gamma)
}

RegDef[uFLAmB, U, 35];

	GOTO[FLOATARRAYPREP],	c3, at[L2.magic, 10, FOP2Disp];{MAGIC}

lfam.s:
{	loop pipe start up }
	at[L2.magic, 10, LFAop],{FOP2 = MAGIC}
	Zimph ← LShift1 Kount - 1, SE ← 0,	c1;
	L0 ← L0.S1mag0, FloatMode.RN.AI.FAST, FloatPIPE,	c2;
	Zimph ← LShift1 Zimph,  SE ← 0,CALL[LFAremapS1],	c3;

{	MAR ← S1 ← [S1 + 4*Kount-1],	c1; }
	stackP ← 6{FLBMinusA},	c2, at[L0.S1mag0, 10, LFAremapS1ret];
	FloatAB ← MD{alpha},	c3;

	MAR ← [rhS1, S1 + 1],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB ← MD{alpha},	c3;

	Zimph ← LShift1 Kount - 1, SE ← 0,	c1;
	L0 ← L0.S2mag0,	c2;
	Zimph ← LShift1 Zimph, CALL[LFAremapNS2],	c3;

{	MAR ← S2 ← [S2 - 4*Kount-1],	}
	,	c2, at[L0.S2mag0, 10, LFAremapS2ret];
	Stemp ← FloatA ← MD{beta}, FLPlus,	c3;

	MAR ← [rhS2, S2 + 1],	c1;
	USrcVALo ← Stemp, CANCELBR[$, 2],	c2;
	Stemp ← FloatA ← MD{beta},	c3;

	FloatPump, uStemp ← Stemp,	c1;
	FloatPump,	c2;
	FloatA ← USrcVALo{beta}, {FLBMinusA,}	c3;

	FloatA ← uStemp{beta},	c1;
	FloatPump,	c2;
	FloatPump,	c3;

	MAR ← S2 ← [rhS2, S2 + 2],	c1;
	CANCELBR[$, 2],	c2;
	FloatAB ← MD{delta}, FloatUnloadS, Float.M,	c3;

	MAR ← [rhS1, S2 + 1], L0 ← L0.lfam.di,	c1;
	, CANCELBR[$, 2],	c2;
	FloatAB ← MD{delta}, FloatUnloadS, Float.L,	c3;

	Zimph ← LShift1 Kount - 1, SE ← 0,	c1;
	Zimph ← LShift1 Zimph, SE ← 0,	c2;
	Zimph ← LShift1 Zimph, SE ← 0,CALL[LFAremapD]	c3;

{	MAR ← D ← [D + 8*Kount-1],	c1; }
	Q ← MDR ← FloatResult{alpha+beta}, GOTO[lfam.entry], FloatPump,	c2, at[L0.lfam.di, 10, LFAremapDret];

{	-	-	-	-	-	-	-}

lfam.loop:	MAR ← D ← [rhD, D - 10'd],	c1;{D.0}
	Q ← MDR ← FloatResult{alpha+beta}, BRANCH[$, fixDA, 1], FloatPump,	c2;
fixDAret:
lfam.entry:
	pop,	c3;{S: 6 to 5}

	MAR ← [rhD, D + 1], L0 ← L0.lfam.s2a,	c1;
	Q ← MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	pop,	c3;{S: 5 to 4}

	MAR ← S1 ← [rhS1, S1 + 2],	c1;
	CANCELBR[$, 2],	c2;
	Stemp ← FloatA ← MD{gamma}, FLPlus, FloatUnloadS, Float.M, push,	c3;{S: 4 to 5}

	MAR ← [rhS1, S1 + 1], push,	c1;{S: 5 to 6}
	USrcVALo{6} ← Stemp, CANCELBR[$, 2],	c2;
	Stemp ← FloatA ← MD{gamma}, FloatUnloadS, Float.L,	c3;

	MAR ← D ← [rhD, D + 6],	c1;{D.3}
	Q ← MDR ← FloatResult{alpha-beta}, LOOPHOLE[wok], BRANCH[$, fixDB, 1], FloatPump,	c2;
fixDBret:
	, uSaveTT ← Stemp,	c3;

	,	c1;
	,	c2;
	Kount ← Kount - 1, ZeroBr,	c3;

	MAR ← [rhD, D + 1], BRANCH[$, lfam.exit]	c1;
	Q ← MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	FloatA ← USrcVALo{gamma}, {FLBMinusA,}	c3;

	MAR ← S1 ← [rhS1, S1 - 6], pop,	c1;{S: 6 to 5}
	FloatA ← uSaveTT{gamma}, BRANCH[$, fixS1A, 1],	c2;
fixS1Aret:
	Stemp{Db} ← FloatAB ← MD{alpha},	c3;

	MAR ← [rhS1, S1 + 1], pop,	c1;{S: 5 to 4}
	, CANCELBR[$, 2],	c2;
	Stemp{Db} ← FloatAB ← MD{alpha},	c3;

	MAR ← S2 ← [rhS2, S2 + 2],	c1;
	BRANCH[$, fixS2A, 1],	c2, at[L0.lfam.s2a, 10, LFAremapS2ret];
fixS2Aret:
	Stemp ← FloatA ← MD{beta}, FLPlus, FloatUnloadS, Float.M, push,	c3;{S: 4 to 5}

	MAR ← [rhS2, S2 + 1], push,	c1;{S: 5 to 6}
	STK{6} ← Stemp, CANCELBR[$, 2],	c2;
	Stemp ← FloatA ← MD{beta}, FloatUnloadS, Float.L,	c3;

	MAR ← D ← [rhD, D - 2],	c1;{D.2}
	Q ← MDR ← FloatResult{delta+gamma}, LOOPHOLE[wok], CANCELBR[$, 2], FloatPump,	c2;
	,	c3;

	MAR ← [rhD, D + 1],	c1;
	Q ← MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	uSaveTT ← Stemp,	c3;

	FloatA ← STK{beta}, {FLAMinusB,} FloatUnloadS, Float.M,	c1;
	FloatA ← Stemp LRot0{beta}, FloatUnloadS, Float.L,	c2;
	,	c3;

	MAR ← D ← [rhD, D - 2],	c1;{D.1}
	Q ← MDR ← FloatResult{delta-gamma}, LOOPHOLE[wok], BRANCH[$, fixDD, 1], FloatPump,	c2;
fixDDret:
	,	c3;

	MAR ← [rhD, D + 1],	c1;
	Q{Db} ← MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	,	c3;

	MAR ← S2 ← [rhS2, S2 + 2],	c1;
	CANCELBR[$, 2],	c2;
	Q{Db} ← FloatAB ← MD{delta}, FloatUnloadS, Float.M,	c3;

	MAR ← [rhS2, S2 + 1],	c1;
	, CANCELBR[$, 2],	c2;
	Q{Db} ← FloatAB ← MD{delta}, GOTO[lfam.loop], FloatUnloadS, Float.L,	c3;

{	-	-	-	-	-	-	-}

lfam.exit:
	MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	FloatA ← USrcVALo{gamma}, {FLAMinusB,}	c3;

	FloatA ← uSaveTT{gamma},	c1;
	FloatPump,	c2;
	FloatPump,	c3;

	,	c1;
	FloatPump, FloatUnloadS, Float.M,	c2;
	FloatPump, FloatUnloadS, Float.L,	c3;

	MAR ← D ← [rhD, D - 2],	c1;
	Q ← MDR ← FloatResult{delta+gamma}, LOOPHOLE[wok], CANCELBR[$, 2], FloatPump,	c2;
fixDEret:
	,	c3;

	MAR ← [rhD, D + 1],	c1;
	Q ← MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	,	c3;

	FloatPump, FloatUnloadS, Float.M,	c1;
	FloatPump, FloatUnloadS, Float.L,	c2;
	,	c3;

	MAR ← D ← [rhD, D - 2],	c1;
	Q ← MDR ← FloatResult{delta-gamma}, LOOPHOLE[wok], BRANCH[$, fixDF, 1], FloatPump,	c2;
fixDFret:
	,	c3;

	MAR ← [rhD, D + 1],	c1;
	MDR ← FloatResult, CANCELBR[$, 2], LOOPHOLE[wok], FloatPump,	c2;
	Q ← 6, L1 ← L1.LFAexit,	c3;

	GOTO[LFACommonExit],	c1;

{	exceptions }

fixDA:	{8*K + 0}
	Zimph ← LShift1 Kount - 1, SE ← 0,	c3;

	Zimph ← LShift1 Zimph, SE ← 0,	c1;
	UQSave ← Q, L0 ← L0.lfam.da,	c2;
	Zimph ← LShift1 Zimph, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← UQSave, GOTO[fixDAret],	c2, at[L0.lfam.da, 10, LFAremapDret];

fixDB:	{8*K + 6}
	Zimph ← LShift1 Kount, SE ← 0,	c3;

	Zimph ← LShift1 Zimph, SE ← 0,	c1;
	UQSave ← Q, L0 ← L0.lfam.db,	c2;
	Zimph ← LShift1 Zimph - 1, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← UQSave, GOTO[fixDBret],	c2, at[L0.lfam.db, 10, LFAremapDret];


fixDD:	{8*K + 2} {Kount has been decremented!}
	Zimph ← LShift1 Kount, SE ← 0,	c3;

	Zimph ← LShift1 Zimph, SE ← 1,	c1;
	UQSave ← Q, L0 ← L0.lfam.dd,	c2;
	Zimph ← LShift1 Zimph, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← UQSave, GOTO[fixDDret],	c2, at[L0.lfam.dd, 10, LFAremapDret];

fixDF:	{8*K + 2} {Kount has been decremented!}
	Zimph ← LShift1 Kount, SE ← 0,	c3;
	Zimph ← LShift1 Zimph, SE ← 1,	c1;
	UQSave ← Q, L0 ← L0.lfam.df,	c2;
	Zimph ← LShift1 Zimph, SE ← 0, CALL[LFAremapD],	c3;

	MDR ← UQSave, GOTO[fixDFret],	c2, at[L0.lfam.df, 10, LFAremapDret];

fixS1A:	{4*K + 0} {Kount has been decremented!}
	Zimph ← LShift1 Kount, SE ← 0,	c3;
	Zimph ← LShift1 Zimph, SE ← 0,	c1;
	L0 ← L0.lfam.s1a,	c2;
	CALL[LFAremapS1],	c3;

	GOTO[fixS1Aret],	c2, at[L0.lfam.s1a, 10, LFAremapS1ret];

fixS2A:	{4*K + 0}
	Zimph ← LShift1 Kount - 1, SE ← 0,	c3;
	Zimph ← LShift1 Zimph, SE ← 0,	c1;
	L0 ← L0.lfam.s2a,	c2;
	CALL[LFAremapNS2],	c3;

LFAremapNS2:
	Zorch ← uS2Lo,	c1;
	Zorch ← Zorch - Zimph, CarryBr,	c2;
	rhZorch ← uS2Hi, BRANCH[LFANS2car, LFANS2nocar],	c3;

LFANS2car:
	Q ← rhZorch,	c1;
	Q ← Q - 1,	c2;
	rhZorch ← Q LRot0,	c3;

LFANS2nocar:
	{map S2}
	Map ← [rhZorch, Zorch], GOTO[lfa.S2map],	c1;

	{ E N D }