:Title[LVARCONST]; * * Edit History * March 22 11:12AM, Masinter, formatting * March 13, 1985 9:42 AM, Masinter, remove call to SAVEUCODESTATE * January 8, 1985 4:12 AM, JonL, GVAR_ and endofstack typos in constants * January 6, 1985 2:50 AM, JonL, emmend GVAR, GVAR_ and the global case of * FVAR lookup to permit 16-bit litatom indices *February 18, 1984 3:14 PM, JonL, labels PUSHSMALLT1 & PUSHTRUE1 for opRWMufMan * January 31, 1984 1:30 AM, JonL, Added subroutine .aconstfetch * January 13, 1984 9:05 PM, JonL, linst and lfv merged into this file * PUSHTMD and TL.ST0TMD in from LSTACK * December 30, 1983 3:33 PM, JonL, merged two insts in call to GCLOOKUP * December 27, 1983 11:28 AM, JonL, opCOPY to LSTACK * December 6, 1982 1:43 PM, Masinter * Variable opcodes, including free variable lookup * and Constants opcodes knowrbase[LTEMP0]; TOP LEVEL; InsSet[LispInsSet, 1]; *-------------------------------------------------------------------- * Some common tails for this file *-------------------------------------------------------------------- *-------------------------------------------------------------------- PUSHTMD: * pushes T,,MD, bumps TSP, and decrements LEFT *-------------------------------------------------------------------- PAGEFAULTNOTOK; branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; T_ Md, TSP_ (store_ TSP) + 1, dbuf_ T, branch[TL.PUSHT]; *-------------------------------------------------------------------- TL.ST0TMD: T_ Md, LTEMP0_ (store_ LTEMP0) + 1, dbuf_ T, branch[TL.ST0]; *-------------------------------------------------------------------- TL.ST0: store_ LTEMP0, dbuf_ T, NextOpCode; *-------------------------------------------------------------------- *-------------------------------------------------------------------- opIVAR: *-------------------------------------------------------------------- T_ (ifetch_ IVAR) + 1; T_ Md, ifetch_ T, branch[PUSHTMD]; regOP1[100, StackBR, opIVAR, 0]; * IVAR regOP1[101, StackBR, opIVAR, 2]; regOP1[102, StackBR, opIVAR, 4]; regOP1[103, StackBR, opIVAR, 6]; regOP1[104, StackBR, opIVAR, 10]; regOP1[105, StackBR, opIVAR, 12]; regOP1[106, StackBR, opIVAR, 14]; regOP2[107, StackBR, opIVAR, noNData]; * PVARX *-------------------------------------------------------------------- opPVAR: *-------------------------------------------------------------------- T_ (ifetch_ PVAR) + 1; T_ Md, ifetch_ T, branch[PUSHTMD]; regOP1[110, StackBR, opPVAR, 0]; * PVAR regOP1[111, StackBR, opPVAR, 2]; regOP1[112, StackBR, opPVAR, 4]; regOP1[113, StackBR, opPVAR, 6]; regOP1[114, StackBR, opPVAR, 10]; regOP1[115, StackBR, opPVAR, 12]; regOP1[116, StackBR, opPVAR, 14]; regOP2[117, StackBR, opPVAR, noNData]; * PVARX *-------------------------------------------------------------------- opFVAR: *-------------------------------------------------------------------- T_ (ifetch_ PVAR) + 1; LTEMP0_ Md, ifetch_ T; .retryfvar: branch[.+2, R even], LTEMP0, T_ Md, memBase_ ScratchLZBR; T_ Id, branch[.FVFAIL]; T_ T and (rhmask); * KLUDGE: LH IS DUPLICATED!!!! BRHi_ T; PAGEFAULTOK; LTEMP0_ (FETCH_ LTEMP0) + 1; T_ MD, fetch_ LTEMP0, branch[PUSHTMD]; .FVFAIL: * T = offset of free variable, fill in and continue LTEMP0_ T, call[FVLOOKUP]; * T passed and smashed by FVLOOKUP T_ LTEMP0; T_ T + (PVAR); T_ (fetch_ T) + 1; LTEMP0_ Md, fetch_ T, branch[.retryfvar]; regOP1[120, StackBR, opFVAR, 0]; * FVAR regOP1[121, StackBR, opFVAR, 2]; regOP1[122, StackBR, opFVAR, 4]; regOP1[123, StackBR, opFVAR, 6]; regOP1[124, StackBR, opFVAR, 10]; regOP1[125, StackBR, opFVAR, 12]; regOP1[126, StackBR, opFVAR, 14]; regOP2[127, StackBR, opFVAR, noNData]; * FVARX *-------------------------------------------------------------------- opGVAR: * alpha + beta form atom number of global to fetch *-------------------------------------------------------------------- T_ Id; * hi bits T_ LSH[T,10]; * shift left LTEMP0_ ((Id) + T); branch[.+2, alu>=0], LTEMP0 _ (LTEMP0) lsh 1; flipMemBase; * use Val2BR instead PAGEFAULTOK; LTEMP0_ (FETCH_ LTEMP0) + 1; T_ MD, fetch_ LTEMP0, branch[PUSHTMD]; regOP3[140, ValSpaceBR, opGVAR, noNData]; *-------------------------------------------------------------------- opSETPVAR: *-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase; T_ Md, fetch_ T; LTEMP0_ (Id) + (PVAR), branch[TL.ST0TMD]; regOP1[130, StackM2BR, opSETPVAR, 0]; * PVAR_ regOP1[131, StackM2BR, opSETPVAR, 2]; regOP1[132, StackM2BR, opSETPVAR, 4]; regOP1[133, StackM2BR, opSETPVAR, 6]; regOP1[134, StackM2BR, opSETPVAR, 10]; regOP1[135, StackM2BR, opSETPVAR, 12]; regOP1[136, StackM2BR, opSETPVAR, 14]; regOP2[137, StackM2BR, opSETPVAR, noNData]; * PVARX_ *-------------------------------------------------------------------- opSETPVARPOP: *-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase; * fetch TSP-2 T_ Md, TSP_ (fetch_ T) - 1; * fetch TSP-1, TSP_ TSP-2 LTEMP0_ (Id) + (PVAR); LEFT_ (LEFT) + 1, BRANCH[TL.ST0TMD]; regOP1[270, StackM2BR, opSETPVARPOP, 0]; regOP1[271, StackM2BR, opSETPVARPOP, 2]; regOP1[272, StackM2BR, opSETPVARPOP, 4]; regOP1[273, StackM2BR, opSETPVARPOP, 6]; regOP1[274, StackM2BR, opSETPVARPOP, 10]; regOP1[275, StackM2BR, opSETPVARPOP, 12]; regOP1[276, StackM2BR, opSETPVARPOP, 14]; *-------------------------------------------------------------------- opSETIVAR: *-------------------------------------------------------------------- T_ (fetch_ TSP) - 1, flipMemBase; T_ Md, fetch_ T; LTEMP0_ (Id) + (IVAR), branch[TL.ST0TMD]; regOP2[142, StackM2BR, opSETIVAR, noNData]; * IVARX_ *-------------------------------------------------------------------- opFVARgets: *-------------------------------------------------------------------- T_ (ifetch_ PVAR) + 1; LTEMP0_ Md, ifetch_ T; .retrysetfvar: branch[.+2, R even], LTEMP0, T_ Md, memBase_ StackM2BR; T_ Id, branch[.setffail]; * Fvar not looked up yet T_ T and (rhmask); * KLUDGE - TOP BYTE IS FILLED IN TOO pd_ T xor (StackHi); branch[.setfglobal, alu#0], TSP_ (fetch_ TSP) - 1, flipMemBase; T_ Md, TSP_ (fetch_ TSP) + 1, branch[TL.ST0TMD]; .setfglobal: TSP_ (TSP) + 1, memBase_ LScratchBR, Branch[.setglobal]; .setffail: LTEMP0_ T, call[FVLOOKUP]; T_ LTEMP0; T_ T + (PVAR); T_ (fetch_ T) + 1; LTEMP0_ Md, fetch_ T, branch[.retrysetfvar]; regOP2[143, StackBR, opFVARgets, noNData]; *-------------------------------------------------------------------- SUBROUTINE; SUB.PUSHT: *-------------------------------------------------------------------- TSP_ (store_ TSP) + 1, dbuf_ T, return; TOP LEVEL; *-------------------------------------------------------------------- * GVAR_ alpha + beta form atom number of global to store TOS *-------------------------------------------------------------------- :if[Reduced]; UfnOps[27]; :else; opGVARgets: LTEMP0_ Id, memBase_ LScratchBR; LTEMP0_ LSH[LTEMP0, 10]; LTEMP0_ ((Id) + (LTEMP0)); branch[.+2, alu>=0], LTEMP0 _ (LTEMP0) lsh 1; T_ (add[VALspace!,1]c), branch[.setglobal]; * use Val2BR instead T_ VALspace, branch[.setglobal]; .setglobal: BrLo_ LTEMP0; BrHi_ T, LTEMP4_ A0; PAGEFAULTOK; Case_ T_ (FETCH_ 0s) + 1, Call[GCLOOKUP]; * deleteref old pointer memBase_ StackM2BR, Branch[RPLPTRTAIL]; * addref for new pointer regOP3[27, ifuBR, opGVARgets, noNData]; :endif; *-------------------------------------------------------------------- opNIL: *-------------------------------------------------------------------- Branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; TSP_ (store_ TSP) + 1, dbuf_ (AtomHiVal), Branch[TL.PUSHNIL]; TL.PUSHNIL: TSP_ (store_ TSP) + 1, dbuf_ (AT.NIL), NextOpCode; regOP1[150, StackBR, opNIL, noNData]; *-------------------------------------------------------------------- opKT: *-------------------------------------------------------------------- branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; PUSHTRUE1: TSP_ (store_ TSP) + 1, dbuf_ (AtomHiVal), branch[TL.PUSHTRUE]; TL.PUSHTRUE: TSP_ (store_ TSP) + 1, dbuf_ AT.T, NextOpCode; regOP1[151, StackBR, opKT, noNData]; *-------------------------------------------------------------------- op01SIC: *-------------------------------------------------------------------- branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; TSP_ (store_ TSP) + 1, dbuf_ SmallHi; TSP_ (store_ TSP) + 1, dbuf_ T, TisID, NextOpCode; regOP1[152, StackBR, op01SIC, 0]; * '0 regOP1[153, StackBR, op01SIC, 1]; * '1 regOP2[154, StackBR, op01SIC, noNData]; * SIC *-------------------------------------------------------------------- opSNIC: *-------------------------------------------------------------------- T_ (Id) - (400c); branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; TSP_ (store_ TSP) + 1, dbuf_ SmallNegHi, branch[TL.PUSHT]; regOP2[155, StackBR, opSNIC, noNData]; * SNIC *-------------------------------------------------------------------- opSICX: *-------------------------------------------------------------------- T_ Id, Call[.aconstfetch]; PUSHSMALLT: branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; PUSHSMALLT1: TSP_ (store_ TSP) + 1, dbuf_ SmallHi, branch[TL.PUSHT]; TL.PUSHT: TSP_ (store_ TSP) + 1, dbuf_ T, NextOpCode; regOP3[156, StackBR, opSICX, noNData]; * SICX regOP3[160, StackBR, opSICX, noNData]; * ATOMNUMBER *-------------------------------------------------------------------- opACONST: *-------------------------------------------------------------------- T_ Id, Call[.aconstfetch]; branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; TSP_ (store_ TSP) + 1, dbuf_ (AtomHiVal), branch[TL.PUSHT]; SUBROUTINE; .aconstfetch: T_ LSH[T,10]; T_ (Id) + (T), Return; TOPLEVEL; regOP3[147, StackBR, opACONST, noNData]; *-------------------------------------------------------------------- opGCONST: *-------------------------------------------------------------------- * push 24 bit inline constant * coded as a one byte jump opcode which jumps to .+4 LTEMP0_ not (PCX'); * current pc LTEMP0_ (LTEMP0) + 1; * byte# of hi byte T_ (LTEMP0) rsh 1; * word# of hi byte PAGEFAULTOK; T_ (FETCH_ T) + 1; * fetch it & next word branch[.+2, R even], LTEMP0, T_ MD, FETCH_ T; T_ T and (rhmask), branch[PUSHTMD]; LTEMP0_ MD; * rh T,,lh Md has low word, lh T has hi word. PAGEFAULTNOTOK; LTEMP0_ rcy[T, LTEMP0, 10]; T_ rsh[T, 10]; PUSHT0: * pushes T,,LTEMP0, bumps TSP, and decrements LEFT branch[.+2, R>=0], LEFT_ (LEFT) - 1, memBase_ StackBR; StackCheck; PAGEFAULTNOTOK; T_ (store_ TSP) + 1, dbuf_ T; TSP_ (store_ T) + 1, dbuf_ LTEMP0, NextOpCode; IFUjmp[157, 1, ifuBR, 0, opGCONST, 4]; :if[Reduced]; UfnOps[57]; :else; *-------------------------------------------------------------------- opSTKSCAN: *-------------------------------------------------------------------- T_ (fetch_ TSP) + 1; FVNAME_ Md, fetch_ T, T_ (FX.PVAR); FVNAME_ Md, pd_ FVNAME; branch[.+2, alu=0], pd_ FVNAME; CallUFN; * not LITATOM branch[.+2, alu#0]; CallUFN; * NIL nop; * placement constraints FVEP_ (PVAR) - T, call[DOLOOKUP]; memBase_ StackM2BR, T_ TSP; T_ (store_ T) + 1, dbuf_ FVHI; store_ T, dbuf_ FVLO, NextOpCode; REGOP1[57, StackM2BR, opSTKSCAN, noNData]; :endif; *-------------------------------------------------------------------- SUBROUTINE; FVLOOKUP: *-------------------------------------------------------------------- * look up free variable # T/2 in current frame * fill in location where value is bound * preserve LTEMP0 memBase_ ifuBR; PAGEFAULTOK; FETCH_ add[FNH.NLFV!]s; FVNAME_ T rsh 1; * free variable index FVCHAIN_ (PVAR) + T + 1; * where to fill in the indirection FVTMP_ MD; * nlocals, fvoffset PAGEFAULTNOTOK; T_ rsh[FVTMP, 10]; * T_ NLOCALS FVTMP_ (FVTMP) and (rhmask); T_ (FVTMP) - T; T_ T + (FVNAME); fetch_ T; FVNAME_ Md, T_ (FX.PVAR); FVEP_ (PVAR) - T; memBase_ StackBR; store_ FVCHAIN, dbuf_ 0c, branch[.newframe]; *-------------------------------------------------------------------- DOLOOKUP: *-------------------------------------------------------------------- * Scan for free variable FVNAME starting at FVEP, return * in FVHI,FVLO the pointer to where it is bound * if FVCHAIN is odd, store indirection pointer at stackspace * should check for reschedule!!! FVCHAIN_ A0; .newframe: T_ (FVEP) + 1, memBase_ StackBR; fetch_ T; FVEP_ Md; FVEP_ (FVEP) and not (1c); FVEP_ (FVEP) - (FX.PVAR); branch[.endofstack, alu=0], fetch_ FVEP; FVTMP_ Md; pd_ (FVTMP) and (FXNTValid); T_ (FVEP) + (FX.DEFLO), branch[.+2, alu=0]; T_ (FVEP) + (FX.NTLO); T_ (fetch_ T) + 1; FVTMP_ Md, fetch_ T, T_ (rhmask); T_ T and (Md), memBase_ LScratchBR; BrHi_ T; BrLo_ FVTMP; FVINDEX_ FNH.FIRSTNAME; .lookforvar: PAGEFAULTOK; FETCH_ add[FNH.NTSIZE!]s; * can fault FVTMP_ Cnt_ MD; * FVTMP = NTSIZE PAGEFAULTNOTOK; .fvloop: * this can really be done in a 2 inst loop branch[.newframe, Cnt=0&-1]; FVINDEX_ (fetch_ FVINDEX) + 1; T_ Md; pd_ (FVNAME) xor T; branch[.fvloop, alu#0]; % this is what a 2 instruction loop would look like T_ A0; * # FVNAME branch[.+2, Cnt#0], pd_ T-T-1; * pd #0 branch[.newframe]; FVINDEX_ (fetch_ FVINDEX) + 1, branch[.fvfound, alu=0]; T_ Md, pd_ (FVNAME) xor T, dblbranch[.notfound, .-1, Cnt=0&-1] .fvfound: FVINDEX_ (FVINDEX) - (2c); % .fvfound: * found a match T_ (FVTMP) - 1; T_ T + (FVINDEX); * add NTSIZE, note FVINDEX already incremented fetch_ T; FVHI_ Md, T_ (rhmask); T_ (T and (FVHI)) lsh 1, branch[.fvpfvar, R<0]; .fvivar: FVEP_ (FVEP) - 1, memBase_ StackBR; FVEP_ (fetch_ FVEP) + 1; FVLO_ T + Md; FVHI_ StackHi, branch[.donefvlookup]; .fvpfvar: T_ T + (FVEP), memBase_ StackBR; T_ T + (FX.PVAR); * T is stack relative location T_ (fetch_ T) + 1; FVLO_ Md, fetch_ T; FVHI_ Md, pd_ (FVHI) and (40000c); * check FVAR bit FVHI_ (FVHI) and (rhmask), branch[.fvfvar, alu#0]; .fvpvar: branch[.+2, R>=0], FVLO, FVLO_ T - 1, memBase_ LScratchBR; branch[.fvloop]; * unbound PVAR FVHI_ StackHi, branch[.donefvlookup]; .fvfvar: branch[.+2, R odd], FVLO; branch[.donefvlookup]; * should create chain here branch[.newframe]; .endofstack: FVLO_ (FVNAME) + (FVNAME); FVHI_ ValSpace, branch[.+2, carry']; FVHI_ (FVHI) xor (1c); * a bit like flipMembase .donefvlookup: branch[.+2, R odd], FVCHAIN, memBase_ StackBR; return; * kludge!!! * STORE FVHI in both halves T_ LSH[FVHI, 10]; T_ T + (FVHI); T_ (store_ FVCHAIN) - 1, dbuf_ T; store_ T, dbuf_ FVLO, return; TOPLEVEL;