mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-29 03:56:15 +00:00
829 lines
32 KiB
Plaintext
829 lines
32 KiB
Plaintext
Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx
|
|
Inlined call main::$0 = call toD018 SCREEN_COPY CHARSET
|
|
|
|
CONTROL FLOW GRAPH SSA
|
|
|
|
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
|
memcpy: scope:[memcpy] from main::@1 main::@2
|
|
memcpy::num#2 = phi( main::@1/memcpy::num#0, main::@2/memcpy::num#1 )
|
|
memcpy::destination#2 = phi( main::@1/memcpy::destination#0, main::@2/memcpy::destination#1 )
|
|
memcpy::source#2 = phi( main::@1/memcpy::source#0, main::@2/memcpy::source#1 )
|
|
memcpy::src#0 = ((byte*)) memcpy::source#2
|
|
memcpy::dst#0 = ((byte*)) memcpy::destination#2
|
|
memcpy::$2 = (byte*)memcpy::source#2
|
|
memcpy::$0 = memcpy::$2 + memcpy::num#2
|
|
memcpy::src_end#0 = memcpy::$0
|
|
to:memcpy::@1
|
|
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
|
|
memcpy::destination#4 = phi( memcpy/memcpy::destination#2, memcpy::@2/memcpy::destination#5 )
|
|
memcpy::dst#3 = phi( memcpy/memcpy::dst#0, memcpy::@2/memcpy::dst#1 )
|
|
memcpy::src_end#1 = phi( memcpy/memcpy::src_end#0, memcpy::@2/memcpy::src_end#2 )
|
|
memcpy::src#2 = phi( memcpy/memcpy::src#0, memcpy::@2/memcpy::src#1 )
|
|
memcpy::$1 = memcpy::src#2 != memcpy::src_end#1
|
|
if(memcpy::$1) goto memcpy::@2
|
|
to:memcpy::@3
|
|
memcpy::@2: scope:[memcpy] from memcpy::@1
|
|
memcpy::destination#5 = phi( memcpy::@1/memcpy::destination#4 )
|
|
memcpy::src_end#2 = phi( memcpy::@1/memcpy::src_end#1 )
|
|
memcpy::dst#2 = phi( memcpy::@1/memcpy::dst#3 )
|
|
memcpy::src#3 = phi( memcpy::@1/memcpy::src#2 )
|
|
*memcpy::dst#2 = *memcpy::src#3
|
|
memcpy::dst#1 = ++ memcpy::dst#2
|
|
memcpy::src#1 = ++ memcpy::src#3
|
|
to:memcpy::@1
|
|
memcpy::@3: scope:[memcpy] from memcpy::@1
|
|
memcpy::destination#3 = phi( memcpy::@1/memcpy::destination#4 )
|
|
memcpy::return#0 = memcpy::destination#3
|
|
to:memcpy::@return
|
|
memcpy::@return: scope:[memcpy] from memcpy::@3
|
|
memcpy::return#4 = phi( memcpy::@3/memcpy::return#0 )
|
|
memcpy::return#1 = memcpy::return#4
|
|
return
|
|
to:@return
|
|
|
|
void main()
|
|
main: scope:[main] from __start
|
|
main::toD0181_screen#0 = SCREEN_COPY
|
|
main::toD0181_gfx#0 = CHARSET
|
|
to:main::toD0181
|
|
main::toD0181: scope:[main] from main
|
|
main::toD0181_gfx#1 = phi( main/main::toD0181_gfx#0 )
|
|
main::toD0181_screen#1 = phi( main/main::toD0181_screen#0 )
|
|
main::toD0181_$7 = (word)main::toD0181_screen#1
|
|
main::toD0181_$0 = main::toD0181_$7 & $3fff
|
|
main::toD0181_$1 = main::toD0181_$0 * 4
|
|
main::toD0181_$2 = > main::toD0181_$1
|
|
main::toD0181_$3 = > (word)main::toD0181_gfx#1
|
|
main::toD0181_$4 = main::toD0181_$3 / 4
|
|
main::toD0181_$5 = main::toD0181_$4 & $f
|
|
main::toD0181_$6 = main::toD0181_$2 | main::toD0181_$5
|
|
main::toD0181_return#0 = main::toD0181_$6
|
|
to:main::toD0181_@return
|
|
main::toD0181_@return: scope:[main] from main::toD0181
|
|
main::toD0181_return#2 = phi( main::toD0181/main::toD0181_return#0 )
|
|
main::toD0181_return#1 = main::toD0181_return#2
|
|
to:main::@1
|
|
main::@1: scope:[main] from main::toD0181_@return
|
|
main::toD0181_return#3 = phi( main::toD0181_@return/main::toD0181_return#1 )
|
|
main::$0 = main::toD0181_return#3
|
|
*D018 = main::$0
|
|
memcpy::destination#0 = (void*)SCREEN_COPY
|
|
memcpy::source#0 = (void*)SCREEN
|
|
memcpy::num#0 = $400
|
|
call memcpy
|
|
memcpy::return#2 = memcpy::return#1
|
|
to:main::@2
|
|
main::@2: scope:[main] from main::@1
|
|
asm { sei }
|
|
*PROCPORT = PROCPORT_RAM_CHARROM
|
|
memcpy::destination#1 = (void*)CHARSET
|
|
memcpy::source#1 = (void*)CHARGEN
|
|
memcpy::num#1 = $800
|
|
call memcpy
|
|
memcpy::return#3 = memcpy::return#1
|
|
to:main::@3
|
|
main::@3: scope:[main] from main::@2
|
|
*PROCPORT = PROCPORT_BASIC_KERNEL_IO
|
|
asm { cli }
|
|
to:main::@return
|
|
main::@return: scope:[main] from main::@3
|
|
return
|
|
to:@return
|
|
|
|
void __start()
|
|
__start: scope:[__start] from
|
|
call main
|
|
to:__start::@1
|
|
__start::@1: scope:[__start] from __start
|
|
to:__start::@return
|
|
__start::@return: scope:[__start] from __start::@1
|
|
return
|
|
to:@return
|
|
|
|
SYMBOL TABLE SSA
|
|
const nomodify byte* CHARGEN = (byte*)$d000
|
|
const nomodify byte* CHARSET = (byte*)$2000
|
|
const nomodify byte* D018 = (byte*)$d018
|
|
const nomodify byte* PROCPORT = (byte*)1
|
|
const nomodify byte PROCPORT_BASIC_KERNEL_IO = 7
|
|
const nomodify byte PROCPORT_RAM_CHARROM = 1
|
|
const nomodify byte* SCREEN = (byte*)$400
|
|
const nomodify byte* SCREEN_COPY = (byte*)$2400
|
|
void __start()
|
|
void main()
|
|
byte~ main::$0
|
|
number~ main::toD0181_$0
|
|
number~ main::toD0181_$1
|
|
number~ main::toD0181_$2
|
|
byte~ main::toD0181_$3
|
|
number~ main::toD0181_$4
|
|
number~ main::toD0181_$5
|
|
number~ main::toD0181_$6
|
|
word~ main::toD0181_$7
|
|
byte* main::toD0181_gfx
|
|
byte* main::toD0181_gfx#0
|
|
byte* main::toD0181_gfx#1
|
|
byte main::toD0181_return
|
|
byte main::toD0181_return#0
|
|
byte main::toD0181_return#1
|
|
byte main::toD0181_return#2
|
|
byte main::toD0181_return#3
|
|
byte* main::toD0181_screen
|
|
byte* main::toD0181_screen#0
|
|
byte* main::toD0181_screen#1
|
|
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
|
byte*~ memcpy::$0
|
|
bool~ memcpy::$1
|
|
byte*~ memcpy::$2
|
|
void* memcpy::destination
|
|
void* memcpy::destination#0
|
|
void* memcpy::destination#1
|
|
void* memcpy::destination#2
|
|
void* memcpy::destination#3
|
|
void* memcpy::destination#4
|
|
void* memcpy::destination#5
|
|
byte* memcpy::dst
|
|
byte* memcpy::dst#0
|
|
byte* memcpy::dst#1
|
|
byte* memcpy::dst#2
|
|
byte* memcpy::dst#3
|
|
word memcpy::num
|
|
word memcpy::num#0
|
|
word memcpy::num#1
|
|
word memcpy::num#2
|
|
void* memcpy::return
|
|
void* memcpy::return#0
|
|
void* memcpy::return#1
|
|
void* memcpy::return#2
|
|
void* memcpy::return#3
|
|
void* memcpy::return#4
|
|
void* memcpy::source
|
|
void* memcpy::source#0
|
|
void* memcpy::source#1
|
|
void* memcpy::source#2
|
|
byte* memcpy::src
|
|
byte* memcpy::src#0
|
|
byte* memcpy::src#1
|
|
byte* memcpy::src#2
|
|
byte* memcpy::src#3
|
|
byte* memcpy::src_end
|
|
byte* memcpy::src_end#0
|
|
byte* memcpy::src_end#1
|
|
byte* memcpy::src_end#2
|
|
|
|
Adding number conversion cast (unumber) $3fff in main::toD0181_$0 = main::toD0181_$7 & $3fff
|
|
Adding number conversion cast (unumber) main::toD0181_$0 in main::toD0181_$0 = main::toD0181_$7 & (unumber)$3fff
|
|
Adding number conversion cast (unumber) 4 in main::toD0181_$1 = main::toD0181_$0 * 4
|
|
Adding number conversion cast (unumber) main::toD0181_$1 in main::toD0181_$1 = main::toD0181_$0 * (unumber)4
|
|
Adding number conversion cast (unumber) main::toD0181_$2 in main::toD0181_$2 = > main::toD0181_$1
|
|
Adding number conversion cast (unumber) 4 in main::toD0181_$4 = main::toD0181_$3 / 4
|
|
Adding number conversion cast (unumber) main::toD0181_$4 in main::toD0181_$4 = main::toD0181_$3 / (unumber)4
|
|
Adding number conversion cast (unumber) $f in main::toD0181_$5 = main::toD0181_$4 & $f
|
|
Adding number conversion cast (unumber) main::toD0181_$5 in main::toD0181_$5 = main::toD0181_$4 & (unumber)$f
|
|
Adding number conversion cast (unumber) main::toD0181_$6 in main::toD0181_$6 = main::toD0181_$2 | main::toD0181_$5
|
|
Adding number conversion cast (unumber) $400 in memcpy::num#0 = $400
|
|
Adding number conversion cast (unumber) $800 in memcpy::num#1 = $800
|
|
Successful SSA optimization PassNAddNumberTypeConversions
|
|
Inlining cast memcpy::src#0 = (byte*)memcpy::source#2
|
|
Inlining cast memcpy::dst#0 = (byte*)memcpy::destination#2
|
|
Inlining cast memcpy::num#0 = (unumber)$400
|
|
Inlining cast memcpy::num#1 = (unumber)$800
|
|
Successful SSA optimization Pass2InlineCast
|
|
Simplifying constant pointer cast (byte*) 53272
|
|
Simplifying constant pointer cast (byte*) 1
|
|
Simplifying constant pointer cast (byte*) 53248
|
|
Simplifying constant pointer cast (byte*) 8192
|
|
Simplifying constant pointer cast (byte*) 1024
|
|
Simplifying constant pointer cast (byte*) 9216
|
|
Simplifying constant integer cast $3fff
|
|
Simplifying constant integer cast 4
|
|
Simplifying constant integer cast 4
|
|
Simplifying constant integer cast $f
|
|
Simplifying constant integer cast $400
|
|
Simplifying constant integer cast $800
|
|
Successful SSA optimization PassNCastSimplification
|
|
Finalized unsigned number type (word) $3fff
|
|
Finalized unsigned number type (byte) 4
|
|
Finalized unsigned number type (byte) 4
|
|
Finalized unsigned number type (byte) $f
|
|
Finalized unsigned number type (word) $400
|
|
Finalized unsigned number type (word) $800
|
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
|
Inferred type updated to word in main::toD0181_$0 = main::toD0181_$7 & $3fff
|
|
Inferred type updated to word in main::toD0181_$1 = main::toD0181_$0 * 4
|
|
Inferred type updated to byte in main::toD0181_$2 = > main::toD0181_$1
|
|
Inferred type updated to byte in main::toD0181_$4 = main::toD0181_$3 / 4
|
|
Inferred type updated to byte in main::toD0181_$5 = main::toD0181_$4 & $f
|
|
Inferred type updated to byte in main::toD0181_$6 = main::toD0181_$2 | main::toD0181_$5
|
|
Alias memcpy::src_end#0 = memcpy::$0
|
|
Alias memcpy::src#2 = memcpy::src#3
|
|
Alias memcpy::dst#2 = memcpy::dst#3
|
|
Alias memcpy::src_end#1 = memcpy::src_end#2
|
|
Alias memcpy::destination#3 = memcpy::destination#5 memcpy::destination#4 memcpy::return#0 memcpy::return#4 memcpy::return#1
|
|
Alias main::toD0181_screen#0 = main::toD0181_screen#1
|
|
Alias main::toD0181_gfx#0 = main::toD0181_gfx#1
|
|
Alias main::toD0181_return#0 = main::toD0181_$6 main::toD0181_return#2 main::toD0181_return#1 main::toD0181_return#3 main::$0
|
|
Successful SSA optimization Pass2AliasElimination
|
|
Identical Phi Values memcpy::src_end#1 memcpy::src_end#0
|
|
Identical Phi Values memcpy::destination#3 memcpy::destination#2
|
|
Successful SSA optimization Pass2IdenticalPhiElimination
|
|
Simple Condition memcpy::$1 [7] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
|
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
|
Constant main::toD0181_screen#0 = SCREEN_COPY
|
|
Constant main::toD0181_gfx#0 = CHARSET
|
|
Constant memcpy::destination#0 = (void*)SCREEN_COPY
|
|
Constant memcpy::source#0 = (void*)SCREEN
|
|
Constant memcpy::num#0 = $400
|
|
Constant memcpy::destination#1 = (void*)CHARSET
|
|
Constant memcpy::source#1 = (void*)CHARGEN
|
|
Constant memcpy::num#1 = $800
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Constant main::toD0181_$7 = (word)main::toD0181_screen#0
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Constant value identified (word)main::toD0181_gfx#0 in [18] main::toD0181_$3 = > (word)main::toD0181_gfx#0
|
|
Successful SSA optimization Pass2ConstantValues
|
|
Eliminating unused variable memcpy::return#2 and assignment [20] memcpy::return#2 = memcpy::destination#2
|
|
Eliminating unused variable memcpy::return#3 and assignment [24] memcpy::return#3 = memcpy::destination#2
|
|
Successful SSA optimization PassNEliminateUnusedVars
|
|
Removing unused procedure __start
|
|
Removing unused procedure block __start
|
|
Removing unused procedure block __start::@1
|
|
Removing unused procedure block __start::@return
|
|
Successful SSA optimization PassNEliminateEmptyStart
|
|
Constant right-side identified [11] main::toD0181_$0 = main::toD0181_$7 & $3fff
|
|
Constant right-side identified [14] main::toD0181_$3 = > (word)main::toD0181_gfx#0
|
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
|
Constant main::toD0181_$0 = main::toD0181_$7&$3fff
|
|
Constant main::toD0181_$3 = >(word)main::toD0181_gfx#0
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Constant right-side identified [11] main::toD0181_$1 = main::toD0181_$0 * 4
|
|
Constant right-side identified [13] main::toD0181_$4 = main::toD0181_$3 / 4
|
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
|
Constant main::toD0181_$1 = main::toD0181_$0*4
|
|
Constant main::toD0181_$4 = main::toD0181_$3/4
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Constant right-side identified [11] main::toD0181_$2 = > main::toD0181_$1
|
|
Constant right-side identified [12] main::toD0181_$5 = main::toD0181_$4 & $f
|
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
|
Constant main::toD0181_$2 = >main::toD0181_$1
|
|
Constant main::toD0181_$5 = main::toD0181_$4&$f
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Constant right-side identified [11] main::toD0181_return#0 = main::toD0181_$2 | main::toD0181_$5
|
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
|
Constant main::toD0181_return#0 = main::toD0181_$2|main::toD0181_$5
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Inlining Noop Cast [1] memcpy::src#0 = (byte*)memcpy::source#2 keeping memcpy::source#2
|
|
Inlining Noop Cast [2] memcpy::dst#0 = (byte*)memcpy::destination#2 keeping memcpy::destination#2
|
|
Inlining Noop Cast [3] memcpy::$2 = (byte*)memcpy::source#2 keeping memcpy::source#2
|
|
Successful SSA optimization Pass2NopCastInlining
|
|
Inlining constant with var siblings memcpy::destination#0
|
|
Inlining constant with var siblings memcpy::source#0
|
|
Inlining constant with var siblings memcpy::num#0
|
|
Inlining constant with var siblings memcpy::destination#1
|
|
Inlining constant with var siblings memcpy::source#1
|
|
Inlining constant with var siblings memcpy::num#1
|
|
Constant inlined main::toD0181_screen#0 = SCREEN_COPY
|
|
Constant inlined main::toD0181_gfx#0 = CHARSET
|
|
Constant inlined main::toD0181_$7 = (word)SCREEN_COPY
|
|
Constant inlined main::toD0181_$2 = >(word)SCREEN_COPY&$3fff*4
|
|
Constant inlined main::toD0181_$1 = (word)SCREEN_COPY&$3fff*4
|
|
Constant inlined main::toD0181_$0 = (word)SCREEN_COPY&$3fff
|
|
Constant inlined memcpy::destination#0 = (void*)SCREEN_COPY
|
|
Constant inlined memcpy::destination#1 = (void*)CHARSET
|
|
Constant inlined memcpy::source#0 = (void*)SCREEN
|
|
Constant inlined main::toD0181_$5 = >(word)CHARSET/4&$f
|
|
Constant inlined main::toD0181_$4 = >(word)CHARSET/4
|
|
Constant inlined main::toD0181_$3 = >(word)CHARSET
|
|
Constant inlined memcpy::num#1 = $800
|
|
Constant inlined memcpy::num#0 = $400
|
|
Constant inlined memcpy::source#1 = (void*)CHARGEN
|
|
Successful SSA optimization Pass2ConstantInlining
|
|
Adding NOP phi() at start of main
|
|
Adding NOP phi() at start of main::toD0181
|
|
Adding NOP phi() at start of main::toD0181_@return
|
|
Adding NOP phi() at start of memcpy::@3
|
|
CALL GRAPH
|
|
Calls in [main] to memcpy:4 memcpy:7
|
|
|
|
Created 5 initial phi equivalence classes
|
|
Coalesced [22] memcpy::src#5 = memcpy::src#1
|
|
Coalesced [23] memcpy::dst#5 = memcpy::dst#1
|
|
Coalesced down to 5 phi equivalence classes
|
|
Culled Empty Block label main::toD0181_@return
|
|
Culled Empty Block label memcpy::@3
|
|
Adding NOP phi() at start of main
|
|
Adding NOP phi() at start of main::toD0181
|
|
|
|
FINAL CONTROL FLOW GRAPH
|
|
|
|
void main()
|
|
main: scope:[main] from
|
|
[0] phi()
|
|
to:main::toD0181
|
|
main::toD0181: scope:[main] from main
|
|
[1] phi()
|
|
to:main::@1
|
|
main::@1: scope:[main] from main::toD0181
|
|
[2] *D018 = main::toD0181_return#0
|
|
[3] call memcpy
|
|
to:main::@2
|
|
main::@2: scope:[main] from main::@1
|
|
asm { sei }
|
|
[5] *PROCPORT = PROCPORT_RAM_CHARROM
|
|
[6] call memcpy
|
|
to:main::@3
|
|
main::@3: scope:[main] from main::@2
|
|
[7] *PROCPORT = PROCPORT_BASIC_KERNEL_IO
|
|
asm { cli }
|
|
to:main::@return
|
|
main::@return: scope:[main] from main::@3
|
|
[9] return
|
|
to:@return
|
|
|
|
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
|
memcpy: scope:[memcpy] from main::@1 main::@2
|
|
[10] memcpy::num#2 = phi( main::@1/$400, main::@2/$800 )
|
|
[10] memcpy::destination#2 = phi( main::@1/(void*)SCREEN_COPY, main::@2/(void*)CHARSET )
|
|
[10] memcpy::source#2 = phi( main::@1/(void*)SCREEN, main::@2/(void*)CHARGEN )
|
|
[11] memcpy::src_end#0 = (byte*)memcpy::source#2 + memcpy::num#2
|
|
[12] memcpy::src#4 = (byte*)memcpy::source#2
|
|
[13] memcpy::dst#4 = (byte*)memcpy::destination#2
|
|
to:memcpy::@1
|
|
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
|
|
[14] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
|
|
[14] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
|
|
[15] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
|
|
to:memcpy::@return
|
|
memcpy::@return: scope:[memcpy] from memcpy::@1
|
|
[16] return
|
|
to:@return
|
|
memcpy::@2: scope:[memcpy] from memcpy::@1
|
|
[17] *memcpy::dst#2 = *memcpy::src#2
|
|
[18] memcpy::dst#1 = ++ memcpy::dst#2
|
|
[19] memcpy::src#1 = ++ memcpy::src#2
|
|
to:memcpy::@1
|
|
|
|
|
|
VARIABLE REGISTER WEIGHTS
|
|
void main()
|
|
byte* main::toD0181_gfx
|
|
byte main::toD0181_return
|
|
byte* main::toD0181_screen
|
|
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
|
void* memcpy::destination
|
|
void* memcpy::destination#2
|
|
byte* memcpy::dst
|
|
byte* memcpy::dst#1 101.0
|
|
byte* memcpy::dst#2 104.66666666666666
|
|
byte* memcpy::dst#4 22.0
|
|
word memcpy::num
|
|
word memcpy::num#2 11.0
|
|
void* memcpy::return
|
|
void* memcpy::source
|
|
void* memcpy::source#2
|
|
byte* memcpy::src
|
|
byte* memcpy::src#1 202.0
|
|
byte* memcpy::src#2 103.75
|
|
byte* memcpy::src#4 11.0
|
|
byte* memcpy::src_end
|
|
byte* memcpy::src_end#0 14.0
|
|
|
|
Initial phi equivalence classes
|
|
[ memcpy::source#2 ]
|
|
[ memcpy::destination#2 ]
|
|
[ memcpy::num#2 ]
|
|
[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
Added variable memcpy::src_end#0 to live range equivalence class [ memcpy::src_end#0 ]
|
|
Complete equivalence classes
|
|
[ memcpy::source#2 ]
|
|
[ memcpy::destination#2 ]
|
|
[ memcpy::num#2 ]
|
|
[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
[ memcpy::src_end#0 ]
|
|
Allocated zp[2]:2 [ memcpy::source#2 ]
|
|
Allocated zp[2]:4 [ memcpy::destination#2 ]
|
|
Allocated zp[2]:6 [ memcpy::num#2 ]
|
|
Allocated zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
Allocated zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
Allocated zp[2]:12 [ memcpy::src_end#0 ]
|
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
|
Statement [2] *D018 = main::toD0181_return#0 [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [5] *PROCPORT = PROCPORT_RAM_CHARROM [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [7] *PROCPORT = PROCPORT_BASIC_KERNEL_IO [ ] ( [ ] { } ) always clobbers reg byte a
|
|
Statement [11] memcpy::src_end#0 = (byte*)memcpy::source#2 + memcpy::num#2 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( memcpy:3 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { } memcpy:6 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { } ) always clobbers reg byte a
|
|
Statement [12] memcpy::src#4 = (byte*)memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( memcpy:3 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { } memcpy:6 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { } ) always clobbers reg byte a
|
|
Statement [13] memcpy::dst#4 = (byte*)memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( memcpy:3 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { } memcpy:6 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { } ) always clobbers reg byte a
|
|
Statement [15] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( memcpy:3 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } memcpy:6 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } ) always clobbers reg byte a
|
|
Statement [17] *memcpy::dst#2 = *memcpy::src#2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( memcpy:3 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } memcpy:6 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Potential registers zp[2]:2 [ memcpy::source#2 ] : zp[2]:2 ,
|
|
Potential registers zp[2]:4 [ memcpy::destination#2 ] : zp[2]:4 ,
|
|
Potential registers zp[2]:6 [ memcpy::num#2 ] : zp[2]:6 ,
|
|
Potential registers zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] : zp[2]:8 ,
|
|
Potential registers zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp[2]:10 ,
|
|
Potential registers zp[2]:12 [ memcpy::src_end#0 ] : zp[2]:12 ,
|
|
|
|
REGISTER UPLIFT SCOPES
|
|
Uplift Scope [memcpy] 316.75: zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 227.67: zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 14: zp[2]:12 [ memcpy::src_end#0 ] 11: zp[2]:6 [ memcpy::num#2 ] 0: zp[2]:2 [ memcpy::source#2 ] 0: zp[2]:4 [ memcpy::destination#2 ]
|
|
Uplift Scope [MOS6526_CIA]
|
|
Uplift Scope [MOS6569_VICII]
|
|
Uplift Scope [MOS6581_SID]
|
|
Uplift Scope [main]
|
|
Uplift Scope []
|
|
|
|
Uplifting [memcpy] best 857 combination zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp[2]:12 [ memcpy::src_end#0 ] zp[2]:6 [ memcpy::num#2 ] zp[2]:2 [ memcpy::source#2 ] zp[2]:4 [ memcpy::destination#2 ]
|
|
Uplifting [MOS6526_CIA] best 857 combination
|
|
Uplifting [MOS6569_VICII] best 857 combination
|
|
Uplifting [MOS6581_SID] best 857 combination
|
|
Uplifting [main] best 857 combination
|
|
Uplifting [] best 857 combination
|
|
Coalescing zero page register [ zp[2]:2 [ memcpy::source#2 ] ] with [ zp[2]:8 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1
|
|
Coalescing zero page register [ zp[2]:4 [ memcpy::destination#2 ] ] with [ zp[2]:10 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1
|
|
Coalescing zero page register [ zp[2]:6 [ memcpy::num#2 ] ] with [ zp[2]:12 [ memcpy::src_end#0 ] ] - score: 1
|
|
|
|
ASSEMBLER BEFORE OPTIMIZATION
|
|
// File Comments
|
|
// Test memcpy - copy charset and screen using memcpy() from stdlib string
|
|
// Upstart
|
|
// Commodore 64 PRG executable file
|
|
.file [name="memcpy-0.prg", type="prg", segments="Program"]
|
|
.segmentdef Program [segments="Basic, Code, Data"]
|
|
.segmentdef Basic [start=$0801]
|
|
.segmentdef Code [start=$80d]
|
|
.segmentdef Data [startAfter="Code"]
|
|
.segment Basic
|
|
:BasicUpstart(main)
|
|
// Global Constants & labels
|
|
// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
|
|
.const PROCPORT_RAM_CHARROM = 1
|
|
// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
|
|
.const PROCPORT_BASIC_KERNEL_IO = 7
|
|
.label D018 = $d018
|
|
// Processor Port Register controlling RAM/ROM configuration and the datasette
|
|
.label PROCPORT = 1
|
|
// The address of the CHARGEN character set
|
|
.label CHARGEN = $d000
|
|
.label CHARSET = $2000
|
|
.label SCREEN = $400
|
|
.label SCREEN_COPY = $2400
|
|
.segment Code
|
|
// main
|
|
main: {
|
|
.const toD0181_return = (>(SCREEN_COPY&$3fff)*4)|(>CHARSET)/4&$f
|
|
// [1] phi from main to main::toD0181 [phi:main->main::toD0181]
|
|
toD0181_from_main:
|
|
jmp toD0181
|
|
// main::toD0181
|
|
toD0181:
|
|
jmp __b1
|
|
// main::@1
|
|
__b1:
|
|
// [2] *D018 = main::toD0181_return#0 -- _deref_pbuc1=vbuc2
|
|
lda #toD0181_return
|
|
sta D018
|
|
// [3] call memcpy
|
|
// [10] phi from main::@1 to memcpy [phi:main::@1->memcpy]
|
|
memcpy_from___b1:
|
|
// [10] phi memcpy::num#2 = $400 [phi:main::@1->memcpy#0] -- vwuz1=vwuc1
|
|
lda #<$400
|
|
sta.z memcpy.num
|
|
lda #>$400
|
|
sta.z memcpy.num+1
|
|
// [10] phi memcpy::destination#2 = (void*)SCREEN_COPY [phi:main::@1->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN_COPY
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN_COPY
|
|
sta.z memcpy.destination+1
|
|
// [10] phi memcpy::source#2 = (void*)SCREEN [phi:main::@1->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<SCREEN
|
|
sta.z memcpy.source
|
|
lda #>SCREEN
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
jmp __b2
|
|
// main::@2
|
|
__b2:
|
|
// asm { sei }
|
|
sei
|
|
// [5] *PROCPORT = PROCPORT_RAM_CHARROM -- _deref_pbuc1=vbuc2
|
|
lda #PROCPORT_RAM_CHARROM
|
|
sta PROCPORT
|
|
// [6] call memcpy
|
|
// [10] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
|
memcpy_from___b2:
|
|
// [10] phi memcpy::num#2 = $800 [phi:main::@2->memcpy#0] -- vwuz1=vwuc1
|
|
lda #<$800
|
|
sta.z memcpy.num
|
|
lda #>$800
|
|
sta.z memcpy.num+1
|
|
// [10] phi memcpy::destination#2 = (void*)CHARSET [phi:main::@2->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<CHARSET
|
|
sta.z memcpy.destination
|
|
lda #>CHARSET
|
|
sta.z memcpy.destination+1
|
|
// [10] phi memcpy::source#2 = (void*)CHARGEN [phi:main::@2->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<CHARGEN
|
|
sta.z memcpy.source
|
|
lda #>CHARGEN
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
jmp __b3
|
|
// main::@3
|
|
__b3:
|
|
// [7] *PROCPORT = PROCPORT_BASIC_KERNEL_IO -- _deref_pbuc1=vbuc2
|
|
lda #PROCPORT_BASIC_KERNEL_IO
|
|
sta PROCPORT
|
|
// asm { cli }
|
|
cli
|
|
jmp __breturn
|
|
// main::@return
|
|
__breturn:
|
|
// [9] return
|
|
rts
|
|
}
|
|
// memcpy
|
|
// Copy block of memory (forwards)
|
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
|
// memcpy(void* zp(4) destination, void* zp(2) source, word zp(6) num)
|
|
memcpy: {
|
|
.label src_end = 6
|
|
.label dst = 4
|
|
.label src = 2
|
|
.label source = 2
|
|
.label destination = 4
|
|
.label num = 6
|
|
// [11] memcpy::src_end#0 = (byte*)memcpy::source#2 + memcpy::num#2 -- pbuz1=pbuz2_plus_vwuz1
|
|
lda.z src_end
|
|
clc
|
|
adc.z source
|
|
sta.z src_end
|
|
lda.z src_end+1
|
|
adc.z source+1
|
|
sta.z src_end+1
|
|
// [12] memcpy::src#4 = (byte*)memcpy::source#2
|
|
// [13] memcpy::dst#4 = (byte*)memcpy::destination#2
|
|
// [14] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
|
|
__b1_from_memcpy:
|
|
__b1_from___b2:
|
|
// [14] phi memcpy::dst#2 = memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy
|
|
// [14] phi memcpy::src#2 = memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy
|
|
jmp __b1
|
|
// memcpy::@1
|
|
__b1:
|
|
// [15] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1
|
|
lda.z src+1
|
|
cmp.z src_end+1
|
|
bne __b2
|
|
lda.z src
|
|
cmp.z src_end
|
|
bne __b2
|
|
jmp __breturn
|
|
// memcpy::@return
|
|
__breturn:
|
|
// [16] return
|
|
rts
|
|
// memcpy::@2
|
|
__b2:
|
|
// [17] *memcpy::dst#2 = *memcpy::src#2 -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (src),y
|
|
ldy #0
|
|
sta (dst),y
|
|
// [18] memcpy::dst#1 = ++ memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
|
inc.z dst
|
|
bne !+
|
|
inc.z dst+1
|
|
!:
|
|
// [19] memcpy::src#1 = ++ memcpy::src#2 -- pbuz1=_inc_pbuz1
|
|
inc.z src
|
|
bne !+
|
|
inc.z src+1
|
|
!:
|
|
jmp __b1_from___b2
|
|
}
|
|
// File Data
|
|
|
|
ASSEMBLER OPTIMIZATIONS
|
|
Removing instruction jmp toD0181
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __b2
|
|
Removing instruction jmp __b3
|
|
Removing instruction jmp __breturn
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __breturn
|
|
Succesful ASM optimization Pass5NextJumpElimination
|
|
Removing instruction ldy #0
|
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
|
Replacing label __b1_from___b2 with __b1
|
|
Removing instruction toD0181_from_main:
|
|
Removing instruction toD0181:
|
|
Removing instruction __b1_from_memcpy:
|
|
Removing instruction __b1_from___b2:
|
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
|
Removing instruction __b1:
|
|
Removing instruction memcpy_from___b1:
|
|
Removing instruction __b2:
|
|
Removing instruction memcpy_from___b2:
|
|
Removing instruction __b3:
|
|
Removing instruction __breturn:
|
|
Removing instruction __breturn:
|
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
|
|
|
FINAL SYMBOL TABLE
|
|
const nomodify byte* CHARGEN = (byte*) 53248
|
|
const nomodify byte* CHARSET = (byte*) 8192
|
|
const nomodify byte* D018 = (byte*) 53272
|
|
const nomodify byte* PROCPORT = (byte*) 1
|
|
const nomodify byte PROCPORT_BASIC_KERNEL_IO = 7
|
|
const nomodify byte PROCPORT_RAM_CHARROM = 1
|
|
const nomodify byte* SCREEN = (byte*) 1024
|
|
const nomodify byte* SCREEN_COPY = (byte*) 9216
|
|
void main()
|
|
byte* main::toD0181_gfx
|
|
byte main::toD0181_return
|
|
const byte main::toD0181_return#0 toD0181_return = >(word)SCREEN_COPY&$3fff*4|>(word)CHARSET/4&$f
|
|
byte* main::toD0181_screen
|
|
void* memcpy(void* memcpy::destination , void* memcpy::source , word memcpy::num)
|
|
void* memcpy::destination
|
|
void* memcpy::destination#2 destination zp[2]:4
|
|
byte* memcpy::dst
|
|
byte* memcpy::dst#1 dst zp[2]:4 101.0
|
|
byte* memcpy::dst#2 dst zp[2]:4 104.66666666666666
|
|
byte* memcpy::dst#4 dst zp[2]:4 22.0
|
|
word memcpy::num
|
|
word memcpy::num#2 num zp[2]:6 11.0
|
|
void* memcpy::return
|
|
void* memcpy::source
|
|
void* memcpy::source#2 source zp[2]:2
|
|
byte* memcpy::src
|
|
byte* memcpy::src#1 src zp[2]:2 202.0
|
|
byte* memcpy::src#2 src zp[2]:2 103.75
|
|
byte* memcpy::src#4 src zp[2]:2 11.0
|
|
byte* memcpy::src_end
|
|
byte* memcpy::src_end#0 src_end zp[2]:6 14.0
|
|
|
|
zp[2]:2 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
zp[2]:4 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
zp[2]:6 [ memcpy::num#2 memcpy::src_end#0 ]
|
|
|
|
|
|
FINAL ASSEMBLER
|
|
Score: 711
|
|
|
|
// File Comments
|
|
// Test memcpy - copy charset and screen using memcpy() from stdlib string
|
|
// Upstart
|
|
// Commodore 64 PRG executable file
|
|
.file [name="memcpy-0.prg", type="prg", segments="Program"]
|
|
.segmentdef Program [segments="Basic, Code, Data"]
|
|
.segmentdef Basic [start=$0801]
|
|
.segmentdef Code [start=$80d]
|
|
.segmentdef Data [startAfter="Code"]
|
|
.segment Basic
|
|
:BasicUpstart(main)
|
|
// Global Constants & labels
|
|
// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
|
|
.const PROCPORT_RAM_CHARROM = 1
|
|
// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
|
|
.const PROCPORT_BASIC_KERNEL_IO = 7
|
|
.label D018 = $d018
|
|
// Processor Port Register controlling RAM/ROM configuration and the datasette
|
|
.label PROCPORT = 1
|
|
// The address of the CHARGEN character set
|
|
.label CHARGEN = $d000
|
|
.label CHARSET = $2000
|
|
.label SCREEN = $400
|
|
.label SCREEN_COPY = $2400
|
|
.segment Code
|
|
// main
|
|
main: {
|
|
.const toD0181_return = (>(SCREEN_COPY&$3fff)*4)|(>CHARSET)/4&$f
|
|
// [1] phi from main to main::toD0181 [phi:main->main::toD0181]
|
|
// main::toD0181
|
|
// main::@1
|
|
// *D018 = toD018(SCREEN_COPY, CHARSET)
|
|
// [2] *D018 = main::toD0181_return#0 -- _deref_pbuc1=vbuc2
|
|
lda #toD0181_return
|
|
sta D018
|
|
// memcpy(SCREEN_COPY, SCREEN, 0x0400)
|
|
// [3] call memcpy
|
|
// [10] phi from main::@1 to memcpy [phi:main::@1->memcpy]
|
|
// [10] phi memcpy::num#2 = $400 [phi:main::@1->memcpy#0] -- vwuz1=vwuc1
|
|
lda #<$400
|
|
sta.z memcpy.num
|
|
lda #>$400
|
|
sta.z memcpy.num+1
|
|
// [10] phi memcpy::destination#2 = (void*)SCREEN_COPY [phi:main::@1->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN_COPY
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN_COPY
|
|
sta.z memcpy.destination+1
|
|
// [10] phi memcpy::source#2 = (void*)SCREEN [phi:main::@1->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<SCREEN
|
|
sta.z memcpy.source
|
|
lda #>SCREEN
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
// main::@2
|
|
// asm
|
|
// asm { sei }
|
|
sei
|
|
// *PROCPORT = PROCPORT_RAM_CHARROM
|
|
// [5] *PROCPORT = PROCPORT_RAM_CHARROM -- _deref_pbuc1=vbuc2
|
|
lda #PROCPORT_RAM_CHARROM
|
|
sta PROCPORT
|
|
// memcpy(CHARSET, CHARGEN, 0x0800)
|
|
// [6] call memcpy
|
|
// [10] phi from main::@2 to memcpy [phi:main::@2->memcpy]
|
|
// [10] phi memcpy::num#2 = $800 [phi:main::@2->memcpy#0] -- vwuz1=vwuc1
|
|
lda #<$800
|
|
sta.z memcpy.num
|
|
lda #>$800
|
|
sta.z memcpy.num+1
|
|
// [10] phi memcpy::destination#2 = (void*)CHARSET [phi:main::@2->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<CHARSET
|
|
sta.z memcpy.destination
|
|
lda #>CHARSET
|
|
sta.z memcpy.destination+1
|
|
// [10] phi memcpy::source#2 = (void*)CHARGEN [phi:main::@2->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<CHARGEN
|
|
sta.z memcpy.source
|
|
lda #>CHARGEN
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
// main::@3
|
|
// *PROCPORT = PROCPORT_BASIC_KERNEL_IO
|
|
// [7] *PROCPORT = PROCPORT_BASIC_KERNEL_IO -- _deref_pbuc1=vbuc2
|
|
lda #PROCPORT_BASIC_KERNEL_IO
|
|
sta PROCPORT
|
|
// asm
|
|
// asm { cli }
|
|
cli
|
|
// main::@return
|
|
// }
|
|
// [9] return
|
|
rts
|
|
}
|
|
// memcpy
|
|
// Copy block of memory (forwards)
|
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
|
// memcpy(void* zp(4) destination, void* zp(2) source, word zp(6) num)
|
|
memcpy: {
|
|
.label src_end = 6
|
|
.label dst = 4
|
|
.label src = 2
|
|
.label source = 2
|
|
.label destination = 4
|
|
.label num = 6
|
|
// src_end = (char*)source+num
|
|
// [11] memcpy::src_end#0 = (byte*)memcpy::source#2 + memcpy::num#2 -- pbuz1=pbuz2_plus_vwuz1
|
|
lda.z src_end
|
|
clc
|
|
adc.z source
|
|
sta.z src_end
|
|
lda.z src_end+1
|
|
adc.z source+1
|
|
sta.z src_end+1
|
|
// [12] memcpy::src#4 = (byte*)memcpy::source#2
|
|
// [13] memcpy::dst#4 = (byte*)memcpy::destination#2
|
|
// [14] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
|
|
// [14] phi memcpy::dst#2 = memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy
|
|
// [14] phi memcpy::src#2 = memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy
|
|
// memcpy::@1
|
|
__b1:
|
|
// while(src!=src_end)
|
|
// [15] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1
|
|
lda.z src+1
|
|
cmp.z src_end+1
|
|
bne __b2
|
|
lda.z src
|
|
cmp.z src_end
|
|
bne __b2
|
|
// memcpy::@return
|
|
// }
|
|
// [16] return
|
|
rts
|
|
// memcpy::@2
|
|
__b2:
|
|
// *dst++ = *src++
|
|
// [17] *memcpy::dst#2 = *memcpy::src#2 -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (src),y
|
|
sta (dst),y
|
|
// *dst++ = *src++;
|
|
// [18] memcpy::dst#1 = ++ memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
|
inc.z dst
|
|
bne !+
|
|
inc.z dst+1
|
|
!:
|
|
// [19] memcpy::src#1 = ++ memcpy::src#2 -- pbuz1=_inc_pbuz1
|
|
inc.z src
|
|
bne !+
|
|
inc.z src+1
|
|
!:
|
|
jmp __b1
|
|
}
|
|
// File Data
|
|
|