Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src)
Warning! Adding boolean cast to non-boolean condition *((byte*) strlen::str)
Identified constant variable (byte*) SCREEN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx 
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3
Culled Empty Block (label) @4
Culled Empty Block (label) memcpy::@4
Culled Empty Block (label) memcpy::@5
Culled Empty Block (label) memcpy::@6
Culled Empty Block (label) memcpy::@7
Culled Empty Block (label) @5
Culled Empty Block (label) @6
Culled Empty Block (label) @7
Culled Empty Block (label) @8
Culled Empty Block (label) @9
Culled Empty Block (label) main::@4
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@5
Culled Empty Block (label) main::@6

CONTROL FLOW GRAPH SSA
@begin: scope:[]  from
  to:@10

(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
memcpy: scope:[memcpy]  from main main::@7
  (word) memcpy::num#2 ← phi( main/(word) memcpy::num#0 main::@7/(word) memcpy::num#1 )
  (void*) memcpy::destination#2 ← phi( main/(void*) memcpy::destination#0 main::@7/(void*) memcpy::destination#1 )
  (void*) memcpy::source#2 ← phi( main/(void*) memcpy::source#0 main::@7/(void*) memcpy::source#1 )
  (byte*) memcpy::src#0 ← ((byte*)) (void*) memcpy::source#2
  (byte*) memcpy::dst#0 ← ((byte*)) (void*) memcpy::destination#2
  (byte*~) memcpy::$0 ← ((byte*)) (void*) memcpy::source#2
  (byte*~) memcpy::$1 ← (byte*~) memcpy::$0 + (word) memcpy::num#2
  (byte*) memcpy::src_end#0 ← (byte*~) memcpy::$1
  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::$2 ← (byte*) memcpy::src#2 != (byte*) memcpy::src_end#1
  if((bool~) memcpy::$2) 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 @10
  *((const byte*) BGCOL) ← (const byte) BLACK
  (void*) memcpy::destination#0 ← (void*)(const byte*) SCREEN
  (void*) memcpy::source#0 ← (void*)(const byte*) MEDUSA_SCREEN
  (word) memcpy::num#0 ← (number) $3e8
  call memcpy 
  (void*) memcpy::return#2 ← (void*) memcpy::return#1
  to:main::@7
main::@7: scope:[main]  from main
  (void*) memcpy::destination#1 ← (void*)(const byte*) COLS
  (void*) memcpy::source#1 ← (void*)(const byte*) MEDUSA_COLORS
  (word) memcpy::num#1 ← (number) $3e8
  call memcpy 
  (void*) memcpy::return#3 ← (void*) memcpy::return#1
  to:main::@8
main::@8: scope:[main]  from main::@7
  to:main::@1
main::@1: scope:[main]  from main::@2 main::@8
  if(true) goto main::@2
  to:main::@return
main::@2: scope:[main]  from main::@1
  (byte*~) main::$2 ← (const byte*) SCREEN + (number) $3e7
  *((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
  to:main::@1
main::@return: scope:[main]  from main::@1
  return 
  to:@return
@10: scope:[]  from @begin
  call main 
  to:@11
@11: scope:[]  from @10
  to:@end
@end: scope:[]  from @11

SYMBOL TABLE SSA
(label) @10
(label) @11
(label) @begin
(label) @end
(const byte*) BGCOL = (byte*)(number) $d021
(const byte) BLACK = (byte) 0
(const byte*) COLS = (byte*)(number) $d800
(const byte*) MEDUSA_COLORS[]  = kickasm {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)
 }}
(const byte*) MEDUSA_SCREEN[(number) $3e8]  = kickasm {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)
 }}
(const byte*) SCREEN = (byte*)(number) $400
(void()) main()
(byte*~) main::$2
(label) main::@1
(label) main::@2
(label) main::@7
(label) main::@8
(label) main::@return
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
(byte*~) memcpy::$0
(byte*~) memcpy::$1
(bool~) 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) $3e8 in (word) memcpy::num#0 ← (number) $3e8
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#1 ← (number) $3e8
Adding number conversion cast (unumber) $3e7 in (byte*~) main::$2 ← (const byte*) SCREEN + (number) $3e7
Adding number conversion cast (unumber) $e in *((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
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 (byte*~) memcpy::$0 ← (byte*)(void*) memcpy::source#2
Inlining cast (word) memcpy::num#0 ← (unumber)(number) $3e8
Inlining cast (word) memcpy::num#1 ← (unumber)(number) $3e8
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53281
Simplifying constant pointer cast (byte*) 55296
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $3e8
Simplifying constant integer cast $3e8
Simplifying constant integer cast $3e7
Simplifying constant integer cast $e
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (word) $3e8
Finalized unsigned number type (word) $3e8
Finalized unsigned number type (word) $3e7
Finalized unsigned number type (byte) $e
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte*) memcpy::src_end#0 = (byte*~) memcpy::$1 
Alias (byte*) memcpy::src#2 = (byte*) memcpy::src#3 
Alias (byte*) memcpy::dst#2 = (byte*) memcpy::dst#3 
Alias (byte*) memcpy::src_end#1 = (byte*) memcpy::src_end#2 
Alias (void*) memcpy::destination#3 = (void*) memcpy::destination#5 (void*) memcpy::destination#4 (void*) memcpy::return#0 (void*) memcpy::return#4 (void*) 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::$2 [7] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant right-side identified [13] (void*) memcpy::destination#0 ← (void*)(const byte*) SCREEN
Constant right-side identified [24] (byte*~) main::$2 ← (const byte*) SCREEN + (word) $3e7
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const void*) memcpy::destination#0 = (void*)SCREEN
Constant (const void*) memcpy::source#0 = (void*)MEDUSA_SCREEN
Constant (const word) memcpy::num#0 = $3e8
Constant (const void*) memcpy::destination#1 = (void*)COLS
Constant (const void*) memcpy::source#1 = (void*)MEDUSA_COLORS
Constant (const word) memcpy::num#1 = $3e8
Constant (const byte*) main::$2 = SCREEN+$3e7
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [23] if(true) goto main::@2
Successful SSA optimization Pass2ConstantIfs
Eliminating unused variable (void*) memcpy::return#2 and assignment [13] (void*) memcpy::return#2 ← (void*) memcpy::destination#2
Eliminating unused variable (void*) memcpy::return#3 and assignment [15] (void*) memcpy::return#3 ← (void*) memcpy::destination#2
Successful SSA optimization PassNEliminateUnusedVars
Removing unused block main::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
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::$0 ← (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
Constant inlined memcpy::num#1 = (word) $3e8
Constant inlined memcpy::num#0 = (word) $3e8
Constant inlined memcpy::source#1 = (void*)(const byte*) MEDUSA_COLORS
Constant inlined main::$2 = (const byte*) SCREEN+(word) $3e7
Constant inlined memcpy::destination#0 = (void*)(const byte*) SCREEN
Constant inlined memcpy::destination#1 = (void*)(const byte*) COLS
Constant inlined memcpy::source#0 = (void*)(const byte*) MEDUSA_SCREEN
Successful SSA optimization Pass2ConstantInlining
Identical Phi Values (word) memcpy::num#2 (word) $3e8
Successful SSA optimization Pass2IdenticalPhiElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @10
Adding NOP phi() at start of @11
Adding NOP phi() at start of @end
Adding NOP phi() at start of main::@7
Adding NOP phi() at start of main::@8
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of memcpy::@3
CALL GRAPH
Calls in [] to main:2 
Calls in [main] to memcpy:6 memcpy:8 

Created 4 initial phi equivalence classes
Coalesced [23] memcpy::src#5 ← memcpy::src#1
Coalesced [24] memcpy::dst#5 ← memcpy::dst#1
Coalesced down to 4 phi equivalence classes
Culled Empty Block (label) @11
Culled Empty Block (label) main::@8
Culled Empty Block (label) main::@1
Culled Empty Block (label) memcpy::@3
Renumbering block @10 to @1
Renumbering block main::@2 to main::@1
Renumbering block main::@7 to main::@2
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::@2

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] *((const byte*) BGCOL) ← (const byte) BLACK
  [5] call memcpy 
  to:main::@2
main::@2: scope:[main]  from main
  [6] phi()
  [7] call memcpy 
  to:main::@1
main::@1: scope:[main]  from main::@1 main::@2
  [8] *((const byte*) SCREEN+(word) $3e7) ← *((const byte*) SCREEN+(word) $3e7) ^ (byte) $e
  to:main::@1

(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
memcpy: scope:[memcpy]  from main main::@2
  [9] (void*) memcpy::destination#2 ← phi( main/(void*)(const byte*) SCREEN main::@2/(void*)(const byte*) COLS )
  [9] (void*) memcpy::source#2 ← phi( main/(void*)(const byte*) MEDUSA_SCREEN main::@2/(void*)(const byte*) MEDUSA_COLORS )
  [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8
  [11] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
  [12] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
  to:memcpy::@1
memcpy::@1: scope:[memcpy]  from memcpy memcpy::@2
  [13] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*) memcpy::dst#4 memcpy::@2/(byte*) memcpy::dst#1 )
  [13] (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#4 memcpy::@2/(byte*) memcpy::src#1 )
  [14] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2
  to:memcpy::@return
memcpy::@return: scope:[memcpy]  from memcpy::@1
  [15] return 
  to:@return
memcpy::@2: scope:[memcpy]  from memcpy::@1
  [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
  [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
  [18] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
  to:memcpy::@1


VARIABLE REGISTER WEIGHTS
(void()) main()
(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 11.0
(byte*) memcpy::dst#2 11.666666666666666
(byte*) memcpy::dst#4 4.0
(word) memcpy::num
(void*) memcpy::return
(void*) memcpy::source
(void*) memcpy::source#2
(byte*) memcpy::src
(byte*) memcpy::src#1 22.0
(byte*) memcpy::src#2 11.5
(byte*) memcpy::src#4 2.0
(byte*) memcpy::src_end
(byte*) memcpy::src_end#0 1.625

Initial phi equivalence classes
[ memcpy::source#2 ]
[ memcpy::destination#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::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::src#2 memcpy::src#4 memcpy::src#1 ]
Allocated zp[2]:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
Allocated zp[2]:10 [ memcpy::src_end#0 ]

INITIAL ASM
Target platform is c64basic / MOS6502X
  // File Comments
// Display  MEDUSA PETSCII by Buzz_clik
// https://csdb.dk/release/?id=178673
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .label BGCOL = $d021
  // Color Ram
  .label COLS = $d800
  // The colors of the C64
  .const BLACK = 0
  .label SCREEN = $400
  // @begin
__bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
  jmp __b1
  // @1
__b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
  jmp __bend
  // @end
__bend:
  // main
main: {
    // [4] *((const byte*) BGCOL) ← (const byte) BLACK -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // [5] call memcpy 
    // [9] phi from main to memcpy [phi:main->memcpy]
  memcpy_from_main:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) SCREEN [phi:main->memcpy#0] -- pvoz1=pvoc1 
    lda #<SCREEN
    sta.z memcpy.destination
    lda #>SCREEN
    sta.z memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte*) MEDUSA_SCREEN [phi:main->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_SCREEN
    sta.z memcpy.source
    lda #>MEDUSA_SCREEN
    sta.z memcpy.source+1
    jsr memcpy
    // [6] phi from main to main::@2 [phi:main->main::@2]
  __b2_from_main:
    jmp __b2
    // main::@2
  __b2:
    // [7] call memcpy 
    // [9] phi from main::@2 to memcpy [phi:main::@2->memcpy]
  memcpy_from___b2:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) COLS [phi:main::@2->memcpy#0] -- pvoz1=pvoc1 
    lda #<COLS
    sta.z memcpy.destination
    lda #>COLS
    sta.z memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte*) MEDUSA_COLORS [phi:main::@2->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_COLORS
    sta.z memcpy.source
    lda #>MEDUSA_COLORS
    sta.z memcpy.source+1
    jsr memcpy
    jmp __b1
    // main::@1
  __b1:
    // [8] *((const byte*) SCREEN+(word) $3e7) ← *((const byte*) SCREEN+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2 
    lda #$e
    eor SCREEN+$3e7
    sta SCREEN+$3e7
    jmp __b1
}
  // 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)
memcpy: {
    .label src_end = $a
    .label dst = 8
    .label src = 6
    .label source = 2
    .label destination = 4
    // [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 -- pbuz1=pbuz2_plus_vwuc1 
    lda.z source
    clc
    adc #<$3e8
    sta.z src_end
    lda.z source+1
    adc #>$3e8
    sta.z src_end+1
    // [11] (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
    // [12] (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
    // [13] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
  __b1_from_memcpy:
  __b1_from___b2:
    // [13] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [13] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    jmp __b1
    // memcpy::@1
  __b1:
    // [14] 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:
    // [15] return 
    rts
    // memcpy::@2
  __b2:
    // [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    ldy #0
    sta (dst),y
    // [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [18] (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
MEDUSA_SCREEN:
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)

MEDUSA_COLORS:
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)


REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) BGCOL) ← (const byte) BLACK [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [8] *((const byte*) SCREEN+(word) $3e7) ← *((const byte*) SCREEN+(word) $3e7) ^ (byte) $e [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( main:2::memcpy:5 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] main:2::memcpy:7 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ) always clobbers reg byte a 
Statement [11] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( main:2::memcpy:5 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] main:2::memcpy:7 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ) always clobbers reg byte a 
Statement [12] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( main:2::memcpy:5 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] main:2::memcpy:7 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ) always clobbers reg byte a 
Statement [14] 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:5 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] main:2::memcpy:7 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ) always clobbers reg byte a 
Statement [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:5 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] main:2::memcpy:7 [ 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::src#2 memcpy::src#4 memcpy::src#1 ] : zp[2]:6 , 
Potential registers zp[2]:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp[2]:8 , 
Potential registers zp[2]:10 [ memcpy::src_end#0 ] : zp[2]:10 , 

REGISTER UPLIFT SCOPES
Uplift Scope [memcpy] 35.5: zp[2]:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 26.67: zp[2]:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 1.62: zp[2]:10 [ memcpy::src_end#0 ] 0: zp[2]:2 [ memcpy::source#2 ] 0: zp[2]:4 [ memcpy::destination#2 ] 
Uplift Scope [main] 
Uplift Scope [] 

Uplifting [memcpy] best 919 combination zp[2]:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp[2]:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp[2]:10 [ memcpy::src_end#0 ] zp[2]:2 [ memcpy::source#2 ] zp[2]:4 [ memcpy::destination#2 ] 
Uplifting [main] best 919 combination 
Uplifting [] best 919 combination 
Coalescing zero page register [ zp[2]:2 [ memcpy::source#2 ] ] with [ zp[2]:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1
Coalescing zero page register [ zp[2]:4 [ memcpy::destination#2 ] ] with [ zp[2]:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1
Allocated (was zp[2]:10) zp[2]:6 [ memcpy::src_end#0 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Display  MEDUSA PETSCII by Buzz_clik
// https://csdb.dk/release/?id=178673
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .label BGCOL = $d021
  // Color Ram
  .label COLS = $d800
  // The colors of the C64
  .const BLACK = 0
  .label SCREEN = $400
  // @begin
__bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
  jmp __b1
  // @1
__b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
  jmp __bend
  // @end
__bend:
  // main
main: {
    // [4] *((const byte*) BGCOL) ← (const byte) BLACK -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // [5] call memcpy 
    // [9] phi from main to memcpy [phi:main->memcpy]
  memcpy_from_main:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) SCREEN [phi:main->memcpy#0] -- pvoz1=pvoc1 
    lda #<SCREEN
    sta.z memcpy.destination
    lda #>SCREEN
    sta.z memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte*) MEDUSA_SCREEN [phi:main->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_SCREEN
    sta.z memcpy.source
    lda #>MEDUSA_SCREEN
    sta.z memcpy.source+1
    jsr memcpy
    // [6] phi from main to main::@2 [phi:main->main::@2]
  __b2_from_main:
    jmp __b2
    // main::@2
  __b2:
    // [7] call memcpy 
    // [9] phi from main::@2 to memcpy [phi:main::@2->memcpy]
  memcpy_from___b2:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) COLS [phi:main::@2->memcpy#0] -- pvoz1=pvoc1 
    lda #<COLS
    sta.z memcpy.destination
    lda #>COLS
    sta.z memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte*) MEDUSA_COLORS [phi:main::@2->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_COLORS
    sta.z memcpy.source
    lda #>MEDUSA_COLORS
    sta.z memcpy.source+1
    jsr memcpy
    jmp __b1
    // main::@1
  __b1:
    // [8] *((const byte*) SCREEN+(word) $3e7) ← *((const byte*) SCREEN+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2 
    lda #$e
    eor SCREEN+$3e7
    sta SCREEN+$3e7
    jmp __b1
}
  // 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)
memcpy: {
    .label src_end = 6
    .label dst = 4
    .label src = 2
    .label source = 2
    .label destination = 4
    // [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 -- pbuz1=pbuz2_plus_vwuc1 
    lda.z source
    clc
    adc #<$3e8
    sta.z src_end
    lda.z source+1
    adc #>$3e8
    sta.z src_end+1
    // [11] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
    // [12] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
    // [13] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
  __b1_from_memcpy:
  __b1_from___b2:
    // [13] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [13] phi (byte*) memcpy::src#2 = (byte*) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    jmp __b1
    // memcpy::@1
  __b1:
    // [14] 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:
    // [15] return 
    rts
    // memcpy::@2
  __b2:
    // [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    ldy #0
    sta (dst),y
    // [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [18] (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
MEDUSA_SCREEN:
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)

MEDUSA_COLORS:
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)


ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b2
Removing instruction jmp __b1
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Replacing label __b1_from___b2 with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1:
Removing instruction __b2_from_main:
Removing instruction memcpy_from___b2:
Removing instruction __b1_from_memcpy:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction memcpy_from_main:
Removing instruction __b2:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(const byte*) BGCOL = (byte*) 53281
(const byte) BLACK = (byte) 0
(const byte*) COLS = (byte*) 55296
(const byte*) MEDUSA_COLORS[]  = kickasm {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)
 }}
(const byte*) MEDUSA_SCREEN[(number) $3e8]  = kickasm {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)
 }}
(const byte*) SCREEN = (byte*) 1024
(void()) main()
(label) main::@1
(label) main::@2
(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]:4
(byte*) memcpy::dst
(byte*) memcpy::dst#1 dst zp[2]:4 11.0
(byte*) memcpy::dst#2 dst zp[2]:4 11.666666666666666
(byte*) memcpy::dst#4 dst zp[2]:4 4.0
(word) memcpy::num
(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 22.0
(byte*) memcpy::src#2 src zp[2]:2 11.5
(byte*) memcpy::src#4 src zp[2]:2 2.0
(byte*) memcpy::src_end
(byte*) memcpy::src_end#0 src_end zp[2]:6 1.625

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::src_end#0 ]


FINAL ASSEMBLER
Score: 797

  // File Comments
// Display  MEDUSA PETSCII by Buzz_clik
// https://csdb.dk/release/?id=178673
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  .label BGCOL = $d021
  // Color Ram
  .label COLS = $d800
  // The colors of the C64
  .const BLACK = 0
  .label SCREEN = $400
  // @begin
  // [1] phi from @begin to @1 [phi:@begin->@1]
  // @1
  // [2] call main 
  // [3] phi from @1 to @end [phi:@1->@end]
  // @end
  // main
main: {
    // *BGCOL = BLACK
    // [4] *((const byte*) BGCOL) ← (const byte) BLACK -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // memcpy(SCREEN, MEDUSA_SCREEN, 1000)
    // [5] call memcpy 
    // [9] phi from main to memcpy [phi:main->memcpy]
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) SCREEN [phi:main->memcpy#0] -- pvoz1=pvoc1 
    lda #<SCREEN
    sta.z memcpy.destination
    lda #>SCREEN
    sta.z memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte*) MEDUSA_SCREEN [phi:main->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_SCREEN
    sta.z memcpy.source
    lda #>MEDUSA_SCREEN
    sta.z memcpy.source+1
    jsr memcpy
    // [6] phi from main to main::@2 [phi:main->main::@2]
    // main::@2
    // memcpy(COLS, MEDUSA_COLORS, 1000)
    // [7] call memcpy 
    // [9] phi from main::@2 to memcpy [phi:main::@2->memcpy]
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) COLS [phi:main::@2->memcpy#0] -- pvoz1=pvoc1 
    lda #<COLS
    sta.z memcpy.destination
    lda #>COLS
    sta.z memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte*) MEDUSA_COLORS [phi:main::@2->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_COLORS
    sta.z memcpy.source
    lda #>MEDUSA_COLORS
    sta.z memcpy.source+1
    jsr memcpy
    // main::@1
  __b1:
    // (*(SCREEN+999)) ^= 0x0e
    // [8] *((const byte*) SCREEN+(word) $3e7) ← *((const byte*) SCREEN+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2 
    lda #$e
    eor SCREEN+$3e7
    sta SCREEN+$3e7
    jmp __b1
}
  // 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)
memcpy: {
    .label src_end = 6
    .label dst = 4
    .label src = 2
    .label source = 2
    .label destination = 4
    // src_end = (char*)source+num
    // [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 -- pbuz1=pbuz2_plus_vwuc1 
    lda.z source
    clc
    adc #<$3e8
    sta.z src_end
    lda.z source+1
    adc #>$3e8
    sta.z src_end+1
    // [11] (byte*) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
    // [12] (byte*) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
    // [13] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
    // [13] phi (byte*) memcpy::dst#2 = (byte*) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [13] 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)
    // [14] 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
    // }
    // [15] return 
    rts
    // memcpy::@2
  __b2:
    // *dst++ = *src++
    // [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    sta (dst),y
    // *dst++ = *src++;
    // [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [18] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 
    inc.z src
    bne !+
    inc.z src+1
  !:
    jmp __b1
}
  // File Data
MEDUSA_SCREEN:
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)

MEDUSA_COLORS:
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)


