: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;

PUSH
QT:
PUSH
QTOK:
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;