:TITLE[Stack.0mc...August 11, 1982 5:27 PM, van Melle];


************************
* Overflow is checked by looking at B0 (R<0).
* If set then overflow has occured.
* This should probably rshift 1 more to begin with.
* Push is done by lsh 1.

onpage[5];
PushTChkP5:
Stack&+1 ← T, loadpage[pgHStack], goto[PushChkxP5];
PushChkP5:
loadpage[pgHStack];
PushChkxP5:
StkState ← lcy[StkState, 1], dblgotop[HStkOverflow, PushChkRet, R<0];

onpage[15];
PushChkP15:
loadpage[pgHStack];
StkState ← lcy[StkState, 1], dblgotop[HStkOverflow, PushChkRet, R<0];

onpage[pgHStack];
PushChkP16:
StkState ← lcy[StkState, 1], dblgoto[HStkOverflow, PushChkRet, R<0];

PushChkRet:
* This pair branched to from other pages also
NextOpCode;

HStkOverflow:

*
lu ← (lspTsp) and (2c);
*
skip[alu#0];
*breakpoint;

* lspTsp is quadodd and points at the cell below the bottom of hstack.
* We store bottom 4 cells (8 words) of Hstack at lspTsp+2 thru +8.
* Low 2 bits of tsp rshift 2 indicate what piece of
* hstack we are dealing with.

dispatch[lspTsp, 14, 2];
StkState ← rcy[StkState, 4], disp[OvfHStkDisp0];
* account for 4 pops

OvfHStkDisp0:
PStore4[lspTsp, Hstack4, 2], goto[Ov0], disptable[4];
PStore4[lspTsp, Hstack10, 2], goto[Ov1];
PStore4[lspTsp, Hstack14, 2], goto[Ov2];
PStore4[lspTsp, Hstack0, 2], goto[Ov3];

Ov0:
PStore4[lspTsp, Hstack10, 6], goto[OvfDone];
Ov1:
PStore4[lspTsp, Hstack14, 6], goto[OvfDone];
Ov2:
PStore4[lspTsp, Hstack0, 6], goto[OvfDone];
Ov3:
PStore4[lspTsp, Hstack4, 6], goto[OvfDone];

OvfDone:
lspTsp ← (lspTsp) + (10c), task;* 8 cells were stored

* Now check for overflow. We need to make sure there is enough room for
* another hstack overflow (10b words) plus the StackFullPunt that could
* follow it (10b words to flush the rest of the stack plus 2 words to
* make a Fsb after it).

T ← (lspTsp) + (22c);* This could overflow!!
lu ← (lspEsp) - T;
skip[nocarry];
NextOpCode;

loadpage[pgLisp0];* could be in skip instr
AC1← (StackRequested), gotop[StackFullPunt];

***********************
* Underflow is checked by looking at B15 (Rodd). More than one bit may
* need to be examined for more than the 1 element functions.
* Pop is done by rsh 1

onpage[6];
PopChk6:
PopChkP6:
loadpage[pgHStack];
StkState ← rcy[StkState, 1], dblgotop[PopChkUndflow, PopchkRet, R Odd];

onpage[pgHStack];
PopChkP16:
StkState ← rcy[StkState, 1], dblgoto[PopChkUndflow, PopchkRet, R Odd];

PopChkUndflow:
* This pair branched to from other pages, too
call[HStkUndflw];
nop;* alloc constraint
PopchkRet:
NextOpCode;


* Check for 2 or 3 elements on stack. Caller did loadpage[pgHStack]

onpage[4];
CheckElt2P4:
lu ← StkState, dblgotop[HStkUndflw, ChkRet, R Odd];

CheckElt3P4:
lu ← (StkState) and (3c), gotop[CE3Tail];

onpage[5];
CheckElt2P5:
lu ← StkState, dblgotop[HStkUndflw, ChkRet, R Odd];

CheckElt3P5:
lu ← (StkState) and (3c), gotop[CE3Tail];

onpage[7];
CheckElt2P7:
lu ← StkState, dblgotop[HStkUndflw, ChkRet, R Odd];

CheckElt3P7:
lu ← (StkState) and (3c), gotop[CE3Tail];

onpage[pgHStack];
CE3Tail:
dblgoto[HStkUndflw, ChkRet, alu#0];
ChkRet: return;

HStkUndflw:

*
Fetch a quadword to the stack, thus putting two more cells on

*** Bind assumes this subroutine does not disturb T

*
lu ← (lspTsp) and (2c);
*
skip[alu#0];
*breakpoint;

lspTsp← (lspTsp) - (2c);
dispatch[lspTsp, 14, 2];
StkState ← lcy[StkState, 2], disp[UndHStkDisp0];

UndHStkDisp0:
PFetch4[lspTsp, Hstack0, 0], goto[UndHStkLoop], disptable[4];
PFetch4[lspTsp, Hstack4, 0], goto[UndHStkLoop];
PFetch4[lspTsp, Hstack10, 0], goto[UndHStkLoop];
PFetch4[lspTsp, Hstack14, 0], goto[UndHStkLoop];

UndHStkLoop:
lspTsp ← (lspTsp) - (2c), return;


ClrHStk:
* called from LspSubr, LspPuntStore

*
lu ← (lspTsp) and (2c);
*
skip[alu#0];
*breakpoint;
*
nop;

UseCtask;* save return link
T ← APC&APCTASK;
lspL5 ← T;

StkState ← rcy[StkState, 1], call[.+1];

*** Stkstate now is odd if this is the last quad to store, i.e.
*** there are 1 or 2 cells on stack left.

dispatch[lspTsp, 14, 2];
disp[ClrHStkDisp0];

ClrHStkDisp0:
PStore4[lspTsp, Hstack4, 2], goto[ClrHStack1], disptable[4];
PStore4[lspTsp, Hstack10, 2], goto[ClrHStack1];
PStore4[lspTsp, Hstack14, 2], goto[ClrHStack1];
PStore4[lspTsp, Hstack0, 2], goto[ClrHStack1];

ClrHStack1:
StkState ← rcy[StkState, 2], goto[ClrDone, R Odd];
lspTsp ← (lspTsp) + (4c), return;* to dispatch
ClrDone:
StkState ← lcy[StkState, 2];* undo last rcy
lspTsp ← (lspTsp) + (4c), skip[alu>=0];
lspTsp ← (lspTsp) - (2c);* really stored odd number of cells

:IF[StkDebug];
nop;* alloc
call[ChkStk];
:ENDIF;

APC&APCTask ← lspL5, goto[retLBL];

MyAlink:
Stack&+1 ← (smallpl), opcode[146];
T ← (lspEp) - (11c);* Offset of Alink word
PFetch1[lspStkBr, Stack];
Stack ← (Stack) and not (1c);* Turn off Xbit
Stack ← (Stack) - (12c), goto[PushLBL];* Point at FX (not PVar)

:IF[StkDebug];

onpage[pgHStack];
ChkStk:
T ← 7c;
T ← (LDF[SSTKP&NSTKP, 14, 3]) xor T;
T ← (LDF[lspTsp, 14, 3]) xor T;
skip[alu=0];
breakpoint;
INCMPANEL, return;
:ENDIF;

:END[Stack];