:Title[linst.mc, December 6, 1982 1:43 PM, Masinter];

* variable opcodes, including free variable lookup

knowrbase[LTEMP0];
TOP LEVEL;
InsSet[LispInsSet, 1];
*--------------------------------------------------------------------
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:
memBase← ScratchLZBR, branch[.+2, R even], T← Md, LTEMP0;
T← Id, branch[.FVFAIL];

* KLUDGE: LH IS DUPLICATED!!!!
T← T and (rhmask);
BRHi← T;

PAGEFAULTOK;

LTEMP0← (FETCH← LTEMP0) + 1;
T← MD, fetch← LTEMP0, branch[
PUSHTMD];* can fault

.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) lsh 1;

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], T← Md, LTEMP0, memBase← StackM2BR;
T← Id, branch[.setffail];


* KLUDGE
*** TOP BYTE IS FILLED IN TOO

T← T and (rhmask);
pd← T xor (StackHi);
branch[.setfglobal, alu#0], TSP← (fetch← TSP) - 1, flipMemBase;
T← Md, TSP← (fetch← TSP) + 1, branch[TL.ST0TMD];

:if[Reduced];
.setfglobal:
TSP← (TSP) + 1, memBase← StackBR, call[SUB.PUSHT];
T← LTEMP0, call[SUB.PUSHT];
DEFLO← AT.SETFVAR;
NARGS ← 2c, branch[DOCALLPUNT];

:else;
.setfglobal:
TSP← (TSP) + 1, memBase← LScratchBR, branch[.setglobal];
:endif;

.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];

*--------------------------------------------------------------------
* 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)) lsh 1;
T← VALspace;

.setglobal:
BrLo← LTEMP0;
BrHi← T;

PAGEFAULTOK;

T← (FETCH← 0s) + 1;
Case← 1c, call[GCLOOKUP];
* deleteref old pointer

memBase← StackM2BR, branch[RPLPTRTAIL];

regOP3[27, ifuBR, opGVARgets, noNData];
:endif;


*--------------------------------------------------------------------
opNIL:
*--------------------------------------------------------------------
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
TSP← (store← TSP) + 1, dbuf← 0c, branch[TL.PUSHNIL];

regOP1[150, StackBR, opNIL, noNData];

*--------------------------------------------------------------------
opKT:
*--------------------------------------------------------------------
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
TSP← (store← TSP) + 1, dbuf← 0c, branch[TL.PUSHTRUE];

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;
T← LSH[T,10];
T← Id or T, branch[PUSHSMALLT];

regOP3[156, StackBR, opSICX, noNData];
* SICX
regOP3[160, StackBR, opSICX, noNData];
* ATOMNUMBER
*--------------------------------------------------------------------
opACONST:
*--------------------------------------------------------------------
T← Id;
T← LSH[T,10];
T← (Id) + (T);
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
TSP← (store← TSP) + 1, dbuf← 0c, branch[TL.PUSHT];

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[.GConstOdd, R even], LTEMP0, T← MD, FETCH← T;

.GConstEven:
T← T and (rhmask), branch[
PUSHTMD];

.GConstOdd:
* rh T,,lh Md has low word, lh T has hi word.
LTEMP0← MD;

PAGEFAULTNOTOK;

LTEMP0← rcy[T, LTEMP0, 10];
T← rsh[T, 10], branch[PUSHT0];

IFUjmp[157, 1, ifuBR, 0, opGCONST, 4];

*--------------------------------------------------------------------
opCOPY:
*--------------------------------------------------------------------
T← (fetch← TSP) - 1, flipMemBase;
T← Md, fetch← T, branch[
PUSHTMD];

regOP1[144, StackM2BR, opCOPY, noNData];