home *** CD-ROM | disk | FTP | other *** search
- REM> armmips
- version$="1.15"
- *Key1 OSCLI("MemoryI "+STR$~code_start+" "+STR$~code_end)|M
- copyright$="(c) 1993 Phill Rogers":filename$="mips"
- loopsize%=2:useram%=FALSE:maxcount%=2<<24
- pwp=12:wsp=12:sp=13:link=14:pc=15:mode_USR=0:mode_FIQ=1:mode_IRQ=2:mode_SVC=3
- flag_F=1<<26:flag_I=1<<27:flag_V=1<<28:flag_C=1<<29:flag_Z=1<<30:flag_N=1<<31
- SYS "OS_SWINumberFromString",, "OS_WriteI" TO OS_WriteI
- SYS "OS_SWINumberFromString",,"XOS_WriteI" TO XOS_WriteI
- MODE 12:PRINT'"ARM pipelining demo."
- PRINT "Count up to what (default is ";maxcount%;") ";
- INPUT maxcount%
- IF maxcount%=0 THEN maxcount%=2<<24
- INPUT "Count in memory rather than register ";yn$
- IF LEFT$(yn$,1)="y" OR LEFT$(yn$,1)="Y" THEN useram%=TRUE
- IF NOT useram% THEN
- REPEAT
- PRINT "Loopsize determines pipeline efficiency."
- PRINT "Too small and the pileline gets interrupted too often."
- PRINT "Too large wastes the cache, which the OS still uses while this is running."
- PRINT "Best seems to be about 128, the default."
- INPUT "What size loop ";loopsize%
- IF loopsize%=0 THEN loopsize%=128
- UNTIL loopsize%>1 AND loopsize%<maxcount%
- ENDIF
- size%=512+loopsize%
- DIM code% size%
- FOR clear%=0 TO size% STEP 4:code%!clear%=0:NEXT
- FOR pass%=0 TO 2 STEP 2
- P%=code%
- PROC_assm
- NEXT
- REM SYS "OS_File",10,filename$,&FFC,,code_start,code_end
- cs%=USR code_start
- PRINT'"Code length is : "+STR$(code_end-code_start)+" (&"+STR$~(code_end-code_start)+"hex) bytes."
- PRINT "Loopsize ";loopsize%;" instructions."
- PRINT "Itterations ";maxcount% / loopsize%;" times."
- PRINT "Total of ";maxcount%;" instructions."
- PRINT "Executed in ";cs%;" centi-seconds."
- PRINT "A rating of ";maxcount% / (cs% * 10000);" MIPS"
- END
- :
- DEF PROC_assm:[OPT pass%:ALIGN:.code_start
- .mips_c ;MIPS
- STMFD sp !,{R1-R4,link}
- SWI "XCache_Flush" ;comment this out if no ARM3
- ADR R4,mips_maxcount
- LDR R4,[R4] ;initialize REGISTER counter
- SUB R4,R4,#3 ;atleast two instuctions lost in timing admin
- ADR R3,mips_counter
- STR R4,[R3] ;initialize RAM counter
- MOV R0,#19 ;wait for video sync
- SWI "OS_Byte" ; to get interrups consistent
- SWINV "OS_IntOff" ;only jokeing, clock wouldnt work!
- SWI "OS_ReadMonotonicTime"
- MOV R1,R0
- .mips_loop
- FN_loopin(loopsize%, useram%) ;number of instructions in the timmed loop
- BGT mips_loop
- SWI "OS_ReadMonotonicTime"
- SWINV "OS_IntOn" ;only jokeing, clock wouldnt work!
- SUB R0,R0,R1 ;save time lapsed into r4 for later
- FN_print(FALSE) ;optionally print
- LDMFD sp !,{R1-R4,pc} ;exit with answer in r0
- .mips_maxcount
- EQUD maxcount%
- .mips_counter
- EQUD 0
- .mips_buffer
- EQUD 0:EQUD 0
- ALIGN:.code_end:]:ENDPROC
- :
- DEF FN_print(yn%)
- IF yn% THEN
- [ OPT pass%
- MOV R4,R0
- ADR R1,mips_buffer ; point to buffer
- MOV R2,#8 ; length of buffer
- SWI "OS_BinaryToDecimal" ;convert to ascii
- MOV R0,#0 ;zero terminator required
- ADD R2,R2,R1 ; r2 = no of chars used
- ADD R2,R2,#1 ; after the end of the text
- STR R0,[R2] ; put the zero terminator
- MOV R0,R1 ;point r0 to text for printing
- SWI "OS_Write0" ;print it out
- SWI "OS_NewLine" ;will change this a bit later
- MOV R0,R4 ;exit with answer in r0
- ]
- ENDIF
- =0
- :
- DEF FN_loopin(loopsize%, ram%)
- LOCAL tmp%
- IF ram%=TRUE THEN
- [ OPT pass%
- LDR R4,[R3]
- SUBS R4,R4,#4 ;decrement four times because other instructions can't
- STR R4,[R3]
- ]
- ELSE
- IF loopsize%>3 THEN
- FOR tmp%=3 TO loopsize%
- [ OPT pass%
- SUBS R4,R4,#1 ;each insr. does itsown decrement
- ]
- NEXT
- ENDIF
- IF loopsize%=3 THEN
- [ OPT pass%
- SUB R4,R4,#3 ;decrement thrice because next two instructions can't
- CMP R4,#0 ;this is what the C compiler writes (decrement then compare)
- ]
- ELSE
- [ OPT pass%
- SUBS R4,R4,#2 ;decrement twice because next instruction can't
- ]
- ENDIF
- ENDIF
- =0
-