:TITLE[Inst.0mc...October 20, 1983  8:38 PM, van Melle];

* Ivars
Ivars:
	T ← (lspIbasex), goto[lspPushT1], opcode[100];
	T ← (lspIbasex) + (02c), goto[lspPushT1], opcode[101];
	T ← (lspIbasex) + (04c), goto[lspPushT1], opcode[102];
	T ← (lspIbasex) + (06c), goto[lspPushT1], opcode[103];
	T ← (lspIbasex) + (10c), goto[lspPushT1], opcode[104];
	T ← (lspIbasex) + (12c), goto[lspPushT1], opcode[105];
	T ← (lspIbasex) + (14c), goto[lspPushT1], opcode[106];

@IvarX:	T ← lspIbasex, opcode[107];
Ivarx1:
	T ← (NextData[IBuf]) + T;
lspPushT1:
	PFetch2[lspStkBr, Stack], goto[PushChkP5];

* Pvars
Pvars:
	PFetch2[lspEp, Stack, 0], goto[PushChkP5], opcode[110];
	PFetch2[lspEp, Stack, 2], goto[PushChkP5], opcode[111];
	PFetch2[lspEp, Stack, 4], goto[PushChkP5], opcode[112];
	PFetch2[lspEp, Stack, 6], goto[PushChkP5], opcode[113];
	PFetch2[lspEp, Stack, 10], goto[PushChkP5], opcode[114];
	PFetch2[lspEp, Stack, 12], goto[PushChkP5], opcode[115];
	PFetch2[lspEp, Stack, 14], goto[PushChkP5], opcode[116];

@PvarX:	T ← lspEp, goto[Ivarx1], opcode[117];



Fvars:
	T ← (lspEp) + (00c), goto[FVarCommon], opcode[120];
	T ← (lspEp) + (02c), goto[FVarCommon], opcode[121];
	T ← (lspEp) + (04c), goto[FVarCommon], opcode[122];
	T ← (lspEp) + (06c), goto[FVarCommon], opcode[123];
	T ← (lspEp) + (10c), goto[FVarCommon], opcode[124];
	T ← (lspEp) + (12c), goto[FVarCommon], opcode[125];
	T ← (lspEp) + (14c), goto[FVarCommon], opcode[126];

	T ← lspEp, opcode[127];
	T ← (NextData[IBuf]) + T;

FVarCommon:
	PFetch2[lspStkBr, lspGenBr], call[retLBL];
					* fetch contents of binding slot
	lu ← lspGenBr, goto[FVarUnbound, R Odd];

	PFetch2[lspGenBr, Stack, 0];	* Fetch value in slot.
					* This can page fault

WaitForStackFaultPush:
	lu ← Stack, goto[PushChkP5];

FVarUnbound:				* not looked up yet
				* T = offset of binding slot at this point
	SavedFvarOffset ← T, call[FVarLookup];
	PStore2[lspStkBr, FVarBinding], goto[FVarCommon];
					* store binding ptr, try again


* GVAR -- access value cell of atom whose index is in next two bytes
@Gvar:
	lspGenBr ← (VALbase), opcode[140];
	T ← NextData[IBuf];
	lspL0 ← T, skip[NoH2Bit8];
	  lspGenBrHi ← (VALspace2), skip;	* Use second seg of val space
	  lspGenBrHi ← (VALspace);		* Use first seg of val space
	T ← NextData[IBuf];
	lspL0 ← (lsh[lspL0, 10]) or T;
	T ← lsh[lspL0, 1];
	PFetch2[lspGenBr, Stack], goto[WaitForStackFaultPush];


SetPvars:
	PStore2[lspEp, Stack, 0], goto[UnPopStack], opcode[130];
	PStore2[lspEp, Stack, 2], goto[UnPopStack], opcode[131];
	PStore2[lspEp, Stack, 4], goto[UnPopStack], opcode[132];
	PStore2[lspEp, Stack, 6], goto[UnPopStack], opcode[133];
	PStore2[lspEp, Stack, 10], goto[UnPopStack], opcode[134];
	PStore2[lspEp, Stack, 12], goto[UnPopStack], opcode[135];
	PStore2[lspEp, Stack, 14], goto[UnPopStack], opcode[136];

UnPopStack:
	Stack&+2, goto[nxiLBL];

SetPvarPops:
	PStore2[lspEp, Stack, 0], goto[PopChk6], opcode[270];
	PStore2[lspEp, Stack, 2], goto[PopChk6], opcode[271];
	PStore2[lspEp, Stack, 4], goto[PopChk6], opcode[272];
	PStore2[lspEp, Stack, 6], goto[PopChk6], opcode[273];
	PStore2[lspEp, Stack, 10], goto[PopChk6], opcode[274];
	PStore2[lspEp, Stack, 12], goto[PopChk6], opcode[275];
	PStore2[lspEp, Stack, 14], goto[PopChk6], opcode[276];


* SetI, op 142, Set IVar N to TOS where N=following byte, dont pop stack
@SetI:
	T ← lspIbasex, goto[Svrx0], opcode[142];

* SetP, op 137, Set PVar N to TOS where N=following byte, dont pop stack
@SetP:
	T ← lspEp, goto[Svrx0], opcode[137];

Svrx0:
	T ← (NextData[IBuf]) + T;
	PStore2[lspStkBr, Stack], goto[UnPopStack];



* SetF, op 143, Set Free var N to TOS, dont pop stack
@SetF:
	T ← lspEp, opcode[143];
	T ← (NextData[IBuf]) + T;
SetF1:
	PFetch2[lspStkBr, lspGenBr], call[retLBL];	* fetch contents of binding slot
	lu ← lspGenBr, goto[SetFUnbound, R Odd];

	T ← (StackSpaceR);
	lu ← (rsh[lspGenBrHi, 10]) xor T;	* is binding slot on stack?
	T ← lspGenBrHi, goto[SetFtop, alu#0];
	PStore2[lspGenBr, Stack, 0], goto[UnPopStack];

SetFUnbound:				* not looked up yet
				* T = offset of binding slot at this point
	SavedFvarOffset ← T, call[FVarLookup];
	PStore2[lspStkBr, FVarBinding], goto[SetF1];
					* store ptr in slot and try again
SetFtop:		* binding slot not on stack, need to refcnt
			* Move base to L2,3.  Should fix RplPtr instead
	lspL3 ← T;
	T ← lspGenBr, loadpage[pgRplPtr];
	lspL2 ← T, gotop[SetGvar1];	* do gvar← on this atom



*
* Called with T pointing to Fvar binding slot
*
FVarLookup:
	PFetch1[lspIfuBr, lspL1, 7];	* lspL1 ← Nlocals,,FvarOffset

	T ← lspEp;
	T ← (SavedFvarOffset) - T, loadPage[pgFvar];
	lspL0 ← T;			* word offset of binding slot past Ep

onpage[pgFvar];

	T ← rsh[lspL1, 10];		* T ← NLocals
	lspL1 ← (rhmask[lspL1]) - T;	* lspL1 ← -NLocals + Fvaroffset

	T ← rsh[lspL0, 1];		* cell offset of binding slot

	T ← (lspL1) + T;	* T ← (SavedFvarOffset - Ep)/2 - NLocals + Fvaroffset
				*    = nametable offset
	PFetch1[lspIfuBr, FVarName], goto[FVarLookupName];


* Nil, op 150, Push Nil onto stack
@Nil:
	T ← Stack&+1 ← 0c, goto[PushTChkP5], opcode[150];

* Kt, op 151, Push T onto stack
@Kt:
	Stack&+1 ← 0c, opcode[151];
	Stack&+1 ← (KtVal), goto[PushChkP5];

* Zero, op 152, Push zero onto stack
@Zero:
	Stack&+1 ← (smallpl), opcode[152];
	Stack&+1 ← 0c, goto[PushChkP5];

* One, op 153, Push small int one onto stack
@One:
	Stack&+1 ← (smallpl), opcode[153];
	Stack&+1 ← 1c, goto[PushChkP5];

* Sic, op 154, Push 2nd byte onto stack as small integer
@SIC:
	Stack&+1 ← (smallpl), opcode[154];
	T ← NextData[IBuf], CallX[PushTChkP5];

* Snic, op 155, Push 2nd byte onto stack as small negative integer
@SNIC:
	Stack&+1 ← (smallneg), opcode[155];
	T ← 177400c;
	T ← (NextData[IBuf]) or T, CallX[PushTChkP5];

* Sicx, op 154, Push next two bytes onto stack as small integer
@SICX:
	Stack&+1 ← (smallpl), opcode[156];
Sicx1:				* push word formed from next two bytes
	lu ← CycleControl ← NextData[IBuf];	* Load from ALUA[10:17],...
	T ← lhmask[Cycle&PCXF];		* CycleControl is read to R[0:7]
	T ← (NextData[IBuf]) or T, CallX[PushTChkP5];

* AtomNumber, op 160, Same as SICX, except for its use
@AtomNumber:
	Stack&+1 ← (smallpl), goto[Sicx1], opcode[160];

* AConst, op 147, Push the following 2 bytes onto stack as an atom
@AConst:
	Stack&+1 ← 0c, goto[Sicx1], opcode[147];

* GConst, op 157, Push the 3 following bytes onto stack as a constant
@GConst:
	T ← NextData[IBuf], opcode[157];
	Stack&+1 ← T, goto[Sicx1];

* Copy, op 144, Copy top of stack onto stack again
@Copy:
	Stack&-1, opcode[144];
	Stack&+2 ← Stack;
	Stack&-1;
	Stack&+2 ← Stack, goto[PushChkP5];

	:END[inst];