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