{ File name : polynomial.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} Ybus ← Q, ZeroBr, 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[ufnX2], c1, at[03, 10, TEST0]; {FPT result not OK} GOTO[ufnX2], c1, at[07, 10, TEST0]; {FPT result not OK} GOTO[ufnX2], c1, at[0B, 10, TEST0]; {FPT result not OK} GOTO[ufnX2], c1, at[03, 10, TEST1]; {FPT result not OK} GOTO[ufnX2], c1, at[07, 10, TEST1]; {FPT result not OK} GOTO[ufnX2], 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[ufnX2], 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[ufnX2], c1, at[03, 10, TEST2]; {FPT result not OK} GOTO[ufnX2], c1, at[07, 10, TEST2]; {FPT result not OK} GOTO[ufnX2], c1, at[0B, 10, TEST2]; {FPT result not OK}