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