{LispMatrix.mc by cal 13-Dec-84 10:31:52 (MATRIXMPY M N K A.MATRIX B.MATRIX C.MATRIX) performs C.MATRIX ← A.MATRIX * B.MATRIX where A.MATRIX is a matrix of M rows by N columns and B.MATRIX is a matrix of N rows by K columns and C.MATRIX is a matrix of M rows by K columns the contents of A.MATRIX is A[m=0, n=0] the contents of A.MATRIX + 1 is A[m=0, n=1] . . the contents of A.MATRIX + N - 1 is A[m=0, n=N - 1] the contents of A.MATRIX + N is A[m=1, n=0] etc. has the following builtin 'sizes' alpha size 1 A[3,3] B[3,3] C[3,3] M = 3, N = 3, K = 3 2 A[4,4] B[4,4] C[4,4] M = 4, N = 4, K = 4 3 A[1,3] B[3,3] C[1,3] M = 1, N = 3, K = 3 4 A[3,3] B[3,1] C[3,1] M = 3, N = 3, K = 1 5 A[1,4] B[4,4] C[1,4] M = 1, N = 4, K = 4 6 A[4,4] B[4,1] C[4,1] M = 4, N = 4, K = 1 -- basically FOR m = 0 to M - 1 FOR k = 0 to K - 1 sum ← 0 FOR n = 0 to N - 1 sum ← sum + A[m, n] * B[n, k] NEXT n C[m, k] ← sum NEXT k NEXT m timing: { 25 + 1 * N + 10 * N↑2 + 8 * N↑3} 3 x 3 x 3 == 334 clicks ~~ 6000 per second 4 x 4 x 4 == 701 clicks ~~ 2850 per second } { defs moved to MoreLispDefs.dfn RegDef[rA, R, 6],{Rx} RegDef[rB, R, 0],{TOS} RegDef[rC, R, 1],{TOSH} RegDef[rhrA, RH, 6],{Rx} RegDef[rhrB, RH, 0],{TOS} RegDef[rhrC, RH, 1],{TOSH} RegDef[urAVlo, U, 02], {Low VA of matrix A} RegDef[urAVhi, U, 03], {High VA of matrix A} RegDef[urBVlo, U, 60], {Low VA of matrix B} RegDef[urBVhi, U, 05], {High VA of matrix B} RegDef[urCVlo, U, 06], {Low VA of matrix C} RegDef[urCVhi, U, 07], {High VA of matrix C} RegDef[uNinit, U, 08], {Initial value of nCOUNT} RegDef[uKinit, U, 0A], {Initial value of kCOUNT} RegDef[umCOUNT, U, 0B], {Current value of mCOUNT} RegDef[ukCOUNT, U, 0C], {Current value of kCOUNT} RegDef[unCOUNT, U, 36], {Current value of nCOUNT, when saved} RegDef[udeltaA1, U, 31], {-2(N-1)} RegDef[udeltaB0, U, 33], {+2K} RegDef[udeltaB1, U, 35], {-2(N-1)(K)+2} RegDef[udeltaB2, U, 37], {-2(N)(K)+2} {RegDef[uTOSH, U, 1D],} {RegDef[uTOS, U, 0D],} Set[L0.delta0, 0], Set[L0.delta1, 1], Set[L0.delta2, 2], Set[L0.deltaI, 3], Set[L1.mxnotfirst, 1], Set[L1.mxfirst, 2], {Set[L1.matufn, 7],} Set[ib.333, 1], Set[ib.444, 2], Set[ib.133, 3], Set[ib.331, 4], Set[ib.144, 5], Set[ib.441, 6]; Set[L1.lm, 9]; Set[L1.matexit, 0A]; } {@MATRIXMPY: Bank ← PolyBank, c1; , c2; CROSS[POLYcode], c3; uTOS ← TOS, c1, at[POLYcode]; Ybus ← Q, YDisp, c2; uTOSH ← TOSH, DISP4[misc3disp], c3; end in bank 1 & 2} at[ib.333, 10, misc3disp]: MAR ← [rhS, S - 1], GOTO[mxmgo], c1; {For 3X3X3} at[ib.444, 10, misc3disp]: MAR ← [rhS, S - 1], GOTO[mxmgo], c1; {For 4X4X4} at[ib.133, 10, misc3disp]: MAR ← [rhS, S - 1], GOTO[mxmgo], c1; {For 3X1X3} at[ib.331, 10, misc3disp]: MAR ← [rhS, S - 1], GOTO[mxmgo], c1; {For 3X3X1} at[ib.144, 10, misc3disp]: MAR ← [rhS, S - 1], GOTO[mxmgo], c1; {For 4X1X4} at[ib.441, 10, misc3disp]: MAR ← [rhS, S - 1], GOTO[mxmgo], c1; {For 4X4X1} mxmgo: FloatNop, CANCELBR[$, 2], c2; TT{Bhi} ← MD, c3; {Bhi is high VA of matrix B} urCVlo ← TOS, L1 ← L1.lm, c1; {Save Clo in urCVlo} CALL[LFASaveRegsHere], c2; S ← S + 4, c1, at[L1.lm, 10, LFASaveRegsRet]; urCVhi ← TOSH, c2; {Save Chi in urCVhi} urBVhi ← TT, c3; {Save Bhi in urBVhi} MAR ← [rhS, S + 0], c1; {Point to BLo} S ← S - 2, c2; Rx{Blo} ← MD, c3; {Blo is low VA of matrix B} MAR ← [rhS, S - 1], c1; {Point to Ahi} urBVlo ← Rx, CANCELBR[$, 2], c2; {Save Blo in urBVlo} TT{Ahi} ← MD, c3; {Ahi is high VA of matrix A} MAR ← [rhS, S + 0], c1; {Point to Alo} urAVhi ← TT, c2; {Save Ahi in urAVhi} TT{Alo} ← MD, c3; {Alo is low VA of matrix A} S ← S + 2, L1 ← L1.mxfirst, c1; urAVlo ← TT, c2; {Save Alo in urAVlo} TT ← 0FF + 1, c3; {set PPort to read} Q ← uPPsave, c1; PPort ← Q and ~TT, c2; Xbus ← ibNA, XDisp, c3; DISP4[mxwhich, 0], c1; {=================================================================== setup for 3 x 3 x 3 =================================================================== } at[ib.333, 10, mxwhich], Q ← 3, c2; uNinit ← Q, c3; {uNinit=3} , c1; uKinit ← Q, c2; {uKini=3} umCOUNT ← Q, c3; {umCount=3} ukCOUNT ← Q, c1; {ukCount=3} unCOUNT ← Q, c2; {unCount=3} Q ← 4, c3; {2(N-1)} udeltaA1 ← Q, c1; {udeltaA1=4} Q ← 6, c2; {2K} udeltaB0 ← Q, c3; {udeltaB0=6} Q ← 10'd, c1; {2(N-1)(K)-2} udeltaB1 ← Q, c2; {udeltaB1=10} Q ← 16'd, c3; {2(N)(K)-2} udeltaB2 ← Q, GOTO[mxmaps], c1; {udeltaB2=16} {=================================================================== setup for 4 x 4 x 4 =================================================================== } at[ib.444, 10, mxwhich], Q ← 4, c2; uNinit ← Q, c3; {uNinit=4} , c1; uKinit ← Q, c2; {uKinit=4} umCOUNT ← Q, c3; {umCOUNT=4} ukCOUNT ← Q, c1; {ukCOUNT=4} unCOUNT ← Q, c2; {unCOUNT=4} Q ← 6, c3; {2(N-1)} udeltaA1 ← Q, c1; {udeltaA1=6} Q ← 8, c2; {2K} udeltaB0 ← Q, c3; {udeltaB0=8} Q ← 22'd, c1; {2(N-1)(K)-2} udeltaB1 ← Q, c2; {udeltaB1=22} Q ← 30'd, c3; {2(N)(K)-2} udeltaB2 ← Q, GOTO[mxmaps], c1; {udeltaB2=30} {=================================================================== setup for 3x1x3 =================================================================== } at[ib.133, 10, mxwhich], Q ← 3, c2; uNinit ← Q, c3; uKinit ← Q, c1; unCOUNT ← Q, c2; ukCOUNT ← Q, c3; Q ← 1, c1; umCOUNT ← Q, c2; Q ← 4, c3; udeltaA1 ← Q, c1; {udeltaA1 ← 2(N-1)} Q ← 6, c2; udeltaB0 ← Q, c3; {udeltaB0 ← 2K} Q ← 10'd, c1; udeltaB1 ← Q, c2; {udeltaB1 ← 2(N-1)(K)-2} Q ← 16'd, c3; udeltaB2 ← Q, GOTO[mxmaps], c1; {udeltaB2 ← 2(N)(K)-2} {=================================================================== setup for 3x3x1 =================================================================== } at[ib.331, 10, mxwhich], Q ← 3, c2; uNinit ← Q, c3; , c1; umCOUNT ← Q, c2; unCOUNT ← Q, c3; Q ← 1, c1; ukCOUNT ← Q, c2; uKinit ← Q, c3; Q ← 4, c1; udeltaB2 ← Q, c2; {udeltaB2 ← 2(N)(K)-2} udeltaA1 ← Q, c3; {udeltaA1 ← 2(N-1)} Q ← 2, c1; udeltaB0 ← Q, c2; {udeltaB0 ← 2K} Q ← 2'd, c3; udeltaB1 ← Q, GOTO[mxmaps], c1; {udeltaB1 ← 2(N-1)(K)-2} {=================================================================== setup for 4x1x4 =================================================================== } at[ib.144, 10, mxwhich], Q ← 4, c2; uNinit ← Q, c3; uKinit ← Q, c1; unCOUNT ← Q, c2; ukCOUNT ← Q, c3; Q ← 1, c1; umCOUNT ← Q, c2; Q ← 6{2(N-1)}, c3; udeltaA1 ← Q, c1; {udeltaA1 ← 2(N-1)} Q ← 8{2K}, c2; udeltaB0 ← Q, c3; {udeltaB0 ← 2K} Q ← 22'd{2(N-1)(K)}, c1; udeltaB1 ← Q, c2; {udeltaB1 ← 2(N-1)(K)-2} Q ← 30'd{2(N)(K)-2}, c3; udeltaB2 ← Q, GOTO[mxmaps], c1; {udeltaB2 ← 2(N)(K)-2} {=================================================================== setup for 4x4x1 =================================================================== } at[ib.441, 10, mxwhich], Q ← 4, c2; uNinit ← Q, c3; {uMinit ← Q}, c1; unCOUNT ← Q, c2; umCOUNT ← Q, c3; Q ← 1, c1; ukCOUNT ← Q, c2; uKinit ← Q, c3; Q ← 6, c1; udeltaA1 ← Q, c2; {udeltaA1 ← 2(M-1)} udeltaB2 ← Q, c3; {udeltaB2 ← 2(N)(K)-2} Q ← 2, c1; udeltaB0 ← Q, c2; {udeltaB0 ← 2K} Q ← 4'd, c3; udeltaB1 ← Q, GOTO[mxmaps], c1; {udeltaB1 ← 2(N-1)(K)-2} {=====================================================================} {=====================================================================} mxmaps: rA ← urAVlo, L0 ← L0.deltaI, c2; {Store low VA of A into rA} TT ← urAVlo, GOTO[fixrAI], c3; {Move it into TT, goto fixrAI} at[L0.deltaI, 4, rAfixed], rB ← urBVlo, c2; {Store low VA of B into rB} TT ← urBVlo, GOTO[fixrBI], c3; {Move it into TT, goto fixrBI} at[L0.deltaI, 4, rBfixed], rC ← urCVlo, c2; {Store low VA of C into rC} TT ← urCVlo, GOTO[fixrCI], c3; {Move it into TT, goto fixrCI} at[L0.deltaI, 4, rCfixed], FloatNop, c2; FloatMode.RN.AI.IEEE, FloatPIPE, c3; mxinit: ufloatplus ← 0, L0 ← L0.delta0, c1; {Initialize to 0} FloatAB ← ufloatplus, FLPlus, c2; {Load AB of FPT chip with 0} FloatAB ← ufloatplus, c3; {Perform addition} MAR ← [rhrA, rA + 0], c1; {Point to first element of A} Q{nCOUNT} ← uNinit, c2; {Initialize column count} FloatAB{Ahi} ← MD, c3; {Load A H into AB of FPT chip} MAR ← [rhrA, rA + 1], c1; {Point to A L} TT ← udeltaB0, CANCELBR[$, 2], c2; FloatAB{Alo} ← MD, c3; {Load A L into AB of FPT chip} MAR ← rB ← [rhrB, rB + 0], c1; {Point to first element of B} , c2; FloatA{Bhi} ← MD, FLTimes.A.B, GOTO[mxstart], c3; {Load B H into A of FPT chip} mxloop: MAR ← rA ← [rhrA, rA + 2], DISP4[mxcheck2, 3], c1; {Point to next column of A} FloatA{prodlo} ← FloatResult, BRANCH[$, fixrA0, 1], c2, at[0F, 10, mxcheck2]; {Load Prod L} mxrAret: FloatAB ← MD, c3; {Load A H into AB} MAR ← [rhrA, rA + 1], c1; {Point to A L} CANCELBR[$, 2], c2; FloatAB ← MD, c3; {Load A L into AB of FPT chip} MAR ← rB ← [rhrB, rB + TT{2K}], c1; {Point to element of matrix B} BRANCH[$, fixrB0, 1], c2; {Check for page carry} mxrBret: FloatA{Bhi} ← MD, FLTimes.A.B, c3; {Load B H into A of FPT chip} mxstart: MAR ← [rhrB, rB + 1], c1; {Point to B L} CANCELBR[$, 2], c2; FloatA{Blo} ← MD, c3; {Load B L into A of FPT chip} {Perform multiplication} FloatPump, c1; FloatPump, c2; FloatPump, FloatUnloadS, Float.M, c3; FloatPump, FloatUnloadS, Float.L, c1; FloatAB{sumhi} ← FloatResult, c2; {Load Sum H into AB of FPT chip} Xbus ← PPort, XDisp, c3; {Get status, and test} FloatAB{sumlo} ← FloatResult, DISP4[mxcheck1, 3], c1; {Load Sum L into AB of FPT chip} FloatPump, FloatUnloadP, Float.M, c2, at[0F, 10, mxcheck1]; {If OK} FloatPump, FloatUnloadP, Float.L, c3; FloatA{prodhi} ← FloatResult, FLPlus, c1; {Load Prod H into A of FPT chip} Q{nCOUNT} ← Q{nCOUNT} - 1, ZeroBr, c2; {Decrement count} Xbus ← PPort, XDisp, BRANCH[mxloop, mxterm], c3; {Get status, and test} mxterm: FloatA{prodlo} ← FloatResult, DISP4[mxcheck3, 3], c1; FloatPump, c2, at[0F, 10, mxcheck3]; FloatPump, c3; FloatPump, c1; FloatPump, c2; FloatPump, c3; FloatPump, c1; FloatPump, FloatUnloadS, Float.M, c2; FloatPump, FloatUnloadS, Float.L, c3; Q ← FloatResult, c1; L1Disp, c2; DISP4[mx?first], c3; MAR ← rC ← [rhrC, rC + 0], L1 ← L1.mxnotfirst, c1, at[L1.mxfirst, 10, mx?first]; MDR{sumhi} ← Q, LOOPHOLE[wok], GOTO[mxrCcont], c2; {Store result H} MAR ← rC ← [rhrC, rC + 2], c1, at[L1.mxnotfirst, 10, mx?first]; MDR{sumhi} ← Q, LOOPHOLE[wok], BRANCH[$, fixrC, 1], c2; {Store result H} mxrCcont: Xbus ← PPort, XDisp, c3; {Get status, and test} MAR ← [rhrC, rC + 1], DISP4[mxcheck4, 3], c1; {Point to C L} MDR{sumlo} ← FloatResult, LOOPHOLE[wok], CANCELBR[$, 2], c2, at[0F, 10, mxcheck4]; {Store result L} Q ← ukCOUNT, c3; Q ← Q - 1, ZeroBr, c1; {Decrement K count} ukCOUNT ← Q, BRANCH[mxmoreK, mxKdone], c2; {and test} mxmoreK: { set nCOUNT to N {done in mxinit} set rA to A[m, 0] {was A[m, N-1] + 1}{delta = -2(N-1)} set rB to B[0, k] {was B[N-1, k-1] + 1}{delta = -2(N-1)*(K)+2} GOTO[mxinit] } Q ← udeltaA1, L0 ← L0.delta1, c3; rA ← rA - Q, PgCarryBr, c1; {Adjust pointer for matrix A} BRANCH[fixrA1, lmrAdn], c2; GOTO[lmrAdn], c2, at[L0.delta1, 4, rAfixed]; lmrAdn: Q ← udeltaB1, c3; rB ← rB - Q, PgCarryBr, c1; {Adjust pointer for matrix B} BRANCH[fixrB1, lmrBdn], c2; GOTO[lmrBdn], c2, at[L0.delta1, 4, rBfixed]; lmrBdn: GOTO[mxinit], c3; mxKdone: { decrement mCOUNT, exit if done set kCOUNT to K set nCOUNT to N {done in mxinit} set rA to A[m, 0] {was A[m-1, N-1] + 1}{delta = +2} set rB to B[0, 0] {was B[n-1, k-1] + 1}{delta = -2(N*K)+2} GOTO[mxinit] } Q ← umCOUNT, L0 ← L0.delta2, c3; Q ← Q - 1, ZeroBr, L1 ← L1.matexit, c1; {Decrement M count} umCOUNT ← Q, BRANCH[$, mxfinished], c2; {Check if multiplication is finished} Q ← uKinit, L1 ← L1.mxnotfirst, c3; rA ← rA + 2, PgCarryBr, c1; {Adjust pointer for matrix A} ukCOUNT ← Q, BRANCH[$, fixrA2], c2, at[L0.delta2, 4, rAfixed]; {Restore ukCOUNT} Q ← udeltaB2, c3; rB ← rB - Q, PgCarryBr, c1; {Adjust pointer for matrix B} BRANCH[fixrB2, lmrBdn2], c2; GOTO[lmrBdn2], c2, at[L0.delta2, 4, rBfixed]; lmrBdn2: GOTO[mxinit], c3; {============================================================================ EXIT POINT ============================================================================} mxfinished: , c3; , c1; Xbus ← ib, c2; Q ← 4, CALL[RestoreRegsHere], c3; at[L1.matexit, 10, RestoreRegsRet], TOSH ← uTOSH, c2; TOS ← uTOS, GOTO[c1.pc2B2], c3; { ******** small mpy 8 bits by 8 bits ******** { TT ← Rx * Q } TT ← 0, c3; Ybus ← Rx and 1, NZeroBr, GOTO[firstmore], c1; firstmore: BRANCH[ftimes0, ftimes1], c2; ftimes1: TT ← TT + Q, GOTO[loop], c3; ftimes0: Ybus ← Rx, ZeroBr, GOTO[loop], c3; loop: Rx ← RShift1 Rx, SE ← 0, YDisp, BRANCH[more, thru], c1; more: Q ← Q + Q, BRANCH[times0, times1, 0D], c2; times1: TT ← TT + Q, GOTO[loop], c3; times0: Ybus ← Rx, ZeroBr, GOTO[loop], c3; thru: , c2; inner loop registers: rA -- Rx rB -- TOS rC -- TOSH nCOUNT -- Q deltaB0 {+2K} -- TT remapping routines: fixrA {+2} fixrB {+2K} fixrC {+2} rB {-2(N-1)(K)+2} rB {-2(N)(K)+2} rA for {-2(N-1)} } {******** rA remapping ***********************************} fixrA0: unCOUNT ← Q, GOTO[fixrAplus], c3; fixrA1: GOTO[fixrAminus], c3; fixrA2: GOTO[fixrAplus], c3; rAok: TT ← udeltaB0, L0Disp, c3; ma10: MAR ← rA ← [rhrA, Q + 0], DISP2[rAfixed], c1; {Point to element of matrix A} Q ← unCOUNT, GOTO[mxrAret], LOOPHOLE[natc], c2, at[L0.delta0, 4, rAfixed]; fixrAplus: TT ← urAVlo, c1; {Load low VA of A into TT} Q ← 0FF + 1, c2; {Prepare to add 1 page} TT ← TT + Q, CarryBr, c3; {Add 1 page, check for carry} fixrAI: Q ← urAVhi, BRANCH[rAno64p, rA64p], c1; {Move high VA of A into Q} rAno64p: urAVlo ← TT, GOTO[rArhok], c2; {No carry, save new low VA of A} rArhok: rhTT ← Q LRot0, c3; {rhTT contains urAVhi} Map ← [rhTT, TT], c1; Q ← rA, c2; {Q now contains urAVlo} rhrA ← rA ← MD, XwdDisp, c3; Map ← [rhTT, TT], DISP2[rAfixFlags], c1; MDR ← rA or 10, GOTO[rAok], c2, at[0,4,rAfixFlags]; MDR ← rA or 10, GOTO[rAok], c2, at[1,4,rAfixFlags]; MDR ← rA or 10, GOTO[rAok], c2, at[2,4,rAfixFlags]; GOTO[MATpagefault], c2, at[3,4,rAfixFlags]; rA64p: Q ← Q + 1, GOTO[rA64ch], c2; {Propagate carry to H word} {Q now contains high VA of A} rA64ch: urAVhi ← Q, c3; {Update urAVhi} GOTO[rAno64p], c1; fixrAminus: TT ← urAVlo, c1; {Store low VA of A in TT} Q ← 0FF + 1, c2; {Prepare to subtract 1 page} TT ← TT - Q, CarryBr, c3; {Subtract, check for borrow} Q ← urAVhi, BRANCH[rA64m, rAno64m], c1; {Load High VA of A into Q} rAno64m: urAVlo ← TT, GOTO[rArhok], c2; {No borrow, save new low VA of A} rA64m: Q ← Q - 1, GOTO[rA64ch], c2; {Borrow, subtract high VA of A} {******* rB remapping ***********************************} fixrB0: unCOUNT ← Q, GOTO[fixrBplus], c3; fixrB1: GOTO[fixrBminus], c3; fixrB2: GOTO[fixrBminus], c3; rBok: TT ← udeltaB0, L0Disp, c3; MAR ← rB ← [rhrB, Q + 0], DISP2[rBfixed], c1; Q ← unCOUNT, GOTO[mxrBret], LOOPHOLE[natc], c2, at[L0.delta0, 4, rBfixed]; fixrBplus: TT ← urBVlo, c1; {Load low VA of B into TT} Q ← 0FF + 1, c2; {Prepare to add 1 page} TT ← TT + Q, CarryBr, c3; {Add 1 page, check for carry} fixrBI: Q ← urBVhi, BRANCH[rBno64p, rB64p], c1; {Move high VA of B into Q} rBno64p: urBVlo ← TT, GOTO[rBrhok], c2; {No carry, save new low VA of B} rBrhok: rhTT ← Q LRot0, c3; {rhTT contains urBVhi} Map ← [rhTT, TT], c1; Q ← rB, c2; {Q now contains urBVlo} rhrB ← rB ← MD, XwdDisp, c3; Map ← [rhTT, TT], DISP2[rBfixFlags], c1; MDR ← rB or 10, GOTO[rBok], c2, at[0,4,rBfixFlags]; MDR ← rB or 10, GOTO[rBok], c2, at[1,4,rBfixFlags]; MDR ← rB or 10, GOTO[rBok], c2, at[2,4,rBfixFlags]; GOTO[MATpagefault], c2, at[3,4,rBfixFlags]; rB64p: Q ← Q + 1, GOTO[rB64ch], c2; {Propagate carry to H word} {Q now contains high VA of B} rB64ch: urBVhi ← Q, c3; {Update urBVhi} GOTO[rBno64p], c1; fixrBminus: TT ← urBVlo, c1; {Store low VA of B in TT} Q ← 0FF + 1, c2; {Prepare to subtract 1 page} TT ← TT - Q, CarryBr, c3; {Subtract, check for borrow} Q ← urBVhi, BRANCH[rB64m, rBno64m], c1; {Load High VA of B into Q} rBno64m: urBVlo ← TT, GOTO[rBrhok], c2; {No borrow, save new low VA of B} rB64m: Q ← Q - 1, GOTO[rB64ch], c2; {Borrow, subtract high VA of B} {******* rC remapping ***********************************} fixrC: unCOUNT{not really} ← Q, GOTO[fixrCplus], c3; rCok: L0Disp, c3; MAR ← rC ← [rhrC, Q + 0], DISP2[rCfixed], c1; MDR ← unCOUNT, GOTO[mxrCcont], c2, at[L0.delta0, 4, rCfixed]; fixrCplus: TT ← urCVlo, c1; {Load low VA of C into TT} Q ← 0FF + 1, c2; {Prepare to add 1 page} TT ← TT + Q, CarryBr, c3; {Add 1 page, check for carry} fixrCI: Q ← urCVhi, BRANCH[rCno64p, rC64p], c1; {Move high VA of C into Q} rCno64p: urCVlo ← TT, GOTO[rCrhok], c2; {No carry, save new low VA of C} rCrhok: rhTT ← Q LRot0, c3; {rhTT contains urCVhi} Map ← [rhTT, TT], c1; Q ← rC, c2; {Q now contains urBVlo} rhrC ← rC ← MD, XwdDisp, c3; Map ← [rhTT, TT], DISP2[rCfixFlags, 1], c1; MDR ← rC or 30, GOTO[rCok], c2, at[1,4,rCfixFlags]; Rx ← rC, GOTO[MATpagefault], c2, at[3,4,rCfixFlags]; rC64p: Q ← Q + 1, GOTO[rC64ch], c2; {Propagate carry to H word} {Q now contains high VA of C} rC64ch: urCVhi ← Q, c3; {Update urCVhi} GOTO[rCno64p], c1; GOTO[MatUfn], L1 ← L1.matufn, c2, at[03, 10, mxcheck1]; GOTO[MatUfn], L1 ← L1.matufn, c2, at[07, 10, mxcheck1]; GOTO[MatUfn], L1 ← L1.matufn, c2, at[0B, 10, mxcheck1]; CANCELBR[MatUfn, 7], L1 ← L1.matufn, c2, at[03, 10, mxcheck2]; CANCELBR[MatUfn, 7], L1 ← L1.matufn, c2, at[07, 10, mxcheck2]; CANCELBR[MatUfn, 7], L1 ← L1.matufn, c2, at[0B, 10, mxcheck2]; GOTO[MatUfn], L1 ← L1.matufn, c2, at[03, 10, mxcheck3]; GOTO[MatUfn], L1 ← L1.matufn, c2, at[07, 10, mxcheck3]; GOTO[MatUfn], L1 ← L1.matufn, c2, at[0B, 10, mxcheck3]; CANCELBR[MatUfn, 7], L1 ← L1.matufn, c2, at[03, 10, mxcheck4]; CANCELBR[MatUfn, 7], L1 ← L1.matufn, c2, at[07, 10, mxcheck4]; CANCELBR[MatUfn, 7], L1 ← L1.matufn, c2, at[0B, 10, mxcheck4]; MATpagefault: TOS ← uTOS, c3; TOSH ← uTOSH, c1; L1 ← L1.LFApf, c2; Q ← 0, CALL[RestoreRegsHere], c3; MatUfn: , c3; ufnstop: TOS ← uTOS, c1; TOSH ← uTOSH, c2; Q ← 0, CALL[RestoreRegsHere], c3; at[L1.matufn, 10, RestoreRegsRet], GOTO[ufnX3], c2; { E N D }