mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-29 03:56:15 +00:00
1354 lines
53 KiB
Plaintext
1354 lines
53 KiB
Plaintext
|
|
CONTROL FLOW GRAPH SSA
|
|
@begin: scope:[] from
|
|
to:@1
|
|
|
|
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
|
|
memcpy: scope:[memcpy] from main::@4 main::@5
|
|
(word) memcpy::num#2 ← phi( main::@4/(word) memcpy::num#0 main::@5/(word) memcpy::num#1 )
|
|
(void*) memcpy::destination#2 ← phi( main::@4/(void*) memcpy::destination#0 main::@5/(void*) memcpy::destination#1 )
|
|
(void*) memcpy::source#2 ← phi( main::@4/(void*) memcpy::source#0 main::@5/(void*) memcpy::source#1 )
|
|
(byte*) memcpy::src#0 ← ((byte*)) (void*) memcpy::source#2
|
|
(byte*) memcpy::dst#0 ← ((byte*)) (void*) memcpy::destination#2
|
|
(byte*~) memcpy::$2 ← (byte*)(void*) memcpy::source#2
|
|
(byte*~) memcpy::$0 ← (byte*~) memcpy::$2 + (word) memcpy::num#2
|
|
(byte*) memcpy::src_end#0 ← (byte*~) memcpy::$0
|
|
to:memcpy::@1
|
|
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
|
|
(void*) memcpy::destination#4 ← phi( memcpy/(void*) memcpy::destination#2 memcpy::@2/(void*) memcpy::destination#5 )
|
|
(byte*) memcpy::dst#3 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@2/(byte*) memcpy::dst#1 )
|
|
(byte*) memcpy::src_end#1 ← phi( memcpy/(byte*) memcpy::src_end#0 memcpy::@2/(byte*) memcpy::src_end#2 )
|
|
(byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@2/(byte*) memcpy::src#1 )
|
|
(bool~) memcpy::$1 ← (byte*) memcpy::src#2 != (byte*) memcpy::src_end#1
|
|
if((bool~) memcpy::$1) goto memcpy::@2
|
|
to:memcpy::@3
|
|
memcpy::@2: scope:[memcpy] from memcpy::@1
|
|
(void*) memcpy::destination#5 ← phi( memcpy::@1/(void*) memcpy::destination#4 )
|
|
(byte*) memcpy::src_end#2 ← phi( memcpy::@1/(byte*) memcpy::src_end#1 )
|
|
(byte*) memcpy::dst#2 ← phi( memcpy::@1/(byte*) memcpy::dst#3 )
|
|
(byte*) memcpy::src#3 ← phi( memcpy::@1/(byte*) memcpy::src#2 )
|
|
*((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#3)
|
|
(byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
|
(byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#3
|
|
to:memcpy::@1
|
|
memcpy::@3: scope:[memcpy] from memcpy::@1
|
|
(void*) memcpy::destination#3 ← phi( memcpy::@1/(void*) memcpy::destination#4 )
|
|
(void*) memcpy::return#0 ← (void*) memcpy::destination#3
|
|
to:memcpy::@return
|
|
memcpy::@return: scope:[memcpy] from memcpy::@3
|
|
(void*) memcpy::return#4 ← phi( memcpy::@3/(void*) memcpy::return#0 )
|
|
(void*) memcpy::return#1 ← (void*) memcpy::return#4
|
|
return
|
|
to:@return
|
|
|
|
(void()) main()
|
|
main: scope:[main] from @1
|
|
(byte*) main::sc#0 ← (const nomodify byte*) SCREEN
|
|
(byte*) main::camelot#0 ← (const to_nomodify byte*) CAMELOT
|
|
(byte) main::i#0 ← (byte) 0
|
|
to:main::@1
|
|
main::@1: scope:[main] from main main::@1
|
|
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
|
(byte*) main::sc#2 ← phi( main/(byte*) main::sc#0 main::@1/(byte*) main::sc#1 )
|
|
(byte*) main::camelot#2 ← phi( main/(byte*) main::camelot#0 main::@1/(byte*) main::camelot#1 )
|
|
*((byte*) main::sc#2) ← *((byte*) main::camelot#2)
|
|
(byte*) main::sc#1 ← ++ (byte*) main::sc#2
|
|
(byte*) main::camelot#1 ← ++ (byte*) main::camelot#2
|
|
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,6)
|
|
(bool~) main::$2 ← (byte) main::i#1 != rangelast(0,6)
|
|
if((bool~) main::$2) goto main::@1
|
|
to:main::@2
|
|
main::@2: scope:[main] from main::@1
|
|
(byte*) main::sc2#0 ← (const nomodify byte*) SCREEN+(number) $28
|
|
(byte*) main::reigns#0 ← (const byte*) main::$4
|
|
(byte) main::i1#0 ← (byte) 0
|
|
to:main::@3
|
|
main::@3: scope:[main] from main::@2 main::@3
|
|
(byte) main::i1#2 ← phi( main::@2/(byte) main::i1#0 main::@3/(byte) main::i1#1 )
|
|
(byte*) main::sc2#2 ← phi( main::@2/(byte*) main::sc2#0 main::@3/(byte*) main::sc2#1 )
|
|
(byte*) main::reigns#2 ← phi( main::@2/(byte*) main::reigns#0 main::@3/(byte*) main::reigns#1 )
|
|
*((byte*) main::sc2#2) ← *((byte*) main::reigns#2)
|
|
(byte*) main::sc2#1 ← ++ (byte*) main::sc2#2
|
|
(byte*) main::reigns#1 ← ++ (byte*) main::reigns#2
|
|
(byte) main::i1#1 ← (byte) main::i1#2 + rangenext(0,5)
|
|
(bool~) main::$3 ← (byte) main::i1#1 != rangelast(0,5)
|
|
if((bool~) main::$3) goto main::@3
|
|
to:main::@4
|
|
main::@4: scope:[main] from main::@3
|
|
(void*) memcpy::destination#0 ← (void*)(const nomodify byte*) SCREEN+(number) $a
|
|
(void*) memcpy::source#0 ← (void*)(const to_nomodify byte*) CAMELOT
|
|
(word) memcpy::num#0 ← (number) 7
|
|
call memcpy
|
|
(void*) memcpy::return#2 ← (void*) memcpy::return#1
|
|
to:main::@5
|
|
main::@5: scope:[main] from main::@4
|
|
(void*) memcpy::destination#1 ← (void*)(const nomodify byte*) SCREEN+(number) $32
|
|
(void*) memcpy::source#1 ← (void*)(const byte*) main::$5
|
|
(word) memcpy::num#1 ← (number) 5
|
|
call memcpy
|
|
(void*) memcpy::return#3 ← (void*) memcpy::return#1
|
|
to:main::@6
|
|
main::@6: scope:[main] from main::@5
|
|
to:main::@return
|
|
main::@return: scope:[main] from main::@6
|
|
return
|
|
to:@return
|
|
@1: scope:[] from @begin
|
|
call main
|
|
to:@2
|
|
@2: scope:[] from @1
|
|
to:@end
|
|
@end: scope:[] from @2
|
|
|
|
SYMBOL TABLE SSA
|
|
(label) @1
|
|
(label) @2
|
|
(label) @begin
|
|
(label) @end
|
|
(const to_nomodify byte*) CAMELOT[] = (byte*) "camelot"
|
|
(const nomodify byte*) SCREEN = (byte*)(number) $400
|
|
(void()) main()
|
|
(bool~) main::$2
|
|
(bool~) main::$3
|
|
(const byte*) main::$4[(byte) 7] = (byte*) "reigns"
|
|
(const byte*) main::$5[(byte) 6] = (byte*) "rules"
|
|
(label) main::@1
|
|
(label) main::@2
|
|
(label) main::@3
|
|
(label) main::@4
|
|
(label) main::@5
|
|
(label) main::@6
|
|
(label) main::@return
|
|
(byte*) main::camelot
|
|
(byte*) main::camelot#0
|
|
(byte*) main::camelot#1
|
|
(byte*) main::camelot#2
|
|
(byte) main::i
|
|
(byte) main::i#0
|
|
(byte) main::i#1
|
|
(byte) main::i#2
|
|
(byte) main::i1
|
|
(byte) main::i1#0
|
|
(byte) main::i1#1
|
|
(byte) main::i1#2
|
|
(byte*) main::reigns
|
|
(byte*) main::reigns#0
|
|
(byte*) main::reigns#1
|
|
(byte*) main::reigns#2
|
|
(byte*) main::sc
|
|
(byte*) main::sc#0
|
|
(byte*) main::sc#1
|
|
(byte*) main::sc#2
|
|
(byte*) main::sc2
|
|
(byte*) main::sc2#0
|
|
(byte*) main::sc2#1
|
|
(byte*) main::sc2#2
|
|
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
|
|
(byte*~) memcpy::$0
|
|
(bool~) memcpy::$1
|
|
(byte*~) memcpy::$2
|
|
(label) memcpy::@1
|
|
(label) memcpy::@2
|
|
(label) memcpy::@3
|
|
(label) memcpy::@return
|
|
(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) $28 in (byte*) main::sc2#0 ← (const nomodify byte*) SCREEN+(number) $28
|
|
Adding number conversion cast (unumber) $a in (void*) memcpy::destination#0 ← (void*)(const nomodify byte*) SCREEN+(number) $a
|
|
Adding number conversion cast (unumber) 7 in (word) memcpy::num#0 ← (number) 7
|
|
Adding number conversion cast (unumber) $32 in (void*) memcpy::destination#1 ← (void*)(const nomodify byte*) SCREEN+(number) $32
|
|
Adding number conversion cast (unumber) 5 in (word) memcpy::num#1 ← (number) 5
|
|
Successful SSA optimization PassNAddNumberTypeConversions
|
|
Inlining cast (byte*) memcpy::src#0 ← (byte*)(void*) memcpy::source#2
|
|
Inlining cast (byte*) memcpy::dst#0 ← (byte*)(void*) memcpy::destination#2
|
|
Inlining cast (word) memcpy::num#0 ← (unumber)(number) 7
|
|
Inlining cast (word) memcpy::num#1 ← (unumber)(number) 5
|
|
Successful SSA optimization Pass2InlineCast
|
|
Simplifying constant pointer cast (byte*) 1024
|
|
Simplifying constant integer cast $28
|
|
Simplifying constant integer cast $a
|
|
Simplifying constant integer cast 7
|
|
Simplifying constant integer cast $32
|
|
Simplifying constant integer cast 5
|
|
Successful SSA optimization PassNCastSimplification
|
|
Finalized unsigned number type (byte) $28
|
|
Finalized unsigned number type (byte) $a
|
|
Finalized unsigned number type (byte) 7
|
|
Finalized unsigned number type (byte) $32
|
|
Finalized unsigned number type (byte) 5
|
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
|
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
|
|
Successful SSA optimization Pass2AliasElimination
|
|
Identical Phi Values (byte*) memcpy::src_end#1 (byte*) memcpy::src_end#0
|
|
Identical Phi Values (void*) memcpy::destination#3 (void*) memcpy::destination#2
|
|
Successful SSA optimization Pass2IdenticalPhiElimination
|
|
Simple Condition (bool~) memcpy::$1 [7] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2
|
|
Simple Condition (bool~) main::$2 [21] if((byte) main::i#1!=rangelast(0,6)) goto main::@1
|
|
Simple Condition (bool~) main::$3 [31] if((byte) main::i1#1!=rangelast(0,5)) goto main::@3
|
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
|
Constant (const byte*) main::sc#0 = SCREEN
|
|
Constant (const byte*) main::camelot#0 = CAMELOT
|
|
Constant (const byte) main::i#0 = 0
|
|
Constant (const byte*) main::sc2#0 = SCREEN+$28
|
|
Constant (const byte*) main::reigns#0 = main::$4
|
|
Constant (const byte) main::i1#0 = 0
|
|
Constant (const void*) memcpy::destination#0 = (void*)SCREEN+$a
|
|
Constant (const void*) memcpy::source#0 = (void*)CAMELOT
|
|
Constant (const word) memcpy::num#0 = 7
|
|
Constant (const void*) memcpy::destination#1 = (void*)SCREEN+$32
|
|
Constant (const void*) memcpy::source#1 = (void*)main::$5
|
|
Constant (const word) memcpy::num#1 = 5
|
|
Successful SSA optimization Pass2ConstantIdentification
|
|
Resolved ranged next value [19] main::i#1 ← ++ main::i#2 to ++
|
|
Resolved ranged comparison value [21] if(main::i#1!=rangelast(0,6)) goto main::@1 to (number) 7
|
|
Resolved ranged next value [29] main::i1#1 ← ++ main::i1#2 to ++
|
|
Resolved ranged comparison value [31] if(main::i1#1!=rangelast(0,5)) goto main::@3 to (number) 6
|
|
Eliminating unused variable (void*) memcpy::return#2 and assignment [24] (void*) memcpy::return#2 ← (void*) memcpy::destination#2
|
|
Eliminating unused variable (void*) memcpy::return#3 and assignment [26] (void*) memcpy::return#3 ← (void*) memcpy::destination#2
|
|
Successful SSA optimization PassNEliminateUnusedVars
|
|
Adding number conversion cast (unumber) 7 in if((byte) main::i#1!=(number) 7) goto main::@1
|
|
Adding number conversion cast (unumber) 6 in if((byte) main::i1#1!=(number) 6) goto main::@3
|
|
Successful SSA optimization PassNAddNumberTypeConversions
|
|
Simplifying constant integer cast 7
|
|
Simplifying constant integer cast 6
|
|
Successful SSA optimization PassNCastSimplification
|
|
Finalized unsigned number type (byte) 7
|
|
Finalized unsigned number type (byte) 6
|
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
|
Inlining Noop Cast [1] (byte*) memcpy::src#0 ← (byte*)(void*) memcpy::source#2 keeping memcpy::source#2
|
|
Inlining Noop Cast [2] (byte*) memcpy::dst#0 ← (byte*)(void*) memcpy::destination#2 keeping memcpy::destination#2
|
|
Inlining Noop Cast [3] (byte*~) memcpy::$2 ← (byte*)(void*) memcpy::source#2 keeping memcpy::source#2
|
|
Successful SSA optimization Pass2NopCastInlining
|
|
Inlining constant with var siblings (const void*) memcpy::destination#0
|
|
Inlining constant with var siblings (const void*) memcpy::source#0
|
|
Inlining constant with var siblings (const word) memcpy::num#0
|
|
Inlining constant with var siblings (const void*) memcpy::destination#1
|
|
Inlining constant with var siblings (const void*) memcpy::source#1
|
|
Inlining constant with var siblings (const word) memcpy::num#1
|
|
Inlining constant with var siblings (const byte*) main::sc#0
|
|
Inlining constant with var siblings (const byte*) main::camelot#0
|
|
Inlining constant with var siblings (const byte) main::i#0
|
|
Inlining constant with var siblings (const byte*) main::sc2#0
|
|
Inlining constant with var siblings (const byte*) main::reigns#0
|
|
Inlining constant with var siblings (const byte) main::i1#0
|
|
Constant inlined main::camelot#0 = (const to_nomodify byte*) CAMELOT
|
|
Constant inlined main::sc#0 = (const nomodify byte*) SCREEN
|
|
Constant inlined memcpy::destination#0 = (void*)(const nomodify byte*) SCREEN+(byte) $a
|
|
Constant inlined memcpy::destination#1 = (void*)(const nomodify byte*) SCREEN+(byte) $32
|
|
Constant inlined memcpy::source#0 = (void*)(const to_nomodify byte*) CAMELOT
|
|
Constant inlined memcpy::num#1 = (byte) 5
|
|
Constant inlined memcpy::num#0 = (byte) 7
|
|
Constant inlined memcpy::source#1 = (void*)(const byte*) main::$5
|
|
Constant inlined main::i#0 = (byte) 0
|
|
Constant inlined main::i1#0 = (byte) 0
|
|
Constant inlined main::$4 = (const byte*) main::reigns#0
|
|
Constant inlined main::sc2#0 = (const nomodify byte*) SCREEN+(byte) $28
|
|
Successful SSA optimization Pass2ConstantInlining
|
|
Inlining constant with var siblings (const byte*) main::reigns#0
|
|
Inlining constant with var siblings (const byte*) main::reigns#0
|
|
Added new block during phi lifting main::@7(between main::@1 and main::@1)
|
|
Added new block during phi lifting main::@8(between main::@3 and main::@3)
|
|
Adding NOP phi() at start of @begin
|
|
Adding NOP phi() at start of @1
|
|
Adding NOP phi() at start of @2
|
|
Adding NOP phi() at start of @end
|
|
Adding NOP phi() at start of main
|
|
Adding NOP phi() at start of main::@2
|
|
Adding NOP phi() at start of main::@4
|
|
Adding NOP phi() at start of main::@5
|
|
Adding NOP phi() at start of main::@6
|
|
Adding NOP phi() at start of memcpy::@3
|
|
CALL GRAPH
|
|
Calls in [] to main:2
|
|
Calls in [main] to memcpy:20 memcpy:22
|
|
|
|
Created 11 initial phi equivalence classes
|
|
Coalesced [25] main::reigns#3 ← main::reigns#1
|
|
Coalesced [26] main::sc2#3 ← main::sc2#1
|
|
Coalesced [27] main::i1#3 ← main::i1#1
|
|
Coalesced [28] main::camelot#3 ← main::camelot#1
|
|
Coalesced [29] main::sc#3 ← main::sc#1
|
|
Coalesced [30] main::i#3 ← main::i#1
|
|
Coalesced [42] memcpy::src#5 ← memcpy::src#1
|
|
Coalesced [43] memcpy::dst#5 ← memcpy::dst#1
|
|
Coalesced down to 11 phi equivalence classes
|
|
Culled Empty Block (label) @2
|
|
Culled Empty Block (label) main::@2
|
|
Culled Empty Block (label) main::@6
|
|
Culled Empty Block (label) main::@8
|
|
Culled Empty Block (label) main::@7
|
|
Culled Empty Block (label) memcpy::@3
|
|
Renumbering block main::@3 to main::@2
|
|
Renumbering block main::@4 to main::@3
|
|
Renumbering block main::@5 to main::@4
|
|
Adding NOP phi() at start of @begin
|
|
Adding NOP phi() at start of @1
|
|
Adding NOP phi() at start of @end
|
|
Adding NOP phi() at start of main
|
|
Adding NOP phi() at start of main::@3
|
|
Adding NOP phi() at start of main::@4
|
|
|
|
FINAL CONTROL FLOW GRAPH
|
|
@begin: scope:[] from
|
|
[0] phi()
|
|
to:@1
|
|
@1: scope:[] from @begin
|
|
[1] phi()
|
|
[2] call main
|
|
to:@end
|
|
@end: scope:[] from @1
|
|
[3] phi()
|
|
|
|
(void()) main()
|
|
main: scope:[main] from @1
|
|
[4] phi()
|
|
to:main::@1
|
|
main::@1: scope:[main] from main main::@1
|
|
[5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
|
[5] (byte*) main::sc#2 ← phi( main/(const nomodify byte*) SCREEN main::@1/(byte*) main::sc#1 )
|
|
[5] (byte*) main::camelot#2 ← phi( main/(const to_nomodify byte*) CAMELOT main::@1/(byte*) main::camelot#1 )
|
|
[6] *((byte*) main::sc#2) ← *((byte*) main::camelot#2)
|
|
[7] (byte*) main::sc#1 ← ++ (byte*) main::sc#2
|
|
[8] (byte*) main::camelot#1 ← ++ (byte*) main::camelot#2
|
|
[9] (byte) main::i#1 ← ++ (byte) main::i#2
|
|
[10] if((byte) main::i#1!=(byte) 7) goto main::@1
|
|
to:main::@2
|
|
main::@2: scope:[main] from main::@1 main::@2
|
|
[11] (byte) main::i1#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::i1#1 )
|
|
[11] (byte*) main::sc2#2 ← phi( main::@1/(const nomodify byte*) SCREEN+(byte) $28 main::@2/(byte*) main::sc2#1 )
|
|
[11] (byte*) main::reigns#2 ← phi( main::@1/(const byte*) main::reigns#0 main::@2/(byte*) main::reigns#1 )
|
|
[12] *((byte*) main::sc2#2) ← *((byte*) main::reigns#2)
|
|
[13] (byte*) main::sc2#1 ← ++ (byte*) main::sc2#2
|
|
[14] (byte*) main::reigns#1 ← ++ (byte*) main::reigns#2
|
|
[15] (byte) main::i1#1 ← ++ (byte) main::i1#2
|
|
[16] if((byte) main::i1#1!=(byte) 6) goto main::@2
|
|
to:main::@3
|
|
main::@3: scope:[main] from main::@2
|
|
[17] phi()
|
|
[18] call memcpy
|
|
to:main::@4
|
|
main::@4: scope:[main] from main::@3
|
|
[19] phi()
|
|
[20] call memcpy
|
|
to:main::@return
|
|
main::@return: scope:[main] from main::@4
|
|
[21] return
|
|
to:@return
|
|
|
|
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
|
|
memcpy: scope:[memcpy] from main::@3 main::@4
|
|
[22] (word) memcpy::num#2 ← phi( main::@3/(byte) 7 main::@4/(byte) 5 )
|
|
[22] (void*) memcpy::destination#2 ← phi( main::@3/(void*)(const nomodify byte*) SCREEN+(byte) $a main::@4/(void*)(const nomodify byte*) SCREEN+(byte) $32 )
|
|
[22] (void*) memcpy::source#2 ← phi( main::@3/(void*)(const to_nomodify byte*) CAMELOT main::@4/(void*)(const byte*) main::$5 )
|
|
[23] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) memcpy::num#2
|
|
[24] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
|
|
[25] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
|
|
to:memcpy::@1
|
|
memcpy::@1: scope:[memcpy] from memcpy memcpy::@2
|
|
[26] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#4 memcpy::@2/(byte*) memcpy::dst#1 )
|
|
[26] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#4 memcpy::@2/(byte*) memcpy::src#1 )
|
|
[27] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2
|
|
to:memcpy::@return
|
|
memcpy::@return: scope:[memcpy] from memcpy::@1
|
|
[28] return
|
|
to:@return
|
|
memcpy::@2: scope:[memcpy] from memcpy::@1
|
|
[29] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
|
|
[30] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
|
|
[31] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
|
|
to:memcpy::@1
|
|
|
|
|
|
VARIABLE REGISTER WEIGHTS
|
|
(void()) main()
|
|
(byte*) main::camelot
|
|
(byte*) main::camelot#1 67.33333333333333
|
|
(byte*) main::camelot#2 101.0
|
|
(byte) main::i
|
|
(byte) main::i#1 151.5
|
|
(byte) main::i#2 50.5
|
|
(byte) main::i1
|
|
(byte) main::i1#1 151.5
|
|
(byte) main::i1#2 50.5
|
|
(byte*) main::reigns
|
|
(byte*) main::reigns#1 67.33333333333333
|
|
(byte*) main::reigns#2 101.0
|
|
(byte*) main::sc
|
|
(byte*) main::sc#1 50.5
|
|
(byte*) main::sc#2 151.5
|
|
(byte*) main::sc2
|
|
(byte*) main::sc2#1 50.5
|
|
(byte*) main::sc2#2 151.5
|
|
(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 1001.0
|
|
(byte*) memcpy::dst#2 1034.6666666666667
|
|
(byte*) memcpy::dst#4 202.0
|
|
(word) memcpy::num
|
|
(word) memcpy::num#2 101.0
|
|
(void*) memcpy::return
|
|
(void*) memcpy::source
|
|
(void*) memcpy::source#2
|
|
(byte*) memcpy::src
|
|
(byte*) memcpy::src#1 2002.0
|
|
(byte*) memcpy::src#2 1026.25
|
|
(byte*) memcpy::src#4 101.0
|
|
(byte*) memcpy::src_end
|
|
(byte*) memcpy::src_end#0 137.75
|
|
|
|
Initial phi equivalence classes
|
|
[ main::camelot#2 main::camelot#1 ]
|
|
[ main::sc#2 main::sc#1 ]
|
|
[ main::i#2 main::i#1 ]
|
|
[ main::reigns#2 main::reigns#1 ]
|
|
[ main::sc2#2 main::sc2#1 ]
|
|
[ main::i1#2 main::i1#1 ]
|
|
[ 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
|
|
[ main::camelot#2 main::camelot#1 ]
|
|
[ main::sc#2 main::sc#1 ]
|
|
[ main::i#2 main::i#1 ]
|
|
[ main::reigns#2 main::reigns#1 ]
|
|
[ main::sc2#2 main::sc2#1 ]
|
|
[ main::i1#2 main::i1#1 ]
|
|
[ 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 [ main::camelot#2 main::camelot#1 ]
|
|
Allocated zp[2]:4 [ main::sc#2 main::sc#1 ]
|
|
Allocated zp[1]:6 [ main::i#2 main::i#1 ]
|
|
Allocated zp[2]:7 [ main::reigns#2 main::reigns#1 ]
|
|
Allocated zp[2]:9 [ main::sc2#2 main::sc2#1 ]
|
|
Allocated zp[1]:11 [ main::i1#2 main::i1#1 ]
|
|
Allocated zp[2]:12 [ memcpy::source#2 ]
|
|
Allocated zp[2]:14 [ memcpy::destination#2 ]
|
|
Allocated zp[2]:16 [ memcpy::num#2 ]
|
|
Allocated zp[2]:18 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
Allocated zp[2]:20 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
Allocated zp[2]:22 [ memcpy::src_end#0 ]
|
|
|
|
INITIAL ASM
|
|
Target platform is c64basic / MOS6502X
|
|
// File Comments
|
|
// Test memcpy on strings (
|
|
// Upstart
|
|
.pc = $801 "Basic"
|
|
:BasicUpstart(main)
|
|
.pc = $80d "Program"
|
|
// Global Constants & labels
|
|
.label SCREEN = $400
|
|
// @begin
|
|
__bbegin:
|
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
|
__b1_from___bbegin:
|
|
jmp __b1
|
|
// @1
|
|
__b1:
|
|
// [2] call main
|
|
// [4] phi from @1 to main [phi:@1->main]
|
|
main_from___b1:
|
|
jsr main
|
|
// [3] phi from @1 to @end [phi:@1->@end]
|
|
__bend_from___b1:
|
|
jmp __bend
|
|
// @end
|
|
__bend:
|
|
// main
|
|
main: {
|
|
// Working memory copy of string
|
|
.label sc = 4
|
|
.label camelot = 2
|
|
.label i = 6
|
|
.label sc2 = 9
|
|
.label reigns = 7
|
|
.label i1 = $b
|
|
// [5] phi from main to main::@1 [phi:main->main::@1]
|
|
__b1_from_main:
|
|
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
|
lda #0
|
|
sta.z i
|
|
// [5] phi (byte*) main::sc#2 = (const nomodify byte*) SCREEN [phi:main->main::@1#1] -- pbuz1=pbuc1
|
|
lda #<SCREEN
|
|
sta.z sc
|
|
lda #>SCREEN
|
|
sta.z sc+1
|
|
// [5] phi (byte*) main::camelot#2 = (const to_nomodify byte*) CAMELOT [phi:main->main::@1#2] -- pbuz1=pbuc1
|
|
lda #<CAMELOT
|
|
sta.z camelot
|
|
lda #>CAMELOT
|
|
sta.z camelot+1
|
|
jmp __b1
|
|
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
|
__b1_from___b1:
|
|
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
|
// [5] phi (byte*) main::sc#2 = (byte*) main::sc#1 [phi:main::@1->main::@1#1] -- register_copy
|
|
// [5] phi (byte*) main::camelot#2 = (byte*) main::camelot#1 [phi:main::@1->main::@1#2] -- register_copy
|
|
jmp __b1
|
|
// main::@1
|
|
__b1:
|
|
// [6] *((byte*) main::sc#2) ← *((byte*) main::camelot#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (camelot),y
|
|
ldy #0
|
|
sta (sc),y
|
|
// [7] (byte*) main::sc#1 ← ++ (byte*) main::sc#2 -- pbuz1=_inc_pbuz1
|
|
inc.z sc
|
|
bne !+
|
|
inc.z sc+1
|
|
!:
|
|
// [8] (byte*) main::camelot#1 ← ++ (byte*) main::camelot#2 -- pbuz1=_inc_pbuz1
|
|
inc.z camelot
|
|
bne !+
|
|
inc.z camelot+1
|
|
!:
|
|
// [9] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
|
|
inc.z i
|
|
// [10] if((byte) main::i#1!=(byte) 7) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
|
lda #7
|
|
cmp.z i
|
|
bne __b1_from___b1
|
|
// [11] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
|
__b2_from___b1:
|
|
// [11] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1
|
|
lda #0
|
|
sta.z i1
|
|
// [11] phi (byte*) main::sc2#2 = (const nomodify byte*) SCREEN+(byte) $28 [phi:main::@1->main::@2#1] -- pbuz1=pbuc1
|
|
lda #<SCREEN+$28
|
|
sta.z sc2
|
|
lda #>SCREEN+$28
|
|
sta.z sc2+1
|
|
// [11] phi (byte*) main::reigns#2 = (const byte*) main::reigns#0 [phi:main::@1->main::@2#2] -- pbuz1=pbuc1
|
|
lda #<reigns_1
|
|
sta.z reigns
|
|
lda #>reigns_1
|
|
sta.z reigns+1
|
|
jmp __b2
|
|
// [11] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
|
|
__b2_from___b2:
|
|
// [11] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy
|
|
// [11] phi (byte*) main::sc2#2 = (byte*) main::sc2#1 [phi:main::@2->main::@2#1] -- register_copy
|
|
// [11] phi (byte*) main::reigns#2 = (byte*) main::reigns#1 [phi:main::@2->main::@2#2] -- register_copy
|
|
jmp __b2
|
|
// main::@2
|
|
__b2:
|
|
// [12] *((byte*) main::sc2#2) ← *((byte*) main::reigns#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (reigns),y
|
|
ldy #0
|
|
sta (sc2),y
|
|
// [13] (byte*) main::sc2#1 ← ++ (byte*) main::sc2#2 -- pbuz1=_inc_pbuz1
|
|
inc.z sc2
|
|
bne !+
|
|
inc.z sc2+1
|
|
!:
|
|
// [14] (byte*) main::reigns#1 ← ++ (byte*) main::reigns#2 -- pbuz1=_inc_pbuz1
|
|
inc.z reigns
|
|
bne !+
|
|
inc.z reigns+1
|
|
!:
|
|
// [15] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuz1=_inc_vbuz1
|
|
inc.z i1
|
|
// [16] if((byte) main::i1#1!=(byte) 6) goto main::@2 -- vbuz1_neq_vbuc1_then_la1
|
|
lda #6
|
|
cmp.z i1
|
|
bne __b2_from___b2
|
|
// [17] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
|
|
__b3_from___b2:
|
|
jmp __b3
|
|
// main::@3
|
|
__b3:
|
|
// [18] call memcpy
|
|
// [22] phi from main::@3 to memcpy [phi:main::@3->memcpy]
|
|
memcpy_from___b3:
|
|
// [22] phi (word) memcpy::num#2 = (byte) 7 [phi:main::@3->memcpy#0] -- vwuz1=vbuc1
|
|
lda #<7
|
|
sta.z memcpy.num
|
|
lda #>7
|
|
sta.z memcpy.num+1
|
|
// [22] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) SCREEN+(byte) $a [phi:main::@3->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN+$a
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN+$a
|
|
sta.z memcpy.destination+1
|
|
// [22] phi (void*) memcpy::source#2 = (void*)(const to_nomodify byte*) CAMELOT [phi:main::@3->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<CAMELOT
|
|
sta.z memcpy.source
|
|
lda #>CAMELOT
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
// [19] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
|
|
__b4_from___b3:
|
|
jmp __b4
|
|
// main::@4
|
|
__b4:
|
|
// [20] call memcpy
|
|
// [22] phi from main::@4 to memcpy [phi:main::@4->memcpy]
|
|
memcpy_from___b4:
|
|
// [22] phi (word) memcpy::num#2 = (byte) 5 [phi:main::@4->memcpy#0] -- vwuz1=vbuc1
|
|
lda #<5
|
|
sta.z memcpy.num
|
|
lda #>5
|
|
sta.z memcpy.num+1
|
|
// [22] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) SCREEN+(byte) $32 [phi:main::@4->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN+$32
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN+$32
|
|
sta.z memcpy.destination+1
|
|
// [22] phi (void*) memcpy::source#2 = (void*)(const byte*) main::$5 [phi:main::@4->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<__5
|
|
sta.z memcpy.source
|
|
lda #>__5
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
jmp __breturn
|
|
// main::@return
|
|
__breturn:
|
|
// [21] return
|
|
rts
|
|
__5: .text "rules"
|
|
.byte 0
|
|
reigns_1: .text "reigns"
|
|
.byte 0
|
|
}
|
|
// 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($e) destination, void* zp($c) source, word zp($10) num)
|
|
memcpy: {
|
|
.label src_end = $16
|
|
.label dst = $14
|
|
.label src = $12
|
|
.label source = $c
|
|
.label destination = $e
|
|
.label num = $10
|
|
// [23] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) memcpy::num#2 -- pbuz1=pbuz2_plus_vwuz3
|
|
lda.z source
|
|
clc
|
|
adc.z num
|
|
sta.z src_end
|
|
lda.z source+1
|
|
adc.z num+1
|
|
sta.z src_end+1
|
|
// [24] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 -- pbuz1=pbuz2
|
|
lda.z source
|
|
sta.z src
|
|
lda.z source+1
|
|
sta.z src+1
|
|
// [25] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 -- pbuz1=pbuz2
|
|
lda.z destination
|
|
sta.z dst
|
|
lda.z destination+1
|
|
sta.z dst+1
|
|
// [26] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
|
|
__b1_from_memcpy:
|
|
__b1_from___b2:
|
|
// [26] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy
|
|
// [26] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy
|
|
jmp __b1
|
|
// memcpy::@1
|
|
__b1:
|
|
// [27] if((byte*) memcpy::src#2!=(byte*) 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:
|
|
// [28] return
|
|
rts
|
|
// memcpy::@2
|
|
__b2:
|
|
// [29] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (src),y
|
|
ldy #0
|
|
sta (dst),y
|
|
// [30] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
|
inc.z dst
|
|
bne !+
|
|
inc.z dst+1
|
|
!:
|
|
// [31] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
|
inc.z src
|
|
bne !+
|
|
inc.z src+1
|
|
!:
|
|
jmp __b1_from___b2
|
|
}
|
|
// File Data
|
|
CAMELOT: .text "camelot"
|
|
.byte 0
|
|
|
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
|
Statement [6] *((byte*) main::sc#2) ← *((byte*) main::camelot#2) [ main::camelot#2 main::sc#2 main::i#2 ] ( main:2 [ main::camelot#2 main::sc#2 main::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Removing always clobbered register reg byte a as potential for zp[1]:6 [ main::i#2 main::i#1 ]
|
|
Removing always clobbered register reg byte y as potential for zp[1]:6 [ main::i#2 main::i#1 ]
|
|
Statement [12] *((byte*) main::sc2#2) ← *((byte*) main::reigns#2) [ main::reigns#2 main::sc2#2 main::i1#2 ] ( main:2 [ main::reigns#2 main::sc2#2 main::i1#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Removing always clobbered register reg byte a as potential for zp[1]:11 [ main::i1#2 main::i1#1 ]
|
|
Removing always clobbered register reg byte y as potential for zp[1]:11 [ main::i1#2 main::i1#1 ]
|
|
Statement [23] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) memcpy::num#2 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( main:2::memcpy:18 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { } main:2::memcpy:20 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { } ) always clobbers reg byte a
|
|
Statement [24] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( main:2::memcpy:18 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { } main:2::memcpy:20 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { } ) always clobbers reg byte a
|
|
Statement [25] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( main:2::memcpy:18 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { } main:2::memcpy:20 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { } ) always clobbers reg byte a
|
|
Statement [27] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:18 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } main:2::memcpy:20 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } ) always clobbers reg byte a
|
|
Statement [29] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:18 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } main:2::memcpy:20 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Statement [6] *((byte*) main::sc#2) ← *((byte*) main::camelot#2) [ main::camelot#2 main::sc#2 main::i#2 ] ( main:2 [ main::camelot#2 main::sc#2 main::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Statement [12] *((byte*) main::sc2#2) ← *((byte*) main::reigns#2) [ main::reigns#2 main::sc2#2 main::i1#2 ] ( main:2 [ main::reigns#2 main::sc2#2 main::i1#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Statement [23] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) memcpy::num#2 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( main:2::memcpy:18 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { } main:2::memcpy:20 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { } ) always clobbers reg byte a
|
|
Statement [24] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( main:2::memcpy:18 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { } main:2::memcpy:20 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { } ) always clobbers reg byte a
|
|
Statement [25] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( main:2::memcpy:18 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { } main:2::memcpy:20 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { } ) always clobbers reg byte a
|
|
Statement [27] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:18 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } main:2::memcpy:20 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } ) always clobbers reg byte a
|
|
Statement [29] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:18 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } main:2::memcpy:20 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { } ) always clobbers reg byte a reg byte y
|
|
Potential registers zp[2]:2 [ main::camelot#2 main::camelot#1 ] : zp[2]:2 ,
|
|
Potential registers zp[2]:4 [ main::sc#2 main::sc#1 ] : zp[2]:4 ,
|
|
Potential registers zp[1]:6 [ main::i#2 main::i#1 ] : zp[1]:6 , reg byte x ,
|
|
Potential registers zp[2]:7 [ main::reigns#2 main::reigns#1 ] : zp[2]:7 ,
|
|
Potential registers zp[2]:9 [ main::sc2#2 main::sc2#1 ] : zp[2]:9 ,
|
|
Potential registers zp[1]:11 [ main::i1#2 main::i1#1 ] : zp[1]:11 , reg byte x ,
|
|
Potential registers zp[2]:12 [ memcpy::source#2 ] : zp[2]:12 ,
|
|
Potential registers zp[2]:14 [ memcpy::destination#2 ] : zp[2]:14 ,
|
|
Potential registers zp[2]:16 [ memcpy::num#2 ] : zp[2]:16 ,
|
|
Potential registers zp[2]:18 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] : zp[2]:18 ,
|
|
Potential registers zp[2]:20 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp[2]:20 ,
|
|
Potential registers zp[2]:22 [ memcpy::src_end#0 ] : zp[2]:22 ,
|
|
|
|
REGISTER UPLIFT SCOPES
|
|
Uplift Scope [memcpy] 3,129.25: zp[2]:18 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 2,237.67: zp[2]:20 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 137.75: zp[2]:22 [ memcpy::src_end#0 ] 101: zp[2]:16 [ memcpy::num#2 ] 0: zp[2]:12 [ memcpy::source#2 ] 0: zp[2]:14 [ memcpy::destination#2 ]
|
|
Uplift Scope [main] 202: zp[2]:4 [ main::sc#2 main::sc#1 ] 202: zp[1]:6 [ main::i#2 main::i#1 ] 202: zp[2]:9 [ main::sc2#2 main::sc2#1 ] 202: zp[1]:11 [ main::i1#2 main::i1#1 ] 168.33: zp[2]:2 [ main::camelot#2 main::camelot#1 ] 168.33: zp[2]:7 [ main::reigns#2 main::reigns#1 ]
|
|
Uplift Scope []
|
|
|
|
Uplifting [memcpy] best 2494 combination zp[2]:18 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp[2]:20 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp[2]:22 [ memcpy::src_end#0 ] zp[2]:16 [ memcpy::num#2 ] zp[2]:12 [ memcpy::source#2 ] zp[2]:14 [ memcpy::destination#2 ]
|
|
Uplifting [main] best 2314 combination zp[2]:4 [ main::sc#2 main::sc#1 ] reg byte x [ main::i#2 main::i#1 ] zp[2]:9 [ main::sc2#2 main::sc2#1 ] reg byte x [ main::i1#2 main::i1#1 ] zp[2]:2 [ main::camelot#2 main::camelot#1 ] zp[2]:7 [ main::reigns#2 main::reigns#1 ]
|
|
Uplifting [] best 2314 combination
|
|
Coalescing zero page register [ zp[2]:12 [ memcpy::source#2 ] ] with [ zp[2]:18 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1
|
|
Coalescing zero page register [ zp[2]:14 [ memcpy::destination#2 ] ] with [ zp[2]:20 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1
|
|
Coalescing zero page register [ zp[2]:16 [ memcpy::num#2 ] ] with [ zp[2]:22 [ memcpy::src_end#0 ] ] - score: 1
|
|
Allocated (was zp[2]:7) zp[2]:6 [ main::reigns#2 main::reigns#1 ]
|
|
Allocated (was zp[2]:9) zp[2]:8 [ main::sc2#2 main::sc2#1 ]
|
|
Allocated (was zp[2]:12) zp[2]:10 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
Allocated (was zp[2]:14) zp[2]:12 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
Allocated (was zp[2]:16) zp[2]:14 [ memcpy::num#2 memcpy::src_end#0 ]
|
|
|
|
ASSEMBLER BEFORE OPTIMIZATION
|
|
// File Comments
|
|
// Test memcpy on strings (
|
|
// Upstart
|
|
.pc = $801 "Basic"
|
|
:BasicUpstart(main)
|
|
.pc = $80d "Program"
|
|
// Global Constants & labels
|
|
.label SCREEN = $400
|
|
// @begin
|
|
__bbegin:
|
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
|
__b1_from___bbegin:
|
|
jmp __b1
|
|
// @1
|
|
__b1:
|
|
// [2] call main
|
|
// [4] phi from @1 to main [phi:@1->main]
|
|
main_from___b1:
|
|
jsr main
|
|
// [3] phi from @1 to @end [phi:@1->@end]
|
|
__bend_from___b1:
|
|
jmp __bend
|
|
// @end
|
|
__bend:
|
|
// main
|
|
main: {
|
|
// Working memory copy of string
|
|
.label sc = 4
|
|
.label camelot = 2
|
|
.label sc2 = 8
|
|
.label reigns = 6
|
|
// [5] phi from main to main::@1 [phi:main->main::@1]
|
|
__b1_from_main:
|
|
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
|
ldx #0
|
|
// [5] phi (byte*) main::sc#2 = (const nomodify byte*) SCREEN [phi:main->main::@1#1] -- pbuz1=pbuc1
|
|
lda #<SCREEN
|
|
sta.z sc
|
|
lda #>SCREEN
|
|
sta.z sc+1
|
|
// [5] phi (byte*) main::camelot#2 = (const to_nomodify byte*) CAMELOT [phi:main->main::@1#2] -- pbuz1=pbuc1
|
|
lda #<CAMELOT
|
|
sta.z camelot
|
|
lda #>CAMELOT
|
|
sta.z camelot+1
|
|
jmp __b1
|
|
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
|
__b1_from___b1:
|
|
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
|
// [5] phi (byte*) main::sc#2 = (byte*) main::sc#1 [phi:main::@1->main::@1#1] -- register_copy
|
|
// [5] phi (byte*) main::camelot#2 = (byte*) main::camelot#1 [phi:main::@1->main::@1#2] -- register_copy
|
|
jmp __b1
|
|
// main::@1
|
|
__b1:
|
|
// [6] *((byte*) main::sc#2) ← *((byte*) main::camelot#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (camelot),y
|
|
ldy #0
|
|
sta (sc),y
|
|
// [7] (byte*) main::sc#1 ← ++ (byte*) main::sc#2 -- pbuz1=_inc_pbuz1
|
|
inc.z sc
|
|
bne !+
|
|
inc.z sc+1
|
|
!:
|
|
// [8] (byte*) main::camelot#1 ← ++ (byte*) main::camelot#2 -- pbuz1=_inc_pbuz1
|
|
inc.z camelot
|
|
bne !+
|
|
inc.z camelot+1
|
|
!:
|
|
// [9] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
|
inx
|
|
// [10] if((byte) main::i#1!=(byte) 7) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
|
cpx #7
|
|
bne __b1_from___b1
|
|
// [11] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
|
__b2_from___b1:
|
|
// [11] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1
|
|
ldx #0
|
|
// [11] phi (byte*) main::sc2#2 = (const nomodify byte*) SCREEN+(byte) $28 [phi:main::@1->main::@2#1] -- pbuz1=pbuc1
|
|
lda #<SCREEN+$28
|
|
sta.z sc2
|
|
lda #>SCREEN+$28
|
|
sta.z sc2+1
|
|
// [11] phi (byte*) main::reigns#2 = (const byte*) main::reigns#0 [phi:main::@1->main::@2#2] -- pbuz1=pbuc1
|
|
lda #<reigns_1
|
|
sta.z reigns
|
|
lda #>reigns_1
|
|
sta.z reigns+1
|
|
jmp __b2
|
|
// [11] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
|
|
__b2_from___b2:
|
|
// [11] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy
|
|
// [11] phi (byte*) main::sc2#2 = (byte*) main::sc2#1 [phi:main::@2->main::@2#1] -- register_copy
|
|
// [11] phi (byte*) main::reigns#2 = (byte*) main::reigns#1 [phi:main::@2->main::@2#2] -- register_copy
|
|
jmp __b2
|
|
// main::@2
|
|
__b2:
|
|
// [12] *((byte*) main::sc2#2) ← *((byte*) main::reigns#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (reigns),y
|
|
ldy #0
|
|
sta (sc2),y
|
|
// [13] (byte*) main::sc2#1 ← ++ (byte*) main::sc2#2 -- pbuz1=_inc_pbuz1
|
|
inc.z sc2
|
|
bne !+
|
|
inc.z sc2+1
|
|
!:
|
|
// [14] (byte*) main::reigns#1 ← ++ (byte*) main::reigns#2 -- pbuz1=_inc_pbuz1
|
|
inc.z reigns
|
|
bne !+
|
|
inc.z reigns+1
|
|
!:
|
|
// [15] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuxx=_inc_vbuxx
|
|
inx
|
|
// [16] if((byte) main::i1#1!=(byte) 6) goto main::@2 -- vbuxx_neq_vbuc1_then_la1
|
|
cpx #6
|
|
bne __b2_from___b2
|
|
// [17] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
|
|
__b3_from___b2:
|
|
jmp __b3
|
|
// main::@3
|
|
__b3:
|
|
// [18] call memcpy
|
|
// [22] phi from main::@3 to memcpy [phi:main::@3->memcpy]
|
|
memcpy_from___b3:
|
|
// [22] phi (word) memcpy::num#2 = (byte) 7 [phi:main::@3->memcpy#0] -- vwuz1=vbuc1
|
|
lda #<7
|
|
sta.z memcpy.num
|
|
lda #>7
|
|
sta.z memcpy.num+1
|
|
// [22] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) SCREEN+(byte) $a [phi:main::@3->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN+$a
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN+$a
|
|
sta.z memcpy.destination+1
|
|
// [22] phi (void*) memcpy::source#2 = (void*)(const to_nomodify byte*) CAMELOT [phi:main::@3->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<CAMELOT
|
|
sta.z memcpy.source
|
|
lda #>CAMELOT
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
// [19] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
|
|
__b4_from___b3:
|
|
jmp __b4
|
|
// main::@4
|
|
__b4:
|
|
// [20] call memcpy
|
|
// [22] phi from main::@4 to memcpy [phi:main::@4->memcpy]
|
|
memcpy_from___b4:
|
|
// [22] phi (word) memcpy::num#2 = (byte) 5 [phi:main::@4->memcpy#0] -- vwuz1=vbuc1
|
|
lda #<5
|
|
sta.z memcpy.num
|
|
lda #>5
|
|
sta.z memcpy.num+1
|
|
// [22] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) SCREEN+(byte) $32 [phi:main::@4->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN+$32
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN+$32
|
|
sta.z memcpy.destination+1
|
|
// [22] phi (void*) memcpy::source#2 = (void*)(const byte*) main::$5 [phi:main::@4->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<__5
|
|
sta.z memcpy.source
|
|
lda #>__5
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
jmp __breturn
|
|
// main::@return
|
|
__breturn:
|
|
// [21] return
|
|
rts
|
|
__5: .text "rules"
|
|
.byte 0
|
|
reigns_1: .text "reigns"
|
|
.byte 0
|
|
}
|
|
// 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($c) destination, void* zp($a) source, word zp($e) num)
|
|
memcpy: {
|
|
.label src_end = $e
|
|
.label dst = $c
|
|
.label src = $a
|
|
.label source = $a
|
|
.label destination = $c
|
|
.label num = $e
|
|
// [23] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) 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
|
|
// [24] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
|
|
// [25] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
|
|
// [26] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
|
|
__b1_from_memcpy:
|
|
__b1_from___b2:
|
|
// [26] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy
|
|
// [26] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy
|
|
jmp __b1
|
|
// memcpy::@1
|
|
__b1:
|
|
// [27] if((byte*) memcpy::src#2!=(byte*) 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:
|
|
// [28] return
|
|
rts
|
|
// memcpy::@2
|
|
__b2:
|
|
// [29] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (src),y
|
|
ldy #0
|
|
sta (dst),y
|
|
// [30] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
|
inc.z dst
|
|
bne !+
|
|
inc.z dst+1
|
|
!:
|
|
// [31] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
|
inc.z src
|
|
bne !+
|
|
inc.z src+1
|
|
!:
|
|
jmp __b1_from___b2
|
|
}
|
|
// File Data
|
|
CAMELOT: .text "camelot"
|
|
.byte 0
|
|
|
|
ASSEMBLER OPTIMIZATIONS
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __bend
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __b2
|
|
Removing instruction jmp __b3
|
|
Removing instruction jmp __b4
|
|
Removing instruction jmp __breturn
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __breturn
|
|
Succesful ASM optimization Pass5NextJumpElimination
|
|
Removing instruction ldy #0
|
|
Removing instruction ldy #0
|
|
Removing instruction ldy #0
|
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
|
Replacing label __b1_from___b1 with __b1
|
|
Replacing label __b2_from___b2 with __b2
|
|
Replacing label __b1_from___b2 with __b1
|
|
Removing instruction __b1_from___bbegin:
|
|
Removing instruction __b1:
|
|
Removing instruction main_from___b1:
|
|
Removing instruction __bend_from___b1:
|
|
Removing instruction __b1_from___b1:
|
|
Removing instruction __b2_from___b2:
|
|
Removing instruction __b3_from___b2:
|
|
Removing instruction memcpy_from___b3:
|
|
Removing instruction __b4_from___b3:
|
|
Removing instruction memcpy_from___b4:
|
|
Removing instruction __b1_from_memcpy:
|
|
Removing instruction __b1_from___b2:
|
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
|
Removing instruction __bbegin:
|
|
Removing instruction __bend:
|
|
Removing instruction __b1_from_main:
|
|
Removing instruction __b2_from___b1:
|
|
Removing instruction __b3:
|
|
Removing instruction __b4:
|
|
Removing instruction __breturn:
|
|
Removing instruction __breturn:
|
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
|
Removing instruction jsr main
|
|
Succesful ASM optimization Pass5SkipBegin
|
|
Removing instruction jmp __b1
|
|
Removing instruction jmp __b2
|
|
Succesful ASM optimization Pass5NextJumpElimination
|
|
|
|
FINAL SYMBOL TABLE
|
|
(label) @1
|
|
(label) @begin
|
|
(label) @end
|
|
(const to_nomodify byte*) CAMELOT[] = (byte*) "camelot"
|
|
(const nomodify byte*) SCREEN = (byte*) 1024
|
|
(void()) main()
|
|
(const byte*) main::$5[(byte) 6] = (byte*) "rules"
|
|
(label) main::@1
|
|
(label) main::@2
|
|
(label) main::@3
|
|
(label) main::@4
|
|
(label) main::@return
|
|
(byte*) main::camelot
|
|
(byte*) main::camelot#1 camelot zp[2]:2 67.33333333333333
|
|
(byte*) main::camelot#2 camelot zp[2]:2 101.0
|
|
(byte) main::i
|
|
(byte) main::i#1 reg byte x 151.5
|
|
(byte) main::i#2 reg byte x 50.5
|
|
(byte) main::i1
|
|
(byte) main::i1#1 reg byte x 151.5
|
|
(byte) main::i1#2 reg byte x 50.5
|
|
(byte*) main::reigns
|
|
(const byte*) main::reigns#0 reigns_1 = (byte*) "reigns"
|
|
(byte*) main::reigns#1 reigns zp[2]:6 67.33333333333333
|
|
(byte*) main::reigns#2 reigns zp[2]:6 101.0
|
|
(byte*) main::sc
|
|
(byte*) main::sc#1 sc zp[2]:4 50.5
|
|
(byte*) main::sc#2 sc zp[2]:4 151.5
|
|
(byte*) main::sc2
|
|
(byte*) main::sc2#1 sc2 zp[2]:8 50.5
|
|
(byte*) main::sc2#2 sc2 zp[2]:8 151.5
|
|
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
|
|
(label) memcpy::@1
|
|
(label) memcpy::@2
|
|
(label) memcpy::@return
|
|
(void*) memcpy::destination
|
|
(void*) memcpy::destination#2 destination zp[2]:12
|
|
(byte*) memcpy::dst
|
|
(byte*) memcpy::dst#1 dst zp[2]:12 1001.0
|
|
(byte*) memcpy::dst#2 dst zp[2]:12 1034.6666666666667
|
|
(byte*) memcpy::dst#4 dst zp[2]:12 202.0
|
|
(word) memcpy::num
|
|
(word) memcpy::num#2 num zp[2]:14 101.0
|
|
(void*) memcpy::return
|
|
(void*) memcpy::source
|
|
(void*) memcpy::source#2 source zp[2]:10
|
|
(byte*) memcpy::src
|
|
(byte*) memcpy::src#1 src zp[2]:10 2002.0
|
|
(byte*) memcpy::src#2 src zp[2]:10 1026.25
|
|
(byte*) memcpy::src#4 src zp[2]:10 101.0
|
|
(byte*) memcpy::src_end
|
|
(byte*) memcpy::src_end#0 src_end zp[2]:14 137.75
|
|
|
|
zp[2]:2 [ main::camelot#2 main::camelot#1 ]
|
|
zp[2]:4 [ main::sc#2 main::sc#1 ]
|
|
reg byte x [ main::i#2 main::i#1 ]
|
|
zp[2]:6 [ main::reigns#2 main::reigns#1 ]
|
|
zp[2]:8 [ main::sc2#2 main::sc2#1 ]
|
|
reg byte x [ main::i1#2 main::i1#1 ]
|
|
zp[2]:10 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
|
|
zp[2]:12 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
|
|
zp[2]:14 [ memcpy::num#2 memcpy::src_end#0 ]
|
|
|
|
|
|
FINAL ASSEMBLER
|
|
Score: 2029
|
|
|
|
// File Comments
|
|
// Test memcpy on strings (
|
|
// Upstart
|
|
.pc = $801 "Basic"
|
|
:BasicUpstart(main)
|
|
.pc = $80d "Program"
|
|
// Global Constants & labels
|
|
.label SCREEN = $400
|
|
// @begin
|
|
// [1] phi from @begin to @1 [phi:@begin->@1]
|
|
// @1
|
|
// [2] call main
|
|
// [4] phi from @1 to main [phi:@1->main]
|
|
// [3] phi from @1 to @end [phi:@1->@end]
|
|
// @end
|
|
// main
|
|
main: {
|
|
// Working memory copy of string
|
|
.label sc = 4
|
|
.label camelot = 2
|
|
.label sc2 = 8
|
|
.label reigns = 6
|
|
// [5] phi from main to main::@1 [phi:main->main::@1]
|
|
// [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
|
ldx #0
|
|
// [5] phi (byte*) main::sc#2 = (const nomodify byte*) SCREEN [phi:main->main::@1#1] -- pbuz1=pbuc1
|
|
lda #<SCREEN
|
|
sta.z sc
|
|
lda #>SCREEN
|
|
sta.z sc+1
|
|
// [5] phi (byte*) main::camelot#2 = (const to_nomodify byte*) CAMELOT [phi:main->main::@1#2] -- pbuz1=pbuc1
|
|
lda #<CAMELOT
|
|
sta.z camelot
|
|
lda #>CAMELOT
|
|
sta.z camelot+1
|
|
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
|
// [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
|
// [5] phi (byte*) main::sc#2 = (byte*) main::sc#1 [phi:main::@1->main::@1#1] -- register_copy
|
|
// [5] phi (byte*) main::camelot#2 = (byte*) main::camelot#1 [phi:main::@1->main::@1#2] -- register_copy
|
|
// main::@1
|
|
__b1:
|
|
// *sc++ = *camelot++
|
|
// [6] *((byte*) main::sc#2) ← *((byte*) main::camelot#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (camelot),y
|
|
sta (sc),y
|
|
// *sc++ = *camelot++;
|
|
// [7] (byte*) main::sc#1 ← ++ (byte*) main::sc#2 -- pbuz1=_inc_pbuz1
|
|
inc.z sc
|
|
bne !+
|
|
inc.z sc+1
|
|
!:
|
|
// [8] (byte*) main::camelot#1 ← ++ (byte*) main::camelot#2 -- pbuz1=_inc_pbuz1
|
|
inc.z camelot
|
|
bne !+
|
|
inc.z camelot+1
|
|
!:
|
|
// for( char i: 0..6)
|
|
// [9] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx
|
|
inx
|
|
// [10] if((byte) main::i#1!=(byte) 7) goto main::@1 -- vbuxx_neq_vbuc1_then_la1
|
|
cpx #7
|
|
bne __b1
|
|
// [11] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
|
// [11] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1
|
|
ldx #0
|
|
// [11] phi (byte*) main::sc2#2 = (const nomodify byte*) SCREEN+(byte) $28 [phi:main::@1->main::@2#1] -- pbuz1=pbuc1
|
|
lda #<SCREEN+$28
|
|
sta.z sc2
|
|
lda #>SCREEN+$28
|
|
sta.z sc2+1
|
|
// [11] phi (byte*) main::reigns#2 = (const byte*) main::reigns#0 [phi:main::@1->main::@2#2] -- pbuz1=pbuc1
|
|
lda #<reigns_1
|
|
sta.z reigns
|
|
lda #>reigns_1
|
|
sta.z reigns+1
|
|
// [11] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
|
|
// [11] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy
|
|
// [11] phi (byte*) main::sc2#2 = (byte*) main::sc2#1 [phi:main::@2->main::@2#1] -- register_copy
|
|
// [11] phi (byte*) main::reigns#2 = (byte*) main::reigns#1 [phi:main::@2->main::@2#2] -- register_copy
|
|
// main::@2
|
|
__b2:
|
|
// *sc2++ = *reigns++
|
|
// [12] *((byte*) main::sc2#2) ← *((byte*) main::reigns#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (reigns),y
|
|
sta (sc2),y
|
|
// *sc2++ = *reigns++;
|
|
// [13] (byte*) main::sc2#1 ← ++ (byte*) main::sc2#2 -- pbuz1=_inc_pbuz1
|
|
inc.z sc2
|
|
bne !+
|
|
inc.z sc2+1
|
|
!:
|
|
// [14] (byte*) main::reigns#1 ← ++ (byte*) main::reigns#2 -- pbuz1=_inc_pbuz1
|
|
inc.z reigns
|
|
bne !+
|
|
inc.z reigns+1
|
|
!:
|
|
// for( char i: 0..5)
|
|
// [15] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuxx=_inc_vbuxx
|
|
inx
|
|
// [16] if((byte) main::i1#1!=(byte) 6) goto main::@2 -- vbuxx_neq_vbuc1_then_la1
|
|
cpx #6
|
|
bne __b2
|
|
// [17] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
|
|
// main::@3
|
|
// memcpy(SCREEN+10, CAMELOT, 7)
|
|
// [18] call memcpy
|
|
// [22] phi from main::@3 to memcpy [phi:main::@3->memcpy]
|
|
// [22] phi (word) memcpy::num#2 = (byte) 7 [phi:main::@3->memcpy#0] -- vwuz1=vbuc1
|
|
lda #<7
|
|
sta.z memcpy.num
|
|
lda #>7
|
|
sta.z memcpy.num+1
|
|
// [22] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) SCREEN+(byte) $a [phi:main::@3->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN+$a
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN+$a
|
|
sta.z memcpy.destination+1
|
|
// [22] phi (void*) memcpy::source#2 = (void*)(const to_nomodify byte*) CAMELOT [phi:main::@3->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<CAMELOT
|
|
sta.z memcpy.source
|
|
lda #>CAMELOT
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
// [19] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
|
|
// main::@4
|
|
// memcpy(SCREEN+50, "rules", 5)
|
|
// [20] call memcpy
|
|
// [22] phi from main::@4 to memcpy [phi:main::@4->memcpy]
|
|
// [22] phi (word) memcpy::num#2 = (byte) 5 [phi:main::@4->memcpy#0] -- vwuz1=vbuc1
|
|
lda #<5
|
|
sta.z memcpy.num
|
|
lda #>5
|
|
sta.z memcpy.num+1
|
|
// [22] phi (void*) memcpy::destination#2 = (void*)(const nomodify byte*) SCREEN+(byte) $32 [phi:main::@4->memcpy#1] -- pvoz1=pvoc1
|
|
lda #<SCREEN+$32
|
|
sta.z memcpy.destination
|
|
lda #>SCREEN+$32
|
|
sta.z memcpy.destination+1
|
|
// [22] phi (void*) memcpy::source#2 = (void*)(const byte*) main::$5 [phi:main::@4->memcpy#2] -- pvoz1=pvoc1
|
|
lda #<__5
|
|
sta.z memcpy.source
|
|
lda #>__5
|
|
sta.z memcpy.source+1
|
|
jsr memcpy
|
|
// main::@return
|
|
// }
|
|
// [21] return
|
|
rts
|
|
__5: .text "rules"
|
|
.byte 0
|
|
reigns_1: .text "reigns"
|
|
.byte 0
|
|
}
|
|
// 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($c) destination, void* zp($a) source, word zp($e) num)
|
|
memcpy: {
|
|
.label src_end = $e
|
|
.label dst = $c
|
|
.label src = $a
|
|
.label source = $a
|
|
.label destination = $c
|
|
.label num = $e
|
|
// src_end = (char*)source+num
|
|
// [23] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) 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
|
|
// [24] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
|
|
// [25] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
|
|
// [26] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
|
|
// [26] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy
|
|
// [26] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy
|
|
// memcpy::@1
|
|
__b1:
|
|
// while(src!=src_end)
|
|
// [27] if((byte*) memcpy::src#2!=(byte*) 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
|
|
// }
|
|
// [28] return
|
|
rts
|
|
// memcpy::@2
|
|
__b2:
|
|
// *dst++ = *src++
|
|
// [29] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2
|
|
ldy #0
|
|
lda (src),y
|
|
sta (dst),y
|
|
// *dst++ = *src++;
|
|
// [30] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1
|
|
inc.z dst
|
|
bne !+
|
|
inc.z dst+1
|
|
!:
|
|
// [31] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1
|
|
inc.z src
|
|
bne !+
|
|
inc.z src+1
|
|
!:
|
|
jmp __b1
|
|
}
|
|
// File Data
|
|
CAMELOT: .text "camelot"
|
|
.byte 0
|
|
|