:Title[LSTACK.mc, December 7, 1982 3:42 PM, Masinter];
* STACK MANAGEMENT ROUTINES, COMMON INSTRUCTION TAILS
KnowRBase[LTEMP0];
TOP LEVEL;
InsSet[LispInsSet, 1];
*--------------------------------------------------------------------
opMYALINK:
*--------------------------------------------------------------------
T← (PVAR) - (FXBACK[ALINK]);
fetch← T, T← (177776c);
T← T and Md;
T← T - (FX.PVAR), branch[PUSHSMALLT];
regOP1[146, StackBR, opMYALINK, noNData];
*--------------------------------------------------------------------
TL.ST0TMD:
T← Md, LTEMP0← (store← LTEMP0) + 1, dbuf← T, branch[TL.ST0];
*--------------------------------------------------------------------
TL.ST0:
store← LTEMP0, dbuf← T, NextOpCode;
*--------------------------------------------------------------------
TL.PUSHNIL:
TSP← (store← TSP) + 1, dbuf← AT.NIL, NextOpCode;
*--------------------------------------------------------------------
TL.PUSHTRUE:
TSP← (store← TSP) + 1, dbuf← AT.T, NextOpCode;
*--------------------------------------------------------------------
TL.PUSHT:
TSP← (store← TSP) + 1, dbuf← T, NextOpCode;
*--------------------------------------------------------------------
TL.NOP:
nop;
NextOpCode;
*--------------------------------------------------------------------
TL.DECTSP2: * after PCF←, normally
TSP← (TSP) - (2c);
NextOpCode;
*--------------------------------------------------------------------
SUBROUTINE;
SUB.PUSHT:
TSP← (store← TSP) + 1, dbuf← T, return;
*--------------------------------------------------------------------
TOP LEVEL;
PUSHT0:
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
:if[Debugging];
pd← T and not (77c);
branch[.+2, alu=0];
uCodeCheck[badpushval];
:endif;
T← (store← TSP) + 1, dbuf← T;
TSP← (store← T) + 1, dbuf← LTEMP0, NextOpCode;
*--------------------------------------------------------------------
PUSHSMALLT:
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
TSP← (store← TSP) + 1, dbuf← SmallHi, branch[TL.PUSHT];
*--------------------------------------------------------------------
PUSHTMD:
PAGEFAULTNOTOK;
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
:if[Debugging];
pd← T and not (77c);
branch[.+2, alu=0];
uCodeCheck[badpushval];
:endif;
T← Md, TSP← (store← TSP) + 1, dbuf← T, branch[TL.PUSHT];
*--------------------------------------------------------------------
:if[Debugging];
PUSHTQ:
pd← T and not (77c);
branch[.+2, alu=0];
uCodeCheck[badpushval];
PUSHTQOK:
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
:else;
PUSHTQ:
PUSHTQOK:
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
:endif;
TSP← (store← TSP) + 1, dbuf← T;
TSP← (store← TSP) + 1, dbuf← Q, NextOpCode;
PUSHQT:
PUSHQTOK:
branch[.+2, R>=0], LEFT← (LEFT) - 1, memBase← StackBR;
StackCheck;
:if[Debugging];
LTEMP0← Q;
pd← (LTEMP0) and not (77c);
branch[.+2, alu=0];
uCodeCheck[badpushval];
:endif;
TSP← (store← TSP) + 1, dbuf← Q, branch[TL.PUSHT];
*--------------------------------------------------------------------
SUBROUTINE;
ADDSTK:* called by FNCALL and MYFRAME when not enough stack
T← (fetch← ESP) + 1;* next stack word
T← Md, fetch← T;
pd← T xor (FreeStackBlock);
branch[.addstkFail, alu#0];
ESP← (ESP) + (Md), branch[.mergefree];
FIXSTACKREGS:
memBase← StackBR;
PVAR← (PVAR) - (sub[FX.PVAR!, FX.NEXT!]c);
PVAR← (fetch← PVAR) + (sub[FX.PVAR!, FX.NEXT!]c);
T← ESP← Md;
TSP← T, branch[.mergefree];
FIXLEFT:
T← ESP, branch[.fixleft1];
.mergefree:
T← (fetch← ESP) + 1;
T← Md, fetch← T;
pd← T xor (FreeStackBlock);
branch[.fixleft1, alu#0], T← ESP;
ESP← (ESP) + (Md), branch[.mergefree];
.fixleft1:
LEFT← T - (TSP);
LEFT← (LEFT) rsh 1;
LEFT← (LEFT) - (LEFTOffset), return;
TOP LEVEL;
.addstkFail:
branch[STKOVPUNT];
*--------------------------------------------------------------------
* REPTMD - replace value on top of stack with value in T,,MD
*--------------------------------------------------------------------
REPTMD:
memBase← StackM2BR;
:if[Debugging];
pd← T and not (77c);
branch[.+2, alu=0];
uCodeCheck[badpushval];
:endif;
T← Md, TSP← (store← TSP) + 1, dbuf← T;
TSP← (store← TSP) - 1, dbuf← T, NextOpcode;
* ---- debugging subroutines
:if[Debugging];
SUBROUTINE;
CHECKPCXSUBR:
pd← (PSTATE) and (PS.PCXBAD);
branch[.+2, alu#0];
return;
PSTATE← Link;
TOP LEVEL;
UCodeCheck[PuntInCall];
:endif;
:if[DebugEachInst];
SUBROUTINE;
DontKnowRBase;
*--------------------------------------------------------------------
NEXTOP: GLOBAL, * debug code that gets executed at the end of each instruction
*--------------------------------------------------------------------
RBASE←RBASE[PSTATE];
PSTATE← (PSTATE) and (not[PS.PCXBAD!]C);
branch[.+2, alu#0], LTEMP1← Link;
ifuJump[0];
TOP LEVEL;
UcodeCheck[];
:endif;