:TITLE[Ustats.0mc, August 11, 1982 3:30 PM, van Melle]; :IF[StatsMode]; onpage[pgFrame3]; FNStat: * Come here on function call when lspStatsPtr is on lspL2 ← T; * Nargs T ← lspIfuBr, loadpage[pgStats]; * fnheader lo lspL3 ← T, UseCTask, call[EmitStats1]; * put out stats T ← lspNargs, goto[FNStatDone]; * Restore state we entered in onpage[pgJump]; * Tail of return is on pgJump for ifu refill ReturnStat: * Come here when we are about to return to someone * returnstat is just like fncall, but Nargs = 77 T ← lspIfuBr; * fnheader lo lspL3 ← T, loadpage[pgStats]; T ← AllOnes, call[EmitStats]; * Nargs = all ones goto[ReturnStatDone]; onpage[pgLisp0]; SubrStat: * Come here on subrcall. Subr# in ac2, Nargs in ac3 lspIfuBrHi ← Zero; * Clear fn header hi T ← AC2; * "fn header" lo = punt# lspL3 ← T, loadpage[pgStats]; T ← AC3, call[EmitStats]; * Nargs T ← (StatsPointerLocation); PStore1[MDS, lspStatsPtr], goto[SubrStatDone]; * Make stats pointer up to date, since going to bcpl now onpage[pgJump]; CheckStatOvfl: * have we overflowed? lu ← (lspStatsPtr) - (StatsBufferBoundary), goto[nxiLBL, R<0]; goto[StatsPunt, alu>=0]; goto[nxiLBL]; onpage[pgStats]; EmitStats: * Come here with T = nargs, L3 = fn addr lo, * IfuBrHi = fn addr hi to emit a 4-word function stat lspL2 ← T, UseCTask; * L2 ← Nargs EmitStats1: T ← APCTask&APC; * return link lspL5 ← T; * save it T ← rhmask[lspIfuBrHi]; * hiloc of fnheader lspL2← (lsh[lspL2, 10]) or T; * Nargs in left half lspL2← (lspL2) or (140000c); * Top two bits mean function event T ← lspStatsPtr, goto[Emit2, R Even]; PStore1[MDS, RZero]; * filler word; even placement T ← lspStatsPtr← (lspStatsPtr) + 1; * Doubleword align pointer Emit2: PStore2[MDS, lspL2]; * Store nargs,,fnheader hi,, Fnheader lo call[GetTime]; * Get time in L2,3 T ← lspStatsPtr ← (lspStatsPtr) + (2c); PStore2[MDS, lspL2]; * store time APCTask&APC ← lspL5; * restore link & return lspStatsPtr ← (lspStatsPtr) + (2c), return; :ENDIF; onpage[pgStats]; * RCLK subroutine. Returns time left justified in L2, L3 GetTime: T ← (R400) + (30c); * Alto RTC PFetch1[MDS, lspL2]; * Fetch high half of clock lspL3 ← IP[RTCLow]c; T ← (SStkP&NStkp) xor (377c); Stkp ← lspL3, lspL3 ← T, NoRegILockOK; T ← (Stack) and not (77c); * fetch most of low clock Stkp ← lspL3, lspL3 ← T, NoRegILockOK, return; * * If we absolutely place one instruction in Timer.mc, we could * get the time instead by doing (saving net 5 instructions) * * loadpageExternal[XMiscPage]; * T ← (R400) + (30c), callExternal[MXRclkLoc]; * * RCLK -- store 32-bit processor clock @TOS @RCLK: loadpage[pgSetBase], opcode[167]; call[lspSetBase]; * Setup lspGenBr for store loadpage[pgStats]; call[GetTime]; * Get clock in L2,3 PStore2[lspGenBr, lspL2, 0], goto[nxiLBL]; * Store it :END[Ustats];