; This file contains three programs that test the speed ; of PDP-11 machine instructions. To use, they will ; have to be split out with the editor as the assembler ; will stop when it sees the ".END" statement of the ; first program. There should be an asociated SPDCPU.DOC ; file which explains how they work. .TITLE S1D .IDENT /V1.55/ .ENABLE LC ; This program is used to test the speed of instructions. ; ; 08-Mar-85 B. Z. Lederman .MCALL QIOW$S, EXIT$S, ENAR$S, SREX$S, GTIM$S $NREP == 31250. ; number of instructions wanted at one pass $NREAL = <$NREP - 3.> ; (minus loop instructions) $NPAS == 320. ; number of passes AC0 = %0 ; standard assignments for Floating AC1 = %1 ; Point registers AC2 = %2 .PSECT ALL, I, RW IOSB:: .BLKW 2 ; I/O status block STRTIM: .BLKW 8. ; for starting time ENDTIM: .BLKW 8. ; for ending time INTRNL: .WORD 0 ; flag for aborts, etc. MNEADR: .WORD MNTAB ; starting point for mnemonics TABADR: .WORD TABLE ; starting point for instructions .NLIST BEX ; All messages must be the same length! ERMS1:: .ASCII \ Instruction \ ERMS2: .ASCII \ started \ ERMS3: .ASCII \ ended \ ERMS4: .ASCII \ Instructions per loop. \ ERMS5: .ASCII \ Passes through loop. \ ERMS7: .ASCII \Enable AST's directive rejected.\ ERMS10: .ASCII \Program has been aborted. \ STABUF: .ASCII \Program ends. \ STALEN = . - STABUF MNTAB:: ; Mnemonics must be in the same order .ASCII /TST / ; as the instructions, the quantities .ASCII /ROR / ; of each must be the same, and they .ASCII /SWAB / ; must all be 6 characters long .ASCII /MOV / .ASCII /MOVB / .ASCII /CMP / .ASCII /ADD / .ASCII /BIT / .ASCII /TST 1 / .ASCII /CMP 1 / .ASCII /MOV 42/ .ASCII /MOVB42/ .ASCII /MUL / .ASCII /DIV / .ASCII /BEQ / .ASCII /BNE / .ASCII /CCC / .ASCII /NOP / .ASCII /JSR 2 / .ASCII /SETF / .ASCII /MULF / .ASCII /ADDF / .ASCII /NEGF / .ASCII /ABSF / .ASCII /LDF / .ASCII /LDF 1 / .ASCII /LDCIF / .ASCII /LDCIF1/ .ASCII /STCFI / .ASCII /STCFI1/ .ASCII /SETD / .ASCII /MULD / .ASCII /ADDD / .ASCII /NEGD / .ASCII /ABSD / .ASCII /Last / .EVEN .LIST BEX ; List of instructions TABLE:: TST R0 ; TeST instruction ROR R0 ; Rotate Right SWAB R0 ; Swap Bytes MOV R0, R1 ; MOVe instruction MOVB R0, R1 ; move byte CMP R0, R3 ; CoMPare instruction ADD R0, R1 ; Add BIT R0, R1 ; bit test TST (R0) ; TeST addressing mode 1 CMP (R0), (R3) ; CoMPare mode 1 MOV -(SP), (SP)+ ; move mode 4 and 2 MOVB -(SP), (SP)+ ; move byte mode 4 and 2 MUL R1, R0 ; multiply DIV R1, R0 ; divide BEQ 900$ ; Branch if Equal 900$: BNE 910$ ; Branch if Not Equal 910$: CCC ; clear all condition codes NOP ; No OPeration JSR PC, (R2) ; Jump to SubRoutine SETF ; set FPP to floating single MULF AC2, AC0 ; multiply floating ADDF AC0, AC1 ; add floating NEGF AC0 ; negate floating ABSF AC0 ; make absolute floating LDF R0, AC0 ; load floating mode 0 LDF (R3), AC0 ; load floating mode 1 LDCIF R0, AC0 ; load and convert LDCIF (R3), AC0 ; load and convert mode 1 STCFI AC0, R0 ; store and convert STCFI AC0, (R3) ; store and convert mode 1 SETD ; set FPP to floating double MULD AC2, AC0 ; multiply floating ADDD AC0, AC1 ; add floating NEGD AC0 ; negate floating ABSD AC0 ; make absolute floating HALT ; won't actually do this RETURN: RTS PC ; need this for JSR test .PAGE START:: SREX$S #ABOAST ; specify abort AST point ENAR$S ; AST's should be enabled already BCC 10$ ; if no error, continue CMP #IE.ITS, $DSW ; were AST's already enabled? BEQ 10$ ; branch if yes, no real error MOV #ERMS7, R4 CALL ERMSG JMP EXIT 10$: MOV #ERMS4, R0 ; address of first information message MOV R0, R4 ; copy for ERMSG routine MOV #$NREP, R1 ; number of instructions per loop CLR R2 ; suppress leading zeroes CALL $CBDMG ; convert to ASCII CALL ERMSG ; write it out MOV #ERMS5, R0 ; repeat for second message MOV R0, R4 MOV #$NPAS, R1 CLR R2 CALL $CBDMG CALL ERMSG BEGIN:: MOV #ERMS1, R1 ; get start of message MOV R1, R4 ; copy for ERMSG routine MOV MNEADR, R5 ; address of mnemonic table MOVB (R5)+, (R1)+ ; move mnemonic into message MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOV R5, MNEADR ; save address for next pass CALL ERMSG ; indicate instruction under test MOV TABADR, R5 ; address of instruction table MOV (R5)+, R0 ; get instruction BNE 15$ ; branch if O.K. instruction JMP EXIT ; quit here if HALT instruction 15$: MOV R5, TABADR ; save address for next pass MOV #$NREAL, R4 ; number of repititions MOV #ISTRT, R3 ; address of instruction space 20$: MOV R0, (R3)+ ; move in instruction SOB R4, 20$ ; continue until all loaded MOV #$NPAS, R4 ; number of times through the loop LDF #1, AC0 ; load floating point for some LDF #1, AC2 ; tests. MOV #IOSB, R0 ; need this for some modes MOV R0, R3 ; this also MOV #RETURN, R2 ; for subroutine test GTIM$S #STRTIM ; time test starts ISTRT:: .REPT $NREAL ; this number of instructions NOP ; filled with real instructions above .ENDR DEC R4 ; count number of passes BLE TIMES ; quit if enough passes JMP ISTRT ; otherwise continue TIMES:: GTIM$S #ENDTIM ; time test ends MOV #ERMS2, R0 MOV #STRTIM, R1 CALL WRITIM MOV #ERMS3, R0 MOV #ENDTIM, R1 CALL WRITIM TST INTRNL ; are we in abort AST? BNE EXIT ; quit if in abort AST JMP BEGIN ; otherwise go on EXIT:: MOV #STABUF, R4 CALL ERMSG ; write out byebye message EXIT$S ; byebye WRITIM: MOV R0, R4 ; copy address for ERMSG CALL $DAT ; convert date MOVB #40, (R0)+ ; blank space MOV #5, R2 ; convert all times CALL $TIM ; convert time CALL ERMSG ; write it out RETURN ERMSG:: QIOW$S #IO.WLB, #5, #5,,,, ; Print error message RETURN ABOAST:: ADD (SP), SP ; clean up stack DEC INTRNL ; mark as abort JMP TIMES ; write out times .END START ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .TITLE S2D .IDENT /V1.5/ .ENABLE LC ; This program is used to test the speed of instructions. ; ; 08-Mar-85 B. Z. Lederman ; 12-Mar-85 Double word instructions .MCALL QIOW$S, EXIT$S, ENAR$S, SREX$S, GTIM$S $NREP == 15625. ; number of instructions wanted at one pass $NREAL = <$NREP - 3.> ; (minus loop instructions) $NPAS == 640. ; number of passes AC0 = %0 ; Standard Floating Point registers AC1 = %1 AC2 = %2 .PSECT ALL, I, RW IOSB:: .BLKW 2 ; I/O status block STRTIM: .BLKW 8. ; for starting time ENDTIM: .BLKW 8. ; for ending time INTRNL: .WORD 0 ; flag for aborts, etc. MNEADR: .WORD MNTAB ; starting point for mnemonics TABADR: .WORD TABLE ; starting point for instructions .NLIST BEX ; All messages must be the same length ! ERMS1:: .ASCII \ Instruction \ ERMS2: .ASCII \ started \ ERMS3: .ASCII \ ended \ ERMS4: .ASCII \ Instructions per loop. \ ERMS5: .ASCII \ Passes through loop. \ ERMS7: .ASCII \Enable AST's directive rejected.\ ERMS10: .ASCII \Program has been aborted. \ STABUF: .ASCII \Program ends. \ STALEN = . - STABUF MNTAB:: .ASCII /MOV 2 / ; The mnemonics must all be 6 characters .ASCII /ASHC / ; long, they must be in the same order .ASCII /MOV 3 / ; as the instructions, and there must .ASCII /TST 3 / ; be the same quantities of each. .ASCII /SWAB 3/ .ASCII /MOV 6 / .ASCII /TST I / .ASCII /TST 6 / .ASCII /MOV 62/ .ASCII /SUBRTN/ .ASCII /LDF 2 / .ASCII /LDF 3 / .ASCII /STF 3/ .ASCII /CMPF 3/ .ASCII /LDCIF2/ .ASCII /LDCIF3/ .ASCII /STCFI3/ .ASCII /Last / .EVEN .LIST BEX ; Instruction table. TABLE:: MOV #1, R0 ; MOVe mode 2 ASHC #1, R0 ; arithmatic shift combined MOV @#IOSB, R1 ; move mode 3 TST @#IOSB ; test mode 3 SWAB @#IOSB ; swap bytes mode 3 MOV IOSB, R1 ; move mode 6 TST 2(R0) ; TeST addressing mode 6 TST IOSB ; test mode 6 MOV 2(R0), (R3) ; move mode 6 and 2 JSR PC, @#RETURN ; call and return from subroutine LDF #1, AC0 ; load floating mode 2 LDF @#IOSB, AC2 ; load floating mode 3 STF AC0, @#IOSB ; store floating CMPF @#IOSB, AC0 ; compare floating LDCIF #1, AC0 ; load and convert LDCIF @#IOSB, AC0 ; load and convert mode 3 STCFI AC0, @#IOSB ; store and convert mode 3 HALT ; won't actually do this HALT RETURN: RTS PC ; for subroutine testing .PAGE START:: SREX$S #ABOAST ; specify abort AST point ENAR$S ; AST's should be enabled already BCC 10$ ; if no error, continue CMP #IE.ITS, $DSW ; were AST's already enabled? BEQ 10$ ; branch if yes, no real error MOV #ERMS7, R4 CALL ERMSG JMP EXIT 10$: MOV #ERMS4, R0 ; address of first information message MOV R0, R4 ; copy for ERMSG routine MOV #$NREP, R1 ; number of instructions per loop CLR R2 ; suppress leading zeroes CALL $CBDMG ; convert to ASCII CALL ERMSG ; write it out MOV #ERMS5, R0 ; repeat for second message MOV R0, R4 MOV #$NPAS, R1 CLR R2 CALL $CBDMG CALL ERMSG BEGIN:: MOV #ERMS1, R1 ; get start of message MOV R1, R4 ; copy for ERMSG routine MOV MNEADR, R5 ; address of mnemonic table MOVB (R5)+, (R1)+ ; move mnemonic into message MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOV R5, MNEADR ; save address for next pass CALL ERMSG ; indicate instruction under test MOV TABADR, R5 ; address of instruction table MOV (R5)+, R0 ; get first word of instruction BNE 15$ ; branch if O.K. instruction JMP EXIT ; quit here if HALT instruction 15$: MOV (R5)+, R1 ; second word of instruction BNE 17$ ; branch if O.K. instruction JMP EXIT ; quit if HALT 17$: MOV R5, TABADR ; save address for next pass MOV #$NREAL, R4 ; number of repititions MOV #ISTRT, R3 ; address of instruction space 20$: MOV R0, (R3)+ ; move in first word of instruction MOV R1, (R3)+ ; second word of instruction SOB R4, 20$ ; continue until all loaded MOV #$NPAS, R4 ; number of times through the loop LDF #1, AC0 ; load floating point for some LDF #1, AC2 ; tests. MOV #IOSB, R0 ; need this for some modes MOV R0, R3 ; this also GTIM$S #STRTIM ; time test starts ISTRT:: .REPT $NREAL ; this number of instructions NOP ; filled with real instructions above NOP .ENDR DEC R4 ; count number of passes BLE TIMES ; quit if enough passes JMP ISTRT ; otherwise continue TIMES:: GTIM$S #ENDTIM ; time test ends MOV #ERMS2, R0 MOV #STRTIM, R1 CALL WRITIM MOV #ERMS3, R0 MOV #ENDTIM, R1 CALL WRITIM TST INTRNL ; are we in abort AST? BNE EXIT ; quit if in abort AST JMP BEGIN ; otherwise go on EXIT:: MOV #STABUF, R4 CALL ERMSG ; write out byebye message EXIT$S ; byebye WRITIM: MOV R0, R4 ; copy address for ERMSG CALL $DAT ; convert date MOVB #40, (R0)+ ; blank space MOV #5, R2 ; convert all times CALL $TIM ; convert time CALL ERMSG ; write it out RETURN ERMSG:: QIOW$S #IO.WLB, #5, #5,,,, ; Print error message RETURN ABOAST:: ADD (SP), SP ; clean up stack DEC INTRNL ; mark as abort JMP TIMES ; write out times .END START ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .TITLE S3D .IDENT /V1.3/ .ENABLE LC ; This program is used to test the speed of instructions. ; ; 13-Mar-85 B. Z. Lederman .MCALL QIOW$S, EXIT$S, ENAR$S, SREX$S, GTIM$S $NREP == 320. ; number of instructions wanted at one pass $NREAL = <$NREP - 3.> ; (minus loop instructions) $NPAS == 31250. ; number of passes ;AC0 = %0 ; Standard Floating Point registers ;AC1 = %1 ;AC2 = %2 .PSECT ALL, I, RW IOSB:: .BLKW 2 ; I/O status block STRTIM: .BLKW 8. ; for starting time ENDTIM: .BLKW 8. ; for ending time INTRNL: .WORD 0 ; flag for aborts, etc. MNEADR:: .WORD MNTAB ; starting point for mnemonics TABADR:: .WORD TABLE ; starting point for instructions .NLIST BEX ERMS1:: .ASCII \ Instruction \ ERMS2: .ASCII \ started \ ERMS3: .ASCII \ ended \ ERMS4: .ASCII \ Instructions per loop. \ ERMS5: .ASCII \ Passes through loop. \ ERMS7: .ASCII \Enable AST's directive rejected.\ ERMS10: .ASCII \Program has been aborted. \ STABUF: .ASCII \Program ends. \ STALEN = . - STABUF MNTAB:: .ASCII /MOV23P/ .ASCII /MOV33P/ .ASCII /MOV66 / .ASCII /ADD23P/ .ASCII /ADD33P/ .ASCII /ADD66 / .ASCII /Last / .EVEN .LIST BEX TABLE:: MOV #1, @#IOSB ; MOVe mode 2, 3 MOV @#IOSB, @#ENDWRD ; move mode 3 and 3 MOV 4(R0), 2(R3) ; move mode 6 and 6 ADD #1, @#ENDWRD ADD @#IOSB, @#ENDWRD ADD 4(R0), 2(R3) HALT ; won't actually do this HALT HALT .PAGE START:: SREX$S #ABOAST ; specify abort AST point ENAR$S ; AST's should be enabled already BCC 10$ ; if no error, continue CMP #IE.ITS, $DSW ; were AST's already enabled? BEQ 10$ ; branch if yes, no real error MOV #ERMS7, R4 CALL ERMSG JMP EXIT 10$: MOV #ERMS4, R0 ; address of first information message MOV R0, R4 ; copy for ERMSG routine MOV #$NREP, R1 ; number of instructions per loop CLR R2 ; suppress leading zeroes CALL $CBDMG ; convert to ASCII CALL ERMSG ; write it out MOV #ERMS5, R0 ; repeat for second message MOV R0, R4 MOV #$NPAS, R1 CLR R2 CALL $CBDMG CALL ERMSG BEGIN:: MOV #ERMS1, R1 ; get start of message MOV R1, R4 ; copy for ERMSG routine MOV MNEADR, R5 ; address of mnemonic table MOVB (R5)+, (R1)+ ; move mnemonic into message MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOVB (R5)+, (R1)+ MOV R5, MNEADR ; save address for next pass CALL ERMSG ; indicate instruction under test MOV TABADR, R5 ; address of instruction table MOV (R5)+, R0 ; get first word of instruction BNE 15$ ; branch if O.K. instruction JMP EXIT ; quit here if HALT instruction 15$: MOV (R5)+, R1 ; second word of instruction BNE 16$ ; branch if O.K. instruction JMP EXIT ; quit if HALT 16$: MOV (R5)+, R2 ; third word of instruction BNE 17$ ; branch if O.K. instruction JMP EXIT ; quit if HALT 17$: MOV R5, TABADR ; save address for next pass MOV #$NREAL, R4 ; number of repititions MOV #ISTRT, R3 ; address of instruction space 20$: MOV R0, (R3)+ ; move in first word of instruction MOV R1, (R3)+ ; second word of instruction MOV R2, (R3)+ ; third word of instruction SOB R4, 20$ ; continue until all loaded MOV #$NPAS, R4 ; number of times through the loop ; LDF #1, AC0 ; load floating point for some ; LDF #1, AC2 ; tests. MOV #IOSB, R0 ; need this for some modes MOV R0, R3 ; this also GTIM$S #STRTIM ; time test starts ISTRT:: .REPT $NREAL ; this number of instructions NOP ; filled with real instructions above NOP NOP .ENDR DEC R4 ; count number of passes BLE TIMES ; quit if enough passes JMP ISTRT ; otherwise continue TIMES:: GTIM$S #ENDTIM ; time test ends MOV #ERMS2, R0 MOV #STRTIM, R1 CALL WRITIM MOV #ERMS3, R0 MOV #ENDTIM, R1 CALL WRITIM TST INTRNL ; are we in abort AST? BNE EXIT ; quit if in abort AST JMP BEGIN ; otherwise go on EXIT:: MOV #STABUF, R4 CALL ERMSG ; write out byebye message EXIT$S ; byebye WRITIM: MOV R0, R4 ; copy address for ERMSG CALL $DAT ; convert date MOVB #40, (R0)+ ; blank space MOV #5, R2 ; convert all times CALL $TIM ; convert time CALL ERMSG ; write it out RETURN ERMSG:: QIOW$S #IO.WLB, #5, #5,,,, ; Print error message RETURN ABOAST:: ADD (SP), SP ; clean up stack DEC INTRNL ; mark as abort JMP TIMES ; write out times ENDWRD:: .BLKW 2 ; data at other end of program .END START