Trailing-Edge
-
PDP-10 Archives
-
BB-BL69D-SB_1986
-
stats.mic
There are 2 other files named stats.mic in the archive. Click here to see a list.
.TOC "TRACKS SUPPORT"
;
; Everything in this file was once part of IO.MIC; it has been split
; out because it is never used in production microcode. At this
; writing (edit 434), none of this code will fit without removing
; or rewriting something else. Use this at your own risk!
;
; According to the University of Essex, when TRACKS is used with
; address break enabled, the monitor cannot disable address break
; for the actual execution of the instruction unless we include
; "ABORT INSTR" as part of the TRACKS loop. Accordingly, this is
; now done for all the different flavors of TRACKS. Thanks, folks.
;
;[317] During an attempt to implement uncounting of doubly counted op
; codes for the OP.CNT conditional, we learned: (1) EA
; calculation requires that VMA be initialized to the instruction
; location (usually PC) for the local/global stuff to work properly.
; Beware! (This is important if you try to do something after
; fetching an instruction but before you EA calc it.) (2) NICOND
; clears the trap enable flag. If INSTR.STAT is on, this will force
; the dispatch to the statistics logic without taking the trap,
; which will thus be lost and gone forever. This is a hardware bug,
; but it's rather impossible to ECO it at this late date.
;
;[321] The solution to this is to ignore the statistics flag if a trap
; is ready. See the block at NEXT for details. (It's not really
; a hardware bug after all.)
;
.IF/INSTR.STAT
=00
PIDX: CLR TRACKS EN,J/IFNOP ;TURN TRACKS OFF
.IF/TRACKS
ARX_SHIFT,ARL_BRL,ARR_0.S,J/PIDO2
.IFNOT/TRACKS
ARX_SHIFT,AR_2,J/PIDX1 ;[315] Turn statistics on
.ENDIF/TRACKS
=11 AR_TRX ;READ BACK POINTER
ARL_0.M ;GET INDEX PART
AR_AR+TRB,STORE,J/STMEM ;DONE WITH DATAI
.IFNOT/TRACKS
PIDX1: AR_ARX+AR*4 ;SAVE PAGE NUMBERS IN TRX REGISTERS
TRB_AR ;INITIAL GARBAGE HERE
=0* VMA_ARX,LOAD AR,PHYS REF,
CALL [XFERW] ;[434]
VMA_ARX+1,LOAD AR,PHYS REF ;[315] Must wait one cycle for
=0* TRX_AR,ARX_ARX+1,CALL [XFERW] ;parity check before writing AC
VMA_ARX+1,LOAD AR,PHYS REF ;[434]
=0* TRX1_AR,ARX_ARX+1,CALL [XFERW] ;[315] Note that this will always
VMA_ARX+1,LOAD AR,PHYS REF ;make it before AR is smashed
=0* TRX2_AR,CALL [XFERW] ;[434]
SET TRACKS EN ;[315] Might as well do this now
TRX3_AR,I FETCH,J/NOP ;SAVE TABLE PAGE #, TURN ON
.ENDIF/TRACKS
PIDO2: TRX_AR,AR_ARX ;SET UP INDEX
TRB_AR ;AND BASE
SET TRACKS EN,J/IFNOP ;TURN TRACKS ON
.IF/TRACKS
;HERE WHEN NICOND FINDS TRACKS ENABLED
=0
TRK1: TRX_AR,J/TRK2 ;PUT BACK UPDATED INDEX
AR_AR SWAP ;END OF BUFFER. RESET
AR_-AR,J/TRK1 ; ORIGINAL INDEX
TRK2: ARL_0.M
AR_AR+TRB ;ADDRESS TRACKS BUFFER
VMA_AR,PHYS REF ;TO MAKE MODEL A WORK
AR_PC,STORE,PHYS REF ; PUT PC THERE
MEM_AR,VMA/PC,CLR TRACKS EN ;PREVENT NICOND SEEING TRACKS...
ABORT INSTR ;[306] Make address break work by
; copying AD BRK CYC to AD FAIL INH
SET TRACKS EN ;...UNTIL NEXT TIME
DISP/NICOND,J/NEXT ;GO DO NEXT INSTR
.ENDIF/TRACKS
.IF/OP.CNT
;HERE WHEN NICOND FINDS OPCODE COUNTING ENABLED
; SKIP IF USER MODE
;[316] Make this register usage compatible with timing version below by
; making it use TRX2 (for exec mode counts pointer) and TRX3 (for user mode
; counts pointer) instead of TRX and TRX+1.
;[317] A massive attempt to uncount doubly counted instructions when an
; interrupt was detected has been backed off. See INSTR.STAT dispatch logic
; above for commentary.
;
=0
OPCT1: AR_TRX2,SKP AC REF,J/OPCT2 ;[316] TRX HAS PAGE # FOR EXEC TABLE
AR_TRX3,SKP AC REF ;[316] NEXT PAGE IS FOR USER
=0
OPCT2: AR_SHIFT,MQ_SHIFT, ;[317] Save VMA of increment
CLR TRACKS EN,J/OPCT3 ;OPCODE INDEXES INTO TABLE
ARX_FM(VMA),J/OPCT2 ;GET INSTR FROM FM
;
=0* ;[434]
OPCT3: VMA_AR,LOAD AR,PHYS REF, ;[306][434] GET TABLE ENTRY, make
CALL [XFERW] ; address break work
=0 BR/AR,AR_AR+1,STORE,CALL [TRKEN];ADD THIS OCCURANCE TO IT, keep old
DISP/NICOND ;DO INSTR IN ARX
;
; In an attempt to prevent an interrupt after counting an instruction,
; we now fake the second NICOND in line.
;
=0000 AR_BR,CLR TRACKS EN,J/OPFIX ;Some kind of odd condition.
=0010 AR_BR,CLR TRACKS EN,J/OPFIX ; Uncount the instruction
AR_BR,CLR TRACKS EN,J/OPFIX
AR_BR,CLR TRACKS EN,J/OPFIX
AR_BR,CLR TRACKS EN,J/OPFIX
AR_BR,CLR TRACKS EN,J/OPFIX
=1010 BRX/ARX,AR_ARX,SET ACCOUNT EN, ;The usual case
XR,EA MOD DISP,J/COMPEA
AR_BR,CLR TRACKS EN,J/OPFIX
=1110 GEN ARX,LOAD IR,#/0,J/XCTGO ;Instruction in registers
AR_BR,CLR TRACKS EN
;
=0
OPFIX: VMA_MQ,STORE,PHYS REF,CALL [TRKEN];[434] Restore old count
DISP/NICOND,J/NEXT ; and do it yet again
;
; Subroutine to wait for memory, set VMA to PC, and reenable TRACKS.
; Return 1. [434]
;
TRKEN: MEM_AR,VMA/PC ;[434]
SET TRACKS EN,RETURN [1] ;Turn TRACKS back on
.ENDIF/OP.CNT
.IF/OP.TIME
;HERE TO ADD UP TIME SPENT IN INSTR'S
OPTM0: SC_#,#/9.,SKP USER,J/OPTM1
=0
OPTM1: BR_AR LONG,AR_TRX2,SKP AC REF, ;INSTR IN ARX PAGE IN AR
J/OPTM2
BR_AR LONG,AR_TRX3,SKP AC REF, ;INSTR IN ARX PAGE IN AR
J/OPTM2
=0
OPTM2: AR_SHIFT,ABORT INSTR,J/OPTM3 ;[306] GENERATE ADDR TO INCREMENT
;NEXT GET ADDR FOR THIS
ARX_FM(VMA),J/OPTM2 ;GET NEXT INSTR FROM FM
OPTM3: VMA_AR,LOAD AR,UNCSH PHYS REF ;BUMP COUNT LOCATION
AR_MEM
AR_AR+1,STORE
MEM_AR,SKP USER
=0 AR_TRX,J/OPTM4
AR_TRX1
OPTM4: AR_SHIFT,ARX_TRB
TRB_AR ;SAVE NEXT LOC TO BUMP
RD+CLR PA ;TIME TO AR
MTR CTL/CLR PERF
VMA_ARX,LOAD ARX,UNCSH PHYS REF ;GET TABLE ENTRY
AR_AR-BR,ARL_0.S ;COMPENSATE TIME FOR THIS CODE
BR/AR,ARX_MEM,SKP AR18 ;IF THIS WAS AN ENABLED STATE,
=0 AR_ARX+BR,STORE ;WRITE IT BACK
MEM_AR,VMA/PC ;NOW SETUP NEXT INSTR AGAIN
ARX_BRX,SET TRK+PA EN ;RESTORE STATISTICS FLAGS
DISP/NICOND,J/NEXT
.ENDIF/OP.TIME
;THIS IS THE SECOND ORDER STATISTICS GATHERING CODE
.IFNOT/SO2.CNT
.IF/SO.CNT
;THIS IS NON DEBUGED CODE THAT IS IN A VERY PRIMATIVE STATE
;IT WAS ABANDONED BETWEEN EDITS AS THE MONITOR NEEDED SOMETHING
;SLIGHTLY DIFFERENT
;THIS IS CODE TO DO A SECOND ORDER STATISTIC IN THE SECOND 128K
;EACH ENTRY IS A HALF WORD
;THE LOW ORDER BIT OF <LAST OPCODE><THIS OPCODE> CONCATENATION
;DETERMINES WHICH HALFWORD IS INCREMENTED. OFF IS HIGH
;IF A HALFWORD OVERFLOWS THE CODE TURNS ITSELF OFF AND WRITES -1
;AT LOCATION 400000
;TRX HIDES THE LOCATION PRESENTED TRB THE LAST OPCODE
; THIS IS IN THE NEXT LOOP COMMENTED HERE FOR DOCUMENTATION
;TRK0: ARX_TRB,BRX/ARX,SKP AC REF,J/TRK1;GET PREV INSTR HIDE THIS ONE
=0
TRK1: AR_1,SC_#,#/9.,J/TRK2 ;SHIFT IN FIRST OPCODE
ARX_FM(VMA),AR_ARX ;GET THE INSTRUCTION FROM FM
BRX/ARX,AR_1,SC_#,#/9.,ARX_AR ; WHEN IT HIDES THERE
TRK2: AR_SHIFT,SC_#,#/8.,ARX_BRX ;SETUP TO DO THE NEXT OPCODE
AR_SHIFT,CLR TRACKS EN ;CONVIENT TO SHUT OFF TRACKS
VMA_AR,LOAD ARX,PHYS REF,AR_ARX ;LOW BIT OF INSTR WHERE CAN TEST
ARX_SHIFT,TRB_AR ;LOW BIT OF INSTR TO HIGH BIT
ARL_0.S,ARR_1S,SKP ARX0 ;SEE WHICH HALFWORD TO INC
; ALSO SETTING UP FOR TEST IN
; LOW INCREMENT
=0 ARL_1.M,ARR_0.M,J/TRK3 ;INC HIGH
ARX_MEM ;INC LOW
BR/AR,ARX_ARX+1,AR/ADX,STORE ;INCREMENT LOW HALF AND STORE IT
TEST AR.BR,SKP CRY0 ;USING AND-1 HACK TO TEST OVFLOW
=0 AR_0S,J/TRKLOS ;OVERFLOWED FIXUP TO LOSE
MEM_AR,ARX_BRX,VMA/PC,AR_BRX ;NO OVERFLOW GET OUT ALSO
TRKN1: SET TRACKS EN ; SAVE AWAY THIS OPCODE
TRKND: DISP/NICOND,J/NEXT ;AND DO NEXT INSTR
TRK3: ARX_MEM,BR/AR ;GET WORD TO INC
AR_ARX+BR,STORE,SKP CRY0 ;COMPUTE AND CHECK FOR OVERFLOW
=0 ARX_BRX,VMA/PC,MEM_AR,AR_BRX, ;SAVE AWAY THIS INSTR
J/TRKN1 ; AND GET OUT
AR_0.C,ARX_BRX,MEM_AR,J/TRKLOS ;SHUT DOWN TRACKS ON OVERFLOW
TRKLOS: AR_1,SC_#,#/17. ;WHEN LOSS PUT -1 IN 400000
AR_SHIFT
GEN AR,VMA/AD,PHYS REF ;SHUT OFF TRACKS AND QUIT
AR_TRB,STORE
MEM_AR,VMA/AD
J/TRKND
.ENDIF/SO.CNT
.IF/SO2.CNT
;THIS ONE DOES THE COUNTING IN 128K STARTING AT AN ADDRESS PRESENTED IT
;THIS IS CODE TO DO A SECOND ORDER STATISTIC IN THE SECOND 128K
;EACH ENTRY IS A HALF WORD
;THE LOW ORDER BIT OF <LAST OPCODE><THIS OPCODE> CONCATENATION
;DETERMINES WHICH HALFWORD IS INCREMENTED. OFF IS HIGH
;IF A HALFWORD OVERFLOWS THE CODE TURNS ITSELF OFF AND WRITES -1
;AT LOCATION PRESENTED
;TRX HIDES THE LOCATION PRESENTED TRB THE LAST OPCODE
; THIS IS IN THE NEXT LOOP COMMENTED HERE FOR DOCUMENTATION
;TRK0: ARX_TRB,BRX/ARX,SKP AC REF,J/TRK1;GET PREV INSTR HIDE THIS ONE
=0
TRK1: AR_0S,SC_#,#/9.,J/TRK2 ;SHIFT IN FIRST OPCODE
ARX_FM(VMA),AR_ARX ;GET THE INSTRUCTION FROM FM
BRX/ARX,AR_0S,SC_#,#/9.,ARX_AR ; WHEN IT HIDES THERE
TRK2: AR_SHIFT,SC_#,#/8.,ARX_BRX ;SETUP TO DO THE NEXT OPCODE
AR_SHIFT,CLR TRACKS EN ;CONVIENT TO SHUT OFF TRACKS
AR_AR+TRX ;BUMPS BY NUMBER FED IT
VMA_AR,LOAD ARX,PHYS REF,AR_ARX ;LOW BIT OF INSTR WHERE CAN TEST
ARX_SHIFT,TRB_AR ;LOW BIT OF INSTR TO HIGH BIT
ARL_0.S,ARR_1S,SKP ARX0 ;SEE WHICH HALFWORD TO INC
; ALSO SETTING UP FOR TEST IN
; LOW INCREMENT
=0 ARL_1.M,ARR_0.M,J/TRK3 ;INC HIGH
ARX_MEM,ABORT INSTR ;[306] INC LOW
BR/AR,ARX_ARX+1,AR/ADX,STORE ;INCREMENT LOW HALF AND STORE IT
TEST AR.BR,SKP CRY0 ;USING AND-1 HACK TO TEST OVFLOW
=0 AR_0S,J/TRKLOS ;OVERFLOWED FIXUP TO LOSE
MEM_AR,ARX_BRX,VMA/PC,AR_BRX ;NO OVERFLOW GET OUT ALSO
TRKN1: SET TRACKS EN ; SAVE AWAY THIS OPCODE
TRKND: DISP/NICOND,J/NEXT ;AND DO NEXT INSTR
TRK3: ARX_MEM,BR/AR,ABORT INSTR ;[306] GET WORD TO INC
AR_ARX+BR,STORE,SKP CRY0 ;COMPUTE AND CHECK FOR OVERFLOW
=0 ARX_BRX,VMA/PC,MEM_AR,AR_BRX, ;SAVE AWAY THIS INSTR
J/TRKN1 ; AND GET OUT
AR_0.C,ARX_BRX,MEM_AR,J/TRKLOS ;SHUT DOWN TRACKS ON OVERFLOW
TRKLOS: AR_TRX
GEN AR,VMA/AD,PHYS REF ;WRITE -1 IN PRESENTED LOCATION
AR_TRB,STORE
MEM_AR,VMA/PC ;NEED AN INSTRUCTION TO GIVE
J/TRKND ;TIME TO NICOND AFTER VMA/PC
.ENDIF/SO2.CNT
.ENDIF/INSTR.STAT