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