:Title[LBIND.mc, December 6, 1982 1:05 PM, Masinter];

*--------------------------------------------------------------------
* BIND, UNBIND, DUNBIND opcodes
*--------------------------------------------------------------------


knowrbase[LTemp0];
top level;
InsSet[LispInsSet, 1];

*--------------------------------------------------------------------
opBIND:
*--------------------------------------------------------------------
* Binds n1 pvars to NIL and
* n2 pvars to the n2 items on the stack
* Last pvar stored into is N
* pushes binding mark [-(n1+n2)-1,, 2*N]

T← LTEMP0← Id;* n1 (first 4 bits) #NILs
LTEMP1← Id, Cnt← T;* n2 (next 4 bits) #values
T← (Id) lsh 1;* 2*N
T← (PVAR) + (Q← T);
branch[.endBindNils, Cnt=0&-1], LTEMP2← T + 1;

.BindVarToNil:
LTEMP2← (store← LTEMP2) - 1, DBuf← AT.NIL;
LTEMP2← (store← LTEMP2) - 1, DBuf← 0c,branch[.BindVarToNil,Cnt#0&-1];

.endBindNils:
Cnt← LTEMP1, T← LTEMP1;* #values to bind
LEFT← (LEFT) + T;

.BindVarToVal:
T← (TSP) - 1, branch[.EndBind, Cnt=0&-1];
TSP← (fetch← T) - 1;
T← Md, (fetch← TSP);
T← Md, LTEMP2← (store← LTEMP2) - 1, dbuf← T;
LTEMP2← (store← LTEMP2) - 1, DBuf← T, branch[.BindVarToVal];

.EndBind:
T← (0s) - (LTEMP1);* -N2
T← T - (LTEMP0) - 1, branch[PUSHTQOK];* -N1-N2-1

IFUreg[21, 3, StackBR, 0, opBIND, noNData, 0, 1];


*--------------------------------------------------------------------
opUNBIND:
*--------------------------------------------------------------------
T← (fetch← TSP) - 1, flipMemBase;
LTEMP0← Md, T← (fetch← T) - 1, flipMemBase;
TSP← T, Q← Md;

opDUNBIND:
T← TSP← (fetch← TSP) - (2c);
LTEMP1← Md, T← T + 1;
branch[opDUNBIND, R>=0], LTEMP1, LTEMP1← not (LTEMP1);

*
T points (relative to StackM2) to the odd word
*
LTEMP2 LTEMP2 has (n1+n2)

flipMemBase;
fetch← T;
Cnt← LTEMP1;
T← (PVAR) + (Md) + 1;

.unbindvar:
branch[.unbindend, Cnt=0&-1], T← T - 1;

:if[Debugging];
* check if slot was not bound
fetch ← T;
pd ← Md;
branch[.+2, alu>=0];
uCodeCheck[UnBindNotBound];
:endif;

T← (store← T) - 1, dbuf← AllOnes, branch[.unbindvar];

.unbindend:
call[FIXLEFT];
pd← Id;
branch[.wasUnbind, alu=0], T← LTEMP0;* Id=0 for unbind
NextOpCode;

.wasUnBind:
branch[PUSHTQ];

regOP1[22, StackM2BR, opUNBIND, 0];
* UNBIND
regOP1[23, StackM2BR, opDUNBIND, 1];
* DUNBIND