-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLMEM.mc
More file actions
386 lines (328 loc) · 12.1 KB
/
Copy pathLMEM.mc
File metadata and controls
386 lines (328 loc) · 12.1 KB
1
:Title[LMEM];* Edit History* March 11, 1985 6:17 PM, Masinter, fix bug where BLT* of number > 2^15 would always exit* February 2, 1985 2:55 PM, Masinter, attempt to fix bug where BLT* January 21, 1985 11:54 AM, Masinter, bum VAG2 a bit, clean up a * PAGEFAULTOK or two* January 17, 1984 4:02 AM, JonL, added .pbsFetch for PUTBASEN and* PUTBITS* January 17, 1984 2:10 AM, JonL, added .gbsFetch for use by GETBASEN,* GETBASEPTRN, and GETBITS; also tailed them out thru REPSMT2* January 17, 1984 1:25 AM, JonL, abstracted .addrNfetch, changed* DOGETBYTE to .getByte and let it use LTEMP1 instead of LTEMP0* January 17, 1984 12:51 AM, JonL, squeezed one inst out of opADDBASE* January 13, 1984 10:42 PM, JonL, spawned LMEM off LOW.mc* January 4, 1984 7:08 PM, JonL, tailed opPUTBASEPTR and opPUTBITS* into TL.POP1. * December 15, 1983 3:45 PM, JonL, HILOC to tail into REPTMD1*--------------------------------------------------------------------* Low-Level Memory referencing*-------------------------------------------------------------------- TOP LEVEL; knowrbase[LTEMP0]; InsSet[LispInsSet, 1];*--------------------------------------------------------------------opHILOC:*-------------------------------------------------------------------- fetch_ TSP, T_ (SmallHi), branch[REPTMD1];regOP1[322, StackM2BR, opHILOC, noNData];*--------------------------------------------------------------------opLOLOC:*-------------------------------------------------------------------- store_ TSP, dbuf_ SmallHi, NextOpCode;regOP1[323, StackM2BR, opLOLOC, noNData];*--------------------------------------------------------------------opADDBASE:*-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase, Call[.addrNfetch]; branch[.adbs1, alu#0], LTEMP1_ (LTEMP1) + (Md); * + Lo.word of addr branch[.+2, carry], LEFT_ (LEFT) + 1; TSP_ (store_ T) + 1, dbuf_ LTEMP1, NextOpCode; * Done - fast case T_ (store_ T) - 1, dbuf_ LTEMP1; * Carry over into next TSP_ (fetch_ T) + (2c); * next segment LTEMP0_ (1s) + (Md); store_ T, dbuf_ LTEMP0, NextOpCode;SUBROUTINE;.addrNfetch:* Enter and exit with StackBR* Leaves 0 on pd iff TOS is a smallposp LTEMP0_ Md, T_ (fetch_ T) - (2c); * LTEMP0_ Hi.word of n LTEMP1_ Md, (fetch_ T); * LTEMP1_ Lo.word of n pd_ (LTEMP0) xor (SmallHi), Return; * Is n a smallP?TOPLEVEL;.adbs1: CallUFN;% * This could continue something like . . . LEFT_ (LEFT) - 1, memBase_ StackM2BR; T_ (fetch_ TSP) - 1, flipMemBase, Call[.UNBOX1]; T_ (TSP) + 1, flipMemBase; * Change back to StackM2BR T_ (fetch_ T) - 1; * TSP was "pulled back" (fetch_ T), LTEMP1_ Md; * LTEMP1_ lo.word of addr T_ (LTEMP1) + Q, LTEMP1_ T; * Lo.word sum LTEMP0_ (LTEMP0) + (Md), XorSavedCarry; * Hi.word sum T_ (store_ LTEMP1) + 1, dbuf_ T; * Store Lo.word (store_ T), dbuf_ LTEMP0, NextOpCode; * Store Hi.word%regOP1[320, StackM2BR, opADDBASE, noNData];*--------------------------------------------------------------------opVAG2:*-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase, Call[.UNBOX2]; T_ (store_ TSP) + 1, dbuf_ Q; TSP_ (store_ T) + 1, dbuf_ LTEMP1, NextOpCode;regOP1[321, StackM2BR, opVAG2, noNData];*--------------------------------------------------------------------opBLT: * (destinationaddr sourceaddr #wds)*--------------------------------------------------------------------* Defined to move one word at a time, from the high end to the* low end, and be continuable after interrupts.* These highly-bummed ideas are taken from Taft's implementation of * Mesa BLT and BLTL, found in DMesaRW.mc* Enter with: * Q set to 20b* T set to number of words to move minus one* stack has running count (minus 1)* Branch back around the loop: * stack updated to next value* T set up 17 for the next full munch* Before starting the transfer, touch the last word of the source and* destination blocks, to force any page faults that would happen, to* happen now rather than in the inner loop. Maybe need not touch the * first words, since a fault there will abort the loop before it has * done anything permanent. Also, "pre-warm" the cache for the next * time around. T_ (fetch_ TSP) - 1, flipMemBase, Call[.addrNfetch]; Branch[.+2, alu=0], T_ T - 1; CallUFN; * Punt: #wds not smallposp LTEMP2_ Md, T_ (fetch_ T) - 1; * Why 2 for StkP? 'Cause LTEMP0_ Md, T_ (fetch_ T) - 1; * BitBlt does it that way LTEMP3_ Md, (fetch_ T), T_ (2c); * Fetch on hi.word of Dest T_ pd_ LTEMP1, StkP_ T; * LTEMP1 had #wds to move branch[.bltxit, alu=0], * zero words to transfer? T_ Md, stack_ T - 1, memBase_ BBDSTBR; * Stack_ #wds-1 branch[.+2, alu>=0], BRHi_ T; CallUFN; * call UFN if > 2^15 words T_ (20c); Q_ T, T_ T - 1; * Q_ (20c), T_ (17c) BRLo_ LTEMP3; T_ (stack) and T, memBase_ BBSRCBR; * T_ #wds-1 mod 20b BRHi_ LTEMP0; BRLo_ LTEMP2; PSTATE_ (add[PS.PFOK!, PS.INBLT!]c); .bltloop: Cnt_ T; LTEMP0_ T_ (FETCH_ stack) - T; * Fetch on first src wd LTEMP2_ (FETCH_ T) - (Q); * Fetch on last src wd PreFetch_ LTEMP2, flipMemBase; FETCH_ stack; * Fetch on first dest wd FETCH_ LTEMP0; * Fetch on last dest wd PreFetch_ LTEMP2, T_ MD, flipMemBase; * Synchronize PageFaults*** Here's the tight inner loop to move a munch.bltmm: fetch_ stack, flipMemBase; stack_ (STORE_ stack) - 1, dbuf_ Md, flipMembase, Branch[.bltmm, Cnt#0&-1]; *** pd_ stack, Branch[.+2, Reschedule']; * Tails into BitBlt code if Branch[BBXitToContinue]; * need to xit for interrupt T_ (17c), Branch[.bltloop, alu>=0]; * Should be 17 or -1, not 0.bltdone: PSTATE_ A0;.bltxit: LEFT_ (LEFT) + (2c); * LEFT is re-computed if TSP_ (TSP) - (4c), NextOpCode; * there is a fault-out% T_ (fetch_ TSP) + 1; LTEMP0_ Md, T_ (fetch_ T) - (2c); pd_ (LTEMP0) xor (SmallHi); branch[.+2, alu=0], LTEMP2_ Md, T_ (fetch_ T) - 1; CallUFN; LTEMP1_ Md, T_ (fetch_ T) - 1; LTEMP0_ Md, T_ (fetch_ T) - 1; LTEMP3_ Md, fetch_ T, pd _ T_ (LTEMP2); branch[.+2, alu#0], LTEMP2_ Md, memBase_ BBDSTBR, T_ T - 1; branch[.bltdone]; * no words to copy Cnt_ T; * number of words to transfer - 1 BRHi_ LTEMP2; BRLo_ LTEMP3; memBase_ BBSRCBR; BRHi_ LTEMP0; BRLo_ LTEMP1;* and now for the loop. This should really keep state in Stack a la BITBLT: PAGEFAULTOK; FETCH_ T, flipMemBase; T_ (store_ T) - 1, dbuf_ MD, flipMembase, branch[.-1, Cnt#0&-1]; PAGEFAULTNOTOK;.bltdone: Left_ (Left) + (2c); TSP_ (TSP) - (4c), NextOpCode;%regOP1[304, StackM2BR, opBLT, noNData];*--------------------------------------------------------------------opGETBASEN:*-------------------------------------------------------------------- T_ (fetch_ TSP) + 1, Call[.gbsFetch];PAGEFAULTOK; IFETCH_ LTEMP0; T_ MD, memBase_ StackM2BR, Branch[REPSMALLT];regOP2[310, StackM2BR, opGETBASEN, noNData];SUBROUTINE;.gbsFetch: T_ Md, fetch_ T, LTEMP1_ (rhmask); LTEMP0_ Md, memBase_ ScratchLZBR; BrHi_ T, Return;TOPLEVEL;*--------------------------------------------------------------------opGETBITS: *-------------------------------------------------------------------- T_ (fetch_ TSP) + 1, Call[.gbsFetch];PAGEFAULTOK; IFETCH_ LTEMP0, TisID; memBase_ StackM2BR; LTEMP0_ MD, RF_ Id; T_ ShiftLMask[LTEMP0], memBase_ StackM2BR, Branch[REPSMALLT];regOP3[312, StackM2BR, opGETBITS, noNData];*--------------------------------------------------------------------opGETBASEPTRN: *-------------------------------------------------------------------- T_ (fetch_ TSP) + 1, Call[.gbsFetch];PAGEFAULTOK; LTEMP0_ (IFETCH_ LTEMP0) + 1; T_ MD, ifetch_ LTEMP0;PAGEFAULTNOTOK; T_ T and (LTEMP1), memBase_ StackM2BR; T_ Md, TSP_ (store_ TSP) + 1, dbuf_ T, Branch[REPSMT2];regOP2[311, StackM2BR, opGETBASEPTRN, noNData];*--------------------------------------------------------------------opGETBASEBYTE:*-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase, Call[.addrNfetch]; * See opADDBASE branch[.+2, alu=0], T_ T - 1; CallUFN; * Index not smallPosp fetch_ T, LTEMP0_ Md; memBase_ LScratchBR, LEFT_ (LEFT) + 1; LTEMP0_ Md, BrLo_ LTEMP0; BrHi_ LTEMP0, call[.getByte]; T_ (store_ T) + 1, dbuf_ SmallHi; TSP_ (store_ T) + 1, dbuf_ LTEMP1, NextOpCode;regOP1[302, StackM2BR, opGETBASEBYTE, noNData];SUBROUTINE;.getByte:* called by BIN, GETBASEBYTE;* Assumes current memBase is pointer, LTEMP1 is byte offset* Returns byte in LTEMP1* Must not clobber T dblbranch[.dgbeven, .dgbodd, R even], LTEMP1_ (LTEMP1) rsh 1;.dgbeven: PAGEFAULTOK; FETCH_ LTEMP1; LTEMP1_ MD, memBase_ StackBR; PAGEFAULTNOTOK; LTEMP1_ RSH[LTEMP1, 10], return;.dgbodd: PAGEFAULTOK; FETCH_ LTEMP1; LTEMP1_ MD, memBase_ StackBR; PAGEFAULTNOTOK; LTEMP1_ (LTEMP1) and (rhmask), return;TOP LEVEL;*--------------------------------------------------------------------opPUTBASEN:*-------------------------------------------------------------------- T_ (fetch_ TSP) + 1, Call[.pbsFetch]; * fetch val hi STORE_ T, dbuf_ LTEMP0;:if[Debugging]; T_ MD, TSP _ (TSP) - (2c); PAGEFAULTNOTOK, NextOpCode;:else; T_ MD, TSP _ (TSP) - (2c), NextOpCode; * wait for faults:endif;SUBROUTINE;.pbsFetch: LTEMP0_ Md, T_ (fetch_ T) - (3c); * LTEMP0_ Hi.newByte pd_ (LTEMP0) xor (SmallHi); * check for smallPosp branch[.+2, alu=0], LTEMP0_ Md, Q_ Md, * LTEMP0_ newByte T_ (fetch_ T) + 1; TOPLEVEL; CallUFN; SUBROUTINE; LTEMP2_ Md, fetch_ T; * LTEMP2_ Hi.addr LEFT_ (LEFT) + 1, memBase_ ScratchLZBR; T_ (Id) + (Md); * T_ Lo.addr + alpha branch[.+2, carry'], BrHi_ LTEMP2; LTEMP2_ (LTEMP2) + 1, branch[.-1];:if[Debugging]; PAGEFAULTOK, Return;:else; Return;:endif;TOPLEVEL;regOP2[315, StackM2BR, opPUTBASEN, noNData];*--------------------------------------------------------------------opPUTBITS:*-------------------------------------------------------------------- T_ (fetch_ TSP) + 1, Call[.pbsFetch]; * fetch val hi FETCH_ T; WF_ Id, LTEMP1_ T; T_ ShMdBothMasks[LTEMP0];PAGEFAULTNOTOK; store_ LTEMP1, dbuf_ T, Branch[TL.POP1];regOP3[317, StackM2BR, opPUTBITS, noNData];*--------------------------------------------------------------------opPUTBASEPTRN:*-------------------------------------------------------------------- T_ (fetch_ TSP) + 1; * fetch val hi LTEMP0_ Md, T_ (fetch_ T) - (3c); * fetch val lo Q_ Md, T_ (fetch_ T) + 1; * fetch addrhi LTEMP2_ Md, fetch_ T; * LTEMP0, Q have newval memBase_ ScratchLZBR, LEFT_ (LEFT) + 1; T_ (Id) + (Md); branch[.+2, carry'], BrHi_ LTEMP2; LTEMP2_ (LTEMP2) + 1, branch[.-1];:if[Debugging];PAGEFAULTOK; T_ (STORE_ T) + 1, dbuf_ LTEMP0; STORE_ T, dbuf_ Q;PAGEFAULTNOTOK, Branch[TL.POP1];:else; T_ (STORE_ T) + 1, dbuf_ LTEMP0; STORE_ T, dbuf_ Q, Branch[TL.POP1];:endif;regOP2[316, StackM2BR, opPUTBASEPTRN, noNData];*--------------------------------------------------------------------opPUTBASEBYTE: * PUTBASEBYTE(base, displacement, value)*-------------------------------------------------------------------- T_ (TSP) - 1; T_ (fetch_ T) - 1; LTEMP0_ Md, T_ (fetch_ T) - 1; * LTEMP0 has new byte pd_ (LTEMP0) and not (rhmask); LTEMP1_ Md, T_ (fetch_ T) - 1, branch[.+2, alu=0]; CallUFN; pd_ (LTEMP1) xor (SmallHi); LTEMP1_ Md, T_ (fetch_ T) - 1, branch[.+2, alu=0];* LTEMP1_offset CallUFN; LTEMP2_ Md, T_ (fetch_ T) - 1; pd_ (LTEMP2) xor (SmallHi); LTEMP2_ Md, fetch_ T, branch[.+2, alu=0]; CallUFN; LEFT_ (LEFT) + 1, memBase_ LScratchBR; LTEMP2_ Md, BrLo_ LTEMP2; BrHi_ LTEMP2; PAGEFAULTOK; branch[.putRight, R odd], LTEMP1_ (LTEMP1) rsh 1; FETCH_ LTEMP1; T_ Md, TSP_ T; * CAN FAULT T_ T and (rhmask); Q_ LTEMP0; LTEMP0_ LSH[LTEMP0, 10]; T_ T + (LTEMP0), branch[.restoreByte];.putRight: FETCH_ LTEMP1; T_ Md, TSP_ T; * CAN FAULT T_ T and (lhmask); T_ T + (LTEMP0), Q_ LTEMP0, branch[.restoreByte];.restoreByte: store_ LTEMP1, dbuf_ T; PAGEFAULTNOTOK; LEFT_ (LEFT) + 1, memBase_ StackBR; TSP_ (store_ TSP) + 1, dbuf_ SmallHi; TSP_ (store_ TSP) + 1, dbuf_ Q, NextOpCode;regOP1[307, StackBR, opPUTBASEBYTE, noNData];