{
File name : Newpolynomial.mc
Author : Gwan Santosa & Don Charnley
Created : 27-Dec-84 13:16:16
==========================================================================
MICROCODE FOR LISP POLYNOMIAL EVALUATION
==========================================================================
}
{Set[ib.poly, 0];}
{RegDef[uAinitH, U, 57]; {A(0) H}
RegDef[uAinitL, U, 58]; {A(0) L}
RegDef[uXHi, U, 30]; {X H}
RegDef[uXLo, U, 05]; {X L}
RegDef[uDegree, U, 42]; {The degree of polynomial}
RegDef[uTTtmp, U, 43]; {Virtual address, tmp}
RegDef[uAnxtH, U, 44]; {New A, H word, tmp}
}
{Set[L0.RedoPOLY0, 3]; {Return value for RLMapFixB2}
Set[L0.RedoPOLY1, 4]; {Return value for RLMapFixB2}
}
{Set[PolyBank, 2];
}
{Set[POLYcode, 12A];
Set[L1.NoFixesB2, 2];
RegDef[TT, R, 2];
RegDef[rhTT, RH, 2];
RegDef[S, R, 4];
RegDef[rhS, RH, 4];
RegDef[Rx, R, 6];
RegDef[rhRx, RH, 6];
RegDef[TOS, R, 0];
RegDef[rhTOS, RH, 0];
RegDef[TOSH, R, 1];
RegDef[rhTOSH, RH, 1];
RegDef[PC, R, 5];
RegDef[uPPsave, U, 4C];
Set[smallpl, 16'b];
MacroDef[CROSS, GOTOABS[#1]];
}
{
@POLY:
Bank ← PolyBank, c1;
, c2; {assume a two byte opcode}
CROSS[POLYcode], c3;
}
uTOS ← TOS, c1, at[POLYcode];
Ybus ← ibNA, YDisp, c2;
uTOSH ← TOSH, DISP4[misc3disp], c3;
PolyB2: MAR ← [rhS, S - 1], c1, at[ib.poly, 10, misc3disp];
Q ← TOSH xor smallpl, ZeroBr, CANCELBR[$,2], c2; {degree of polynomial}
rhTT ← MD, BRANCH[PolyufnX1, $], c3; {H Address of memory block}
MAR ← [rhS, S + 0], c1; {for coefficients of polynomial}
S ← S - 2, c2;
TT ← MD, c3; {L address of coefficient}
MAR ← [rhS, S - 1], c1; {pointer to X}
Xbus ← ib, CANCELBR[$,2], c2;
Q ← MD, c3; {Load X H word}
{ uXHi ← Q, c1;
Noop, c2; {Set up the degree of polynomial}
uDegree ← TOS, c3;
MAR ← [rhS, S + 0], c1; {pointer to X}
S ← S + 2, c2;
Q ← MD, c3; {Load X L word}
uXLo ← Q, c1;
L1 ← L1.NoFixesB2, c2;
L0 ← L0.RedoPOLY0, c3;}
MAR ← [rhS, S + 0], c1; {pointer to X}
uXHi ← Q, c2;
Q ← MD, c3; {Load X L word}
uXLo ← Q, c1;
S ← S + 2, L1 ← L1.NoFixesB2, c2;
uDegree ← TOS, L0 ← L0.RedoPOLY0, c3; {Set up the degree of polynomial}
Map ← [rhTT, TT], c1; {point to virtual memory}
uTTtmp ← TT, c2; {Save these regs for remap !}
rhRx ← Rx ← MD, XRefBr, c3; {Check ref. bit}
MAR ← Q ← [rhRx, TT + 0], BRANCH[POLYmapcheck, $], c1, at[L0.RedoPOLY0, 10,RMapFixCallerB2];
Rx ← Q, c2;
Q ← MD, c3; {A(0) H word}
MAR ← Rx ← [rhRx, Rx + 1], c1;
uAinitH ← Q, CANCELBR[$, 2], c2;
Q ← MD, c3; {A(0) L word}
TT ← 0FF + 1, c1; {set PPort to read}
uAinitL ← Q, c2;
Noop, c3;
Noop, c1;
Q ← uPPsave, c2;
PPort ← Q ← Q and ~TT, c3;
{ INNER LOOP OF POLY OPCODE
init: FPChip ← a(0)
FPChip ← X mpy
loop: FPChip ← a(next)
FPChip ← FPResult add
if no more a, then GOTO end
FPChip ← X
FPChip ← FPResult mpy
GOTO loop
end: Answer ← FPResult}
{
This section handles the arithmatic operation,
utilizing the floating point chips.
}
POLYinit:
FloatNop, c1;
FloatNop, c2;
FloatMode.RN.AI.IEEE, FloatPIPE, c3;
Q ← FloatAB ← uAinitH, c1; {Load A(0)}
FloatAB ← uAinitL, c2; {Load A(0)}
TT ← FloatA ← uXHi, FLTimes.A.B, c3; {Multiply by X}
Noop, c1;
Noop, c2;
FloatA ← uXLo, GOTO[POLYpump], c3;
POLYloop:
uAnxtH ← Q, c2;
Noop, c3;
MAR ← Rx ← [rhRx, Rx + 1], c1; {next coeff., L word}
FloatAB ← uAnxtH, FloatUnloadP, Float.M, CANCELBR[$,2], c2; {Load A(next)hi}
FloatAB ← MD, FloatUnloadP, Float.L, c3; {Load A(next)lo}
Q ← FloatA ← FloatResult, FLPlus, c1; {Load multiplication result}
Xbus ← PPort, XDisp, c2; {Get status}
TT ← FloatA ← FloatResult, DISP4[TEST0,3], c3; {Add with new constant}
{Check result}
TP11:
FloatPump, c1, at[0F,10,TEST0];
FloatPump, c2; {If correct, continue}
FloatPump, c3; {count down}
Q ← uDegree, c1;
FloatPump, c2;
Q ← Q - 1, ZeroBr, c3;
uDegree ← Q, BRANCH[POLYgoon,POLYend], c1;
POLYgoon:
FloatAB ← uXHi, c2; {Load X, H word}
FloatAB ← uXLo, c3; {Load X, L word}
Noop, c1;
FloatUnloadS, Float.M, c2;
FloatUnloadS, Float.L, c3;
Q ← FloatA ← FloatResult, FLTimes.A.B, c1; {Load new result, multiply by X}
Xbus ← PPort, XDisp, c2; {Get status}
TT ← FloatA ← FloatResult, DISP4[TEST1,3], c3; {Check status}
POLYpump:
FloatPump, c1, at[0F,10,TEST1];
FloatPump, c2; {If correct, continue}
FloatPump, c3;
TP22: MAR ← Rx ← [rhRx, Rx + 1], c1; {point to next coefficient, H word}
FloatPump, BRANCH[$, POLYnwpg,1], c2; {check for page boundary}
POLYpgbn:
Q ← MD, FloatPump, c3; {Load A H word}
FloatPump, GOTO[POLYloop], c1;
GOTO[ufnX22], c1, at[03, 10, TEST0]; {FPT result not OK}
GOTO[ufnX22], c1, at[07, 10, TEST0]; {FPT result not OK}
GOTO[ufnX22], c1, at[0B, 10, TEST0]; {FPT result not OK}
GOTO[ufnX22], c1, at[03, 10, TEST1]; {FPT result not OK}
GOTO[ufnX22], c1, at[07, 10, TEST1]; {FPT result not OK}
GOTO[ufnX22], c1, at[0B, 10, TEST1]; {FPT result not OK}
POLYnwpg:
TT ← uTTtmp, c3; {Retrieve TT}
Q ← 0FF + 1, c1; {Load Q with 100}
TT ← TT + Q, CarryBr, c2; {Add TT with 100}
Q ← rhTT, BRANCH[POLYnoadd, POLYadd], c3; {Check for carry}
POLYadd:
Q ← Q + 1, c1; {If there is, propagate to rhTT}
rhTT ← Q LRot0, c2;
L0 ← L0.RedoPOLY1, c3;
POLYnoadd:
Map ← [rhTT, TT], c1; {No carry}
L1 ← L1.NoFixesB2, uTTtmp ← TT, c2; {Save TT again}
rhRx ← Rx ← MD, XRefBr, c3;
MAR ← Q ← [rhRx, 0+0], BRANCH[POLYmapcheck1, $], c1, at[L0.RedoPOLY1,10,RMapFixCallerB2];
Rx ← Q, GOTO[POLYpgbn], c2; {Go back}
POLYmapcheck:
CALL[RLMapFixB2], c2;
POLYmapcheck1:
CALL[RLMapFixB2], c2;
PolyufnX1:
GOTO[ufnX22], c1;
POLYend:
FloatPump, c2;
FloatPump, c3;
Noop, c1;
FloatUnloadS, Float.M, c2;
FloatUnloadS, Float.L, c3;
TOSH ← FloatResult, c1; {Result H word}
Xbus ← PPort, XDisp, c2; {Read the status}
TOS ← FloatResult, DISP4[TEST2,3], c3; {Result L word}
S ← S - 4, c1, at[0F,10,TEST2];
Noop, c2;
GOTO[c1.pc2B2], c3;
GOTO[ufnX22], c1, at[03, 10, TEST2]; {FPT result not OK}
GOTO[ufnX22], c1, at[07, 10, TEST2]; {FPT result not OK}
GOTO[ufnX22], c1, at[0B, 10, TEST2]; {FPT result not OK}