1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-29 03:56:15 +00:00
kickc/src/test/ref/memcpy-0.log

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