:Title[LSTACK.mc, StackFrame manipulations]; * * Edit History * March 22, 1985 masinter, Formatting only * January 17, 1985 11:32 PM, Masinter, add STORE.N, COPY.N * January 13, 1984 9:25 PM, JonL, LBIND merged in here * PUSHTMD, TL.ST0TMD, TL.PUSHNIL and TL.PUSHTRUE to LVARCONST, * removed PUSHQT (no users?) * January 6, 1984 4:55 AM, JonL, Note that REPNIL appears here (when ?) * added TL.REPNIL2 for CDR's benefit * January 3, 1984 8:32 PM, JonL, Removed FIXSTACKREGS (was * nowhere else referenced) and added lots of commentary * December 27, 1983 11:30 AM, JonL, moved opCOPY from LINST * December 26, 1983 3:11 PM, JonL, added subroutine ABFETCH, * SWAP starts out StackM2BR, and to use ABFETCH * December 21, 1983 7:48 AM, JonL, brought in opSWAP, opPOP, * and REPSMALLT; Moved NEXTOP to LOPS * December 15, 1983 3:49 PM -- added label REPTMD1 - JonL * December 9, 1983 1:14 PM -- Added ARG0 - JonL * Prior dates -- Masinter KnowRBase[LTEMP0]; TOP LEVEL; InsSet[LispInsSet, 1]; *-------------------------------------------------------------------- opCOPY: *-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase; T_ Md, fetch_ T, branch[PUSHTMD]; regOP1[144, StackM2BR, opCOPY, noNData]; *-------------------------------------------------------------------- opCOPYN: *-------------------------------------------------------------------- T_ (TSP) - (T), TisID; T_ (fetch_ T) - 1, flipMemBase; T_ Md, fetch_ T, branch[PUSHTMD]; regOP2[75, StackM2BR, opCOPYN, noNData]; *-------------------------------------------------------------------- opSTOREN: *-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase; T_ Md, LTEMP0 _ (fetch_ T) - (3c); LTEMP0_ (LTEMP0) - (T), TisID, branch[TL.ST0TMD]; regOP2[74, StackM2BR, opSTOREN, noNData]; *-------------------------------------------------------------------- opPOP: *-------------------------------------------------------------------- regOP1[277, StackBR, opPOP, noNData]; LEFT_ (LEFT) + 1; TL.POP1: TSP_ (TSP) - (2c), NextOpcode; *-------------------------------------------------------------------- opSWAP: *------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMembase, call[ABFETCH]; * Bhi in LTEMP0 * Blo in LTEMP1 LTEMP2_ Md, T_ (fetch_ T) - 1; * Ahi in LTEMP2 LTEMP3_ Md, * Alo in LTEMP3 T_ (store_ T) + 1, dbuf_ LTEMP0; * Ahi_ Bhi T_ (store_ T) + 1, dbuf_ LTEMP1; * Alo_ Blo T_ (store_ T) + 1, dbuf_ LTEMP2; * Bhi_ Ahi store_ T, dbuf_ LTEMP3, NextOpcode; * Blo_ Alo regOP1[375, StackM2BR, opSWAP, noNData]; *-------------------------------------------------------------------- SUBROUTINE; ABFETCH: *-------------------------------------------------------------------- * For two-arguments A and B on stack (B in TOS) * Enter with fetch pending on Bhi, * T positioned over Blo, * membase is StackBr * typical entry starts membase at StackM2BR and does * T_ (fetch_ TSP) - 1, flipMembase, call[ABFETCH]; * Exit with Bhi in LTEMP0 * Blo in LTEMP1 * fetch pending on Ahi * T positioned over Alo LTEMP0_ Md, T_ (fetch_ T) - (3c); * Hi.word in LTEMP0 LTEMP1_ Md, T_ (fetch_ T) + 1, return; * Lo.word in LTEMP1 TOPLEVEL; *-------------------------------------------------------------------- opMYALINK: *-------------------------------------------------------------------- regOP1[146, StackBR, opMYALINK, noNData]; T_ (PVAR) - (FXBACK[ALINK]); fetch_ T, T_ (177776c); T_ T and Md; T_ T - (FX.PVAR), branch[PUSHSMALLT]; UfnOps[145]; * MYARGCOUNT UfnOps[141]; * ARG0 % Someday, we'd like to do these two *-------------------------------------------------------------------- opMYARGCOUNT: *-------------------------------------------------------------------- regOP1[145, StackBR, opMYARGCOUNT, noNData]; T_ (PVAR) - (FXBACK[ALINK]), call[.GETMYARGCOUNT]; * Get Alink wd to see if fastp branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; TSP_ (store_ TSP) + 1, dbuf_ SmallHi, branch[TL.PUSHT]; SUBROUTINE; .GETMYARGCOUNT: T_ (fetch_ T)+(FXDIF[BFLAGS,ALINK]); * T points to BFLAGS in BF LTEMP0_ Md, fetch_ T; *LTEMP0 holds Alink,fetch Bflags contents branch[.+2, R even], LTEMP0, LTEMP0 _ (BfPadded); TOP LEVEL; callUFN; SUBROUTINE; *Punt out if not fastp case pd _ (LTEMP0) and (Md); branch[.+2, alu=0], T_ (T - (IVAR)) rsh 1; * and nargs _ # IVAR wds / 2 T_ T - 1, RETURN; * when "padded", there is an extra cell. sub it off return; TOP LEVEL; *-------------------------------------------------------------------- opARG0: *-------------------------------------------------------------------- regOP1[141, StackM2BR, opARG0, noNData]; T_ (fetch_ TSP) + 1; * One arg, the index of IVAR T_ Md, fetch_ T; * wanted pd_ T-(SmallHi), LTEMP1_ Md; branch[.+2, alu=0], T_ (LTEMP1) + (LTEMP1), flipMemBase;*punt if ~SMALLPOSP callUFN; * or if = 0 branch[.+2, alu#0], LTEMP2_ T + (IVAR); * args are double wds callUFN; * BEGINNING OF TESTING nop; T_ (PVAR) - (FXBACK[ALINK]), call[.GETMYARGCOUNT]; * at this point, T has MYARGCOUNT in it pd_ (LTEMP1) - T - 1, flipMemBase; branch [.+2, carry']; callUFN;* arg too large! * end of test T_ (fetch_ LTEMP2) + 1; T_ Md, fetch_ T; T_ Md, TSP _ (store_ TSP) + 1, dbuf_ T; TSP _ (store_ TSP) - 1, dbuf_ T, NextOpCode; % *-------------------------------------------------------------------- opBIND: *-------------------------------------------------------------------- * Binds n1 pvars to NIL and * n2 pvars to the n2 items on the stack * Last pvar stored into is N * pushes binding mark [-(n1+n2)-1,, 2*N] T_ LTEMP0_ Id; * n1 (first 4 bits) #NILs LTEMP1_ Id, Cnt_ T; * n2 (next 4 bits) #values T_ (Id) lsh 1; * 2*N T_ (PVAR) + (Q_ T); branch[.endBindNils, Cnt=0&-1], LTEMP2_ T + 1; .BindVarToNil: LTEMP2_ (store_ LTEMP2) - 1, DBuf_ AT.NIL; LTEMP2_ (store_ LTEMP2) - 1, DBuf_ 0c, branch[.BindVarToNil,Cnt#0&-1]; .endBindNils: Cnt_ LTEMP1, T_ LTEMP1; * #values to bind LEFT_ (LEFT) + T; .BindVarToVal: T_ (TSP) - 1, branch[.EndBind, Cnt=0&-1]; TSP_ (fetch_ T) - 1; T_ Md, (fetch_ TSP); T_ Md, LTEMP2_ (store_ LTEMP2) - 1, dbuf_ T; LTEMP2_ (store_ LTEMP2) - 1, DBuf_ T, branch[.BindVarToVal]; .EndBind: T_ (0s) - (LTEMP1); * -N2 T_ T - (LTEMP0) - 1; * -N1-N2-1 PUSHTQ: branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; :if[Debugging]; pd_ T and not (77c); branch[.+2, alu=0]; uCodeCheck[badpushval]; :endif; TSP_ (store_ TSP) + 1, dbuf_ T; TSP_ (store_ TSP) + 1, dbuf_ Q, NextOpCode; IFUreg[21, 3, StackBR, 0, opBIND, noNData, 0, 1]; *-------------------------------------------------------------------- opUNBIND: *-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase; LTEMP0_ Md, T_ (fetch_ T) - 1, flipMemBase; TSP_ T, Q_ Md, branch[opDUNBIND]; *-------------------------------------------------------------------- opDUNBIND: *-------------------------------------------------------------------- T_ TSP_ (fetch_ TSP) - (2c); LTEMP1_ Md, T_ T + 1; branch[opDUNBIND, R>=0], LTEMP1, LTEMP1_ not (LTEMP1); * T points (relative to StackM2BR) to the odd word * LTEMP1 has (n1+n2) flipMemBase; fetch_ T; Cnt_ LTEMP1; T_ (PVAR) + (Md) + 1; .unbindvar: * Loop here branch[.unbindend, Cnt=0&-1], T_ T - 1; :if[Debugging]; * check if slot was not bound fetch _ T; pd _ Md; branch[.+2, alu>=0]; uCodeCheck[UnBindNotBound]; :endif; T_ (store_ T) - 1, dbuf_ AllOnes, branch[.unbindvar]; .unbindend: call[FIXLEFT]; pd_ Id; branch[PUSHTQ, alu=0], T_ LTEMP0; * Id=0 for unbind NextOpCode; regOP1[22, StackM2BR, opUNBIND, 0]; * UNBIND regOP1[23, StackM2BR, opDUNBIND, 1]; * DUNBIND