Google
 

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