:TITLE[Fncall.0mc...February 21, 1985  3:44 PM, van Melle];

* Fn0, op 010, Call function of 0 args whose name is in first 2 bytes
@Fn0:
	lspNargs ← 0c, goto[FnxTail], opcode[010];

* Fn1, op 011, Call function of 1 args whose name is in first 2 bytes
@Fn1:
	lspNargs ← 1c, goto[FnxTail], opcode[011];

* Fn2, op 012, Call function of 2 args whose name is in first 2 bytes
@Fn2:
	lspNargs ← 2c, goto[FnxTail], opcode[012];

* Fn3, op 013, Call function of 3 args whose name is in first 2 bytes
@Fn3:
	lspNargs ← 3c, goto[FnxTail], opcode[013];

* Fn4, op 014, Call function of 4 args whose name is in first 2 bytes
@Fn4:
	lspNargs ← 4c, goto[FnxTail], opcode[014];

* Fnx, op 015, Fully general function call, first byte is number of args, next 2 bytes are atom
@Fnx:	T ← NextData[IBuf], opcode[015];
	lspNargs ← T, goto[FnxTail];	* Get number of args

FnxTail:
	T ← NextData[IBuf];
	lspDefx1 ← T;
	T ← NextData[IBuf];
	loadpage[pgFrame];
	lspDefx1 ← (lsh[lspDefx1, 10]) or T, gotop[lspCallFn0];

* CheckApply*, op 017: Punt if TOS is not ccodep or is NLAMBDA*

@CheckApply:
	T ← lsh[Stack&-1, 1], skip[R<0], opcode[17];
	  lspGenBrHi ← (DEFspace), skip; * use first seg of def space
	  lspGenBrHi ← (DEFspace2);	* use second seg of def space
	lu ← Stack&+1;
	lspGenBr ← (DEFbase), skip[alu=0];
	  lspUFN ← 17c, goto[ufnLBL];	* TOS not atom
	nop;		* Wait for base to be written because fetch can fault
	PFetch2[lspGenBr, lspL0];	* fetch function definition cell
	lspL0 ← (lspL0) and (10000c), goto[ApplyStarUfn, R>=0];
					* Ufn if codep bit off
	skip[alu#0];
	  NextOpCode;
	lspUFN ← 17c, goto[ufnLBL];
ApplyStarUfn:
	lspUFN ← 17c, goto[ufnLBL];

* Applyfn, op 016:
* apply function whose name is TOS and number of args is TOS-2

* This checks for 3 elements on stack because StkState cannot
*  indicate no elements on stack

@Applyfn:
	nop, opcode[016];
ApplyFn:
	loadpage[pgHStack], call[CheckElt3P4];
	T ← Stack&-1;
	lspDefx1 ← T;
	T ← Stack&-1;
	lspDefx0 ← T;
	T ← Stack&-2;
	lspNargs ← T, loadpage[pgFrame];
	StkState ← rsh[StkState, 2], gotop[lspCallfn];

onpage[opPage0];
lspUfnxP4:
	T ← SStkp;
	lspL4 ← T, loadpage[pgUfnxA];
	T ← (PcxReg);
onpage[pgUfnxA];
	Stkp ← lspL4, lspL4 ← T, NoRegILockOk, task;
				* Stkp backed up to as of start of opcode
				* LspL4 = PCF as of start of opcode
	T ← (PCFReg);
	lu ← (lspL4) - T;	* has PCF changed (i.e. more bytes fetched)?
	lspGenBrHi ← STATSspace, skip[alu=0];
	  PCF ← lspL4;	* yes, restore it.  Can't be unconditional
			* because only low 3 bits of PCF can be loaded
	lspGenBr ← UFNTableBase;
	T ← lsh[lspUFN, 1];		* index into double-word ufn table
	PFetch2[lspGenBr, lspL2];		* fetch function definition
	T ← rhmask[lspL3];			* get number of args
	lspL3 ← rsh[lspL3, 10];			* number of extra bytes (0-2)
	lspNargs ← T, goto[lspUfnx4a, alu=0];	* skip much if no extra bytes
	T ← NextData[IBuf];
	lu ← lspL3, goto[lspUfnx4b, R Odd];
	lspL1 ← T;
	T ← NextData[IBuf];
	T ← (lsh[lspL1, 10]) or T;
lspUfnx4b:
	Stack&+1 ← (smallpl);
	Stack&+1 ← T;				* Push extra byte(s) as smallp
	StkState ← lsh[StkState, 1];
lspUfnx4a:
	T ← lspL2, loadpage[pgFrame];		* Ufn atom
	lspDefx1 ← T, gotop[lspCallfn0];	* call the function


	:END[Fncall];