Fixing pointer array-indexing *((dword*) main::screen + (number) 0)
Fixing pointer array-indexing *((dword*) main::screen + (number) 1)
Identified constant variable (dword*) main::screen
Culled Empty Block (label) @1
Culled Empty Block (label) mul16u::@1

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

(void()) main()
main: scope:[main]  from @2
  (word) main::w#0 ← (word) $a
  (word) mul16u::b#0 ← (word) main::w#0
  (word) mul16u::a#0 ← (word) main::w#0
  call mul16u 
  (dword) mul16u::return#0 ← (dword) mul16u::return#3
  to:main::@1
main::@1: scope:[main]  from main
  (dword) mul16u::return#4 ← phi( main/(dword) mul16u::return#0 )
  (dword~) main::$0 ← (dword) mul16u::return#4
  (number~) main::$2 ← (number) 0 * (const byte) SIZEOF_DWORD
  *((const dword*) main::screen + (number~) main::$2) ← (dword~) main::$0
  (word) main::w#1 ← (number) $3e8
  (word) mul16u::b#1 ← (word) main::w#1
  (word) mul16u::a#1 ← (word) main::w#1
  call mul16u 
  (dword) mul16u::return#1 ← (dword) mul16u::return#3
  to:main::@2
main::@2: scope:[main]  from main::@1
  (dword) mul16u::return#5 ← phi( main::@1/(dword) mul16u::return#1 )
  (dword~) main::$1 ← (dword) mul16u::return#5
  (number~) main::$3 ← (number) 1 * (const byte) SIZEOF_DWORD
  *((const dword*) main::screen + (number~) main::$3) ← (dword~) main::$1
  to:main::@return
main::@return: scope:[main]  from main::@2
  return 
  to:@return

(dword()) mul16u((word) mul16u::b , (word) mul16u::a)
mul16u: scope:[mul16u]  from main main::@1
  (word) mul16u::a#2 ← phi( main/(word) mul16u::a#0 main::@1/(word) mul16u::a#1 )
  (word) mul16u::b#2 ← phi( main/(word) mul16u::b#0 main::@1/(word) mul16u::b#1 )
  (dword) mul16u::mb#0 ← (dword)(word) mul16u::b#2
  (dword~) mul16u::$0 ← (dword) mul16u::mb#0 + (word) mul16u::a#2
  (dword) mul16u::return#2 ← (dword~) mul16u::$0
  to:mul16u::@return
mul16u::@return: scope:[mul16u]  from mul16u
  (dword) mul16u::return#6 ← phi( mul16u/(dword) mul16u::return#2 )
  (dword) mul16u::return#3 ← (dword) mul16u::return#6
  return 
  to:@return
@2: scope:[]  from @begin
  call main 
  to:@3
@3: scope:[]  from @2
  to:@end
@end: scope:[]  from @3

SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(const byte) SIZEOF_DWORD = (byte) 4
(void()) main()
(dword~) main::$0
(dword~) main::$1
(number~) main::$2
(number~) main::$3
(label) main::@1
(label) main::@2
(label) main::@return
(const dword*) main::screen = (dword*)(number) $400
(word) main::w
(word) main::w#0
(word) main::w#1
(dword()) mul16u((word) mul16u::b , (word) mul16u::a)
(dword~) mul16u::$0
(label) mul16u::@return
(word) mul16u::a
(word) mul16u::a#0
(word) mul16u::a#1
(word) mul16u::a#2
(word) mul16u::b
(word) mul16u::b#0
(word) mul16u::b#1
(word) mul16u::b#2
(dword) mul16u::mb
(dword) mul16u::mb#0
(dword) mul16u::return
(dword) mul16u::return#0
(dword) mul16u::return#1
(dword) mul16u::return#2
(dword) mul16u::return#3
(dword) mul16u::return#4
(dword) mul16u::return#5
(dword) mul16u::return#6

Adding number conversion cast (unumber) 0 in (number~) main::$2 ← (number) 0 * (const byte) SIZEOF_DWORD
Adding number conversion cast (unumber) main::$2 in (number~) main::$2 ← (unumber)(number) 0 * (const byte) SIZEOF_DWORD
Adding number conversion cast (unumber) $3e8 in (word) main::w#1 ← (number) $3e8
Adding number conversion cast (unumber) 1 in (number~) main::$3 ← (number) 1 * (const byte) SIZEOF_DWORD
Adding number conversion cast (unumber) main::$3 in (number~) main::$3 ← (unumber)(number) 1 * (const byte) SIZEOF_DWORD
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (word) main::w#1 ← (unumber)(number) $3e8
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (dword*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast $3e8
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (word) $3e8
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in (unumber~) main::$2 ← (byte) 0 * (const byte) SIZEOF_DWORD
Inferred type updated to byte in (unumber~) main::$3 ← (byte) 1 * (const byte) SIZEOF_DWORD
Alias (dword) mul16u::return#0 = (dword) mul16u::return#4 
Alias (dword) mul16u::return#1 = (dword) mul16u::return#5 
Alias (dword) mul16u::return#2 = (dword~) mul16u::$0 (dword) mul16u::return#6 (dword) mul16u::return#3 
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [6] (byte~) main::$2 ← (byte) 0 * (const byte) SIZEOF_DWORD
Constant right-side identified [14] (byte~) main::$3 ← (byte) 1 * (const byte) SIZEOF_DWORD
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const word) main::w#0 = $a
Constant (const byte) main::$2 = 0*SIZEOF_DWORD
Constant (const word) main::w#1 = $3e8
Constant (const byte) main::$3 = 1*SIZEOF_DWORD
Successful SSA optimization Pass2ConstantIdentification
Constant (const word) mul16u::b#0 = main::w#0
Constant (const word) mul16u::a#0 = main::w#0
Constant (const word) mul16u::b#1 = main::w#1
Constant (const word) mul16u::a#1 = main::w#1
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_DWORD in 
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero main::screen in [7] *((const dword*) main::screen + (const byte) main::$2) ← (dword~) main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) main::$2
Successful SSA optimization PassNEliminateUnusedVars
Inlining constant with different constant siblings (const word) main::w#0
Inlining constant with different constant siblings (const word) main::w#1
Inlining constant with var siblings (const word) mul16u::b#0
Inlining constant with var siblings (const word) mul16u::a#0
Inlining constant with var siblings (const word) mul16u::b#1
Inlining constant with var siblings (const word) mul16u::a#1
Constant inlined mul16u::b#1 = (word) $3e8
Constant inlined main::$3 = (byte) 1*(const byte) SIZEOF_DWORD
Constant inlined main::w#1 = (word) $3e8
Constant inlined main::w#0 = (word) $a
Constant inlined mul16u::b#0 = (word) $a
Constant inlined mul16u::a#1 = (word) $3e8
Constant inlined mul16u::a#0 = (word) $a
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(main::screen+1*SIZEOF_DWORD)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
CALL GRAPH
Calls in [] to main:2 
Calls in [main] to mul16u:6 mul16u:10 

Created 2 initial phi equivalence classes
Coalesced down to 2 phi equivalence classes
Culled Empty Block (label) @3
Renumbering block @2 to @1
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

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()
  [5] call mul16u 
  [6] (dword) mul16u::return#0 ← (dword) mul16u::return#2
  to:main::@1
main::@1: scope:[main]  from main
  [7] (dword~) main::$0 ← (dword) mul16u::return#0
  [8] *((const dword*) main::screen) ← (dword~) main::$0
  [9] call mul16u 
  [10] (dword) mul16u::return#1 ← (dword) mul16u::return#2
  to:main::@2
main::@2: scope:[main]  from main::@1
  [11] (dword~) main::$1 ← (dword) mul16u::return#1
  [12] *((const dword*) main::screen+(byte) 1*(const byte) SIZEOF_DWORD) ← (dword~) main::$1
  to:main::@return
main::@return: scope:[main]  from main::@2
  [13] return 
  to:@return

(dword()) mul16u((word) mul16u::b , (word) mul16u::a)
mul16u: scope:[mul16u]  from main main::@1
  [14] (word) mul16u::a#2 ← phi( main/(word) $a main::@1/(word) $3e8 )
  [14] (word) mul16u::b#2 ← phi( main/(word) $a main::@1/(word) $3e8 )
  [15] (dword) mul16u::mb#0 ← (dword)(word) mul16u::b#2
  [16] (dword) mul16u::return#2 ← (dword) mul16u::mb#0 + (word) mul16u::a#2
  to:mul16u::@return
mul16u::@return: scope:[mul16u]  from mul16u
  [17] return 
  to:@return


VARIABLE REGISTER WEIGHTS
(void()) main()
(dword~) main::$0 4.0
(dword~) main::$1 4.0
(word) main::w
(dword()) mul16u((word) mul16u::b , (word) mul16u::a)
(word) mul16u::a
(word) mul16u::a#2 1.0
(word) mul16u::b
(word) mul16u::b#2
(dword) mul16u::mb
(dword) mul16u::mb#0 4.0
(dword) mul16u::return
(dword) mul16u::return#0 4.0
(dword) mul16u::return#1 4.0
(dword) mul16u::return#2 1.5

Initial phi equivalence classes
[ mul16u::b#2 ]
[ mul16u::a#2 ]
Added variable mul16u::return#0 to live range equivalence class [ mul16u::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable mul16u::return#1 to live range equivalence class [ mul16u::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable mul16u::mb#0 to live range equivalence class [ mul16u::mb#0 ]
Added variable mul16u::return#2 to live range equivalence class [ mul16u::return#2 ]
Complete equivalence classes
[ mul16u::b#2 ]
[ mul16u::a#2 ]
[ mul16u::return#0 ]
[ main::$0 ]
[ mul16u::return#1 ]
[ main::$1 ]
[ mul16u::mb#0 ]
[ mul16u::return#2 ]
Allocated zp[2]:2 [ mul16u::b#2 ]
Allocated zp[2]:4 [ mul16u::a#2 ]
Allocated zp[4]:6 [ mul16u::return#0 ]
Allocated zp[4]:10 [ main::$0 ]
Allocated zp[4]:14 [ mul16u::return#1 ]
Allocated zp[4]:18 [ main::$1 ]
Allocated zp[4]:22 [ mul16u::mb#0 ]
Allocated zp[4]:26 [ mul16u::return#2 ]

INITIAL ASM
Target platform is c64basic / MOS6502X
  // File Comments
// Tests that ASM fragment variations works
// ASM fragment variations "cast" constants to different types
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .const SIZEOF_DWORD = 4
  // @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: {
    .label screen = $400
    .label __0 = $a
    .label __1 = $12
    // [5] call mul16u 
    // [14] phi from main to mul16u [phi:main->mul16u]
  mul16u_from_main:
    // [14] phi (word) mul16u::a#2 = (word) $a [phi:main->mul16u#0] -- vwuz1=vwuc1 
    lda #<$a
    sta.z mul16u.a
    lda #>$a
    sta.z mul16u.a+1
    // [14] phi (word) mul16u::b#2 = (word) $a [phi:main->mul16u#1] -- vwuz1=vwuc1 
    lda #<$a
    sta.z mul16u.b
    lda #>$a
    sta.z mul16u.b+1
    jsr mul16u
    // [6] (dword) mul16u::return#0 ← (dword) mul16u::return#2 -- vduz1=vduz2 
    lda.z mul16u.return_2
    sta.z mul16u.return
    lda.z mul16u.return_2+1
    sta.z mul16u.return+1
    lda.z mul16u.return_2+2
    sta.z mul16u.return+2
    lda.z mul16u.return_2+3
    sta.z mul16u.return+3
    jmp __b1
    // main::@1
  __b1:
    // [7] (dword~) main::$0 ← (dword) mul16u::return#0 -- vduz1=vduz2 
    lda.z mul16u.return
    sta.z __0
    lda.z mul16u.return+1
    sta.z __0+1
    lda.z mul16u.return+2
    sta.z __0+2
    lda.z mul16u.return+3
    sta.z __0+3
    // [8] *((const dword*) main::screen) ← (dword~) main::$0 -- _deref_pduc1=vduz1 
    lda.z __0
    sta screen
    lda.z __0+1
    sta screen+1
    lda.z __0+2
    sta screen+2
    lda.z __0+3
    sta screen+3
    // [9] call mul16u 
    // [14] phi from main::@1 to mul16u [phi:main::@1->mul16u]
  mul16u_from___b1:
    // [14] phi (word) mul16u::a#2 = (word) $3e8 [phi:main::@1->mul16u#0] -- vwuz1=vwuc1 
    lda #<$3e8
    sta.z mul16u.a
    lda #>$3e8
    sta.z mul16u.a+1
    // [14] phi (word) mul16u::b#2 = (word) $3e8 [phi:main::@1->mul16u#1] -- vwuz1=vwuc1 
    lda #<$3e8
    sta.z mul16u.b
    lda #>$3e8
    sta.z mul16u.b+1
    jsr mul16u
    // [10] (dword) mul16u::return#1 ← (dword) mul16u::return#2 -- vduz1=vduz2 
    lda.z mul16u.return_2
    sta.z mul16u.return_1
    lda.z mul16u.return_2+1
    sta.z mul16u.return_1+1
    lda.z mul16u.return_2+2
    sta.z mul16u.return_1+2
    lda.z mul16u.return_2+3
    sta.z mul16u.return_1+3
    jmp __b2
    // main::@2
  __b2:
    // [11] (dword~) main::$1 ← (dword) mul16u::return#1 -- vduz1=vduz2 
    lda.z mul16u.return_1
    sta.z __1
    lda.z mul16u.return_1+1
    sta.z __1+1
    lda.z mul16u.return_1+2
    sta.z __1+2
    lda.z mul16u.return_1+3
    sta.z __1+3
    // [12] *((const dword*) main::screen+(byte) 1*(const byte) SIZEOF_DWORD) ← (dword~) main::$1 -- _deref_pduc1=vduz1 
    lda.z __1
    sta screen+1*SIZEOF_DWORD
    lda.z __1+1
    sta screen+1*SIZEOF_DWORD+1
    lda.z __1+2
    sta screen+1*SIZEOF_DWORD+2
    lda.z __1+3
    sta screen+1*SIZEOF_DWORD+3
    jmp __breturn
    // main::@return
  __breturn:
    // [13] return 
    rts
}
  // mul16u
// mul16u(word zp(2) b, word zp(4) a)
mul16u: {
    .label return = 6
    .label return_1 = $e
    .label mb = $16
    .label return_2 = $1a
    .label b = 2
    .label a = 4
    // [15] (dword) mul16u::mb#0 ← (dword)(word) mul16u::b#2 -- vduz1=_dword_vwuz2 
    lda.z b
    sta.z mb
    lda.z b+1
    sta.z mb+1
    lda #0
    sta.z mb+2
    sta.z mb+3
    // [16] (dword) mul16u::return#2 ← (dword) mul16u::mb#0 + (word) mul16u::a#2 -- vduz1=vduz2_plus_vwuz3 
    lda.z mb
    clc
    adc.z a
    sta.z return_2
    lda.z mb+1
    adc.z a+1
    sta.z return_2+1
    lda.z mb+2
    adc #0
    sta.z return_2+2
    lda.z mb+3
    adc #0
    sta.z return_2+3
    jmp __breturn
    // mul16u::@return
  __breturn:
    // [17] return 
    rts
}
  // File Data

REGISTER UPLIFT POTENTIAL REGISTERS
Statement [6] (dword) mul16u::return#0 ← (dword) mul16u::return#2 [ mul16u::return#0 ] ( main:2 [ mul16u::return#0 ] ) always clobbers reg byte a 
Statement [7] (dword~) main::$0 ← (dword) mul16u::return#0 [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a 
Statement [8] *((const dword*) main::screen) ← (dword~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [10] (dword) mul16u::return#1 ← (dword) mul16u::return#2 [ mul16u::return#1 ] ( main:2 [ mul16u::return#1 ] ) always clobbers reg byte a 
Statement [11] (dword~) main::$1 ← (dword) mul16u::return#1 [ main::$1 ] ( main:2 [ main::$1 ] ) always clobbers reg byte a 
Statement [12] *((const dword*) main::screen+(byte) 1*(const byte) SIZEOF_DWORD) ← (dword~) main::$1 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [15] (dword) mul16u::mb#0 ← (dword)(word) mul16u::b#2 [ mul16u::a#2 mul16u::mb#0 ] ( main:2::mul16u:5 [ mul16u::a#2 mul16u::mb#0 ] main:2::mul16u:9 [ mul16u::a#2 mul16u::mb#0 ] ) always clobbers reg byte a 
Statement [16] (dword) mul16u::return#2 ← (dword) mul16u::mb#0 + (word) mul16u::a#2 [ mul16u::return#2 ] ( main:2::mul16u:5 [ mul16u::return#2 ] main:2::mul16u:9 [ mul16u::return#2 ] ) always clobbers reg byte a 
Potential registers zp[2]:2 [ mul16u::b#2 ] : zp[2]:2 , 
Potential registers zp[2]:4 [ mul16u::a#2 ] : zp[2]:4 , 
Potential registers zp[4]:6 [ mul16u::return#0 ] : zp[4]:6 , 
Potential registers zp[4]:10 [ main::$0 ] : zp[4]:10 , 
Potential registers zp[4]:14 [ mul16u::return#1 ] : zp[4]:14 , 
Potential registers zp[4]:18 [ main::$1 ] : zp[4]:18 , 
Potential registers zp[4]:22 [ mul16u::mb#0 ] : zp[4]:22 , 
Potential registers zp[4]:26 [ mul16u::return#2 ] : zp[4]:26 , 

REGISTER UPLIFT SCOPES
Uplift Scope [mul16u] 4: zp[4]:6 [ mul16u::return#0 ] 4: zp[4]:14 [ mul16u::return#1 ] 4: zp[4]:22 [ mul16u::mb#0 ] 1.5: zp[4]:26 [ mul16u::return#2 ] 1: zp[2]:4 [ mul16u::a#2 ] 0: zp[2]:2 [ mul16u::b#2 ] 
Uplift Scope [main] 4: zp[4]:10 [ main::$0 ] 4: zp[4]:18 [ main::$1 ] 
Uplift Scope [] 

Uplifting [mul16u] best 296 combination zp[4]:6 [ mul16u::return#0 ] zp[4]:14 [ mul16u::return#1 ] zp[4]:22 [ mul16u::mb#0 ] zp[4]:26 [ mul16u::return#2 ] zp[2]:4 [ mul16u::a#2 ] zp[2]:2 [ mul16u::b#2 ] 
Uplifting [main] best 296 combination zp[4]:10 [ main::$0 ] zp[4]:18 [ main::$1 ] 
Uplifting [] best 296 combination 
Coalescing zero page register [ zp[4]:6 [ mul16u::return#0 ] ] with [ zp[4]:10 [ main::$0 ] ] - score: 1
Coalescing zero page register [ zp[4]:6 [ mul16u::return#0 main::$0 ] ] with [ zp[4]:26 [ mul16u::return#2 ] ] - score: 1
Coalescing zero page register [ zp[4]:14 [ mul16u::return#1 ] ] with [ zp[4]:18 [ main::$1 ] ] - score: 1
Coalescing zero page register [ zp[4]:6 [ mul16u::return#0 main::$0 mul16u::return#2 ] ] with [ zp[4]:14 [ mul16u::return#1 main::$1 ] ] - score: 1
Coalescing zero page register [ zp[4]:6 [ mul16u::return#0 main::$0 mul16u::return#2 mul16u::return#1 main::$1 ] ] with [ zp[4]:22 [ mul16u::mb#0 ] ] - score: 1

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Tests that ASM fragment variations works
// ASM fragment variations "cast" constants to different types
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .const SIZEOF_DWORD = 4
  // @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: {
    .label screen = $400
    .label __0 = 6
    .label __1 = 6
    // [5] call mul16u 
    // [14] phi from main to mul16u [phi:main->mul16u]
  mul16u_from_main:
    // [14] phi (word) mul16u::a#2 = (word) $a [phi:main->mul16u#0] -- vwuz1=vwuc1 
    lda #<$a
    sta.z mul16u.a
    lda #>$a
    sta.z mul16u.a+1
    // [14] phi (word) mul16u::b#2 = (word) $a [phi:main->mul16u#1] -- vwuz1=vwuc1 
    lda #<$a
    sta.z mul16u.b
    lda #>$a
    sta.z mul16u.b+1
    jsr mul16u
    // [6] (dword) mul16u::return#0 ← (dword) mul16u::return#2
    jmp __b1
    // main::@1
  __b1:
    // [7] (dword~) main::$0 ← (dword) mul16u::return#0
    // [8] *((const dword*) main::screen) ← (dword~) main::$0 -- _deref_pduc1=vduz1 
    lda.z __0
    sta screen
    lda.z __0+1
    sta screen+1
    lda.z __0+2
    sta screen+2
    lda.z __0+3
    sta screen+3
    // [9] call mul16u 
    // [14] phi from main::@1 to mul16u [phi:main::@1->mul16u]
  mul16u_from___b1:
    // [14] phi (word) mul16u::a#2 = (word) $3e8 [phi:main::@1->mul16u#0] -- vwuz1=vwuc1 
    lda #<$3e8
    sta.z mul16u.a
    lda #>$3e8
    sta.z mul16u.a+1
    // [14] phi (word) mul16u::b#2 = (word) $3e8 [phi:main::@1->mul16u#1] -- vwuz1=vwuc1 
    lda #<$3e8
    sta.z mul16u.b
    lda #>$3e8
    sta.z mul16u.b+1
    jsr mul16u
    // [10] (dword) mul16u::return#1 ← (dword) mul16u::return#2
    jmp __b2
    // main::@2
  __b2:
    // [11] (dword~) main::$1 ← (dword) mul16u::return#1
    // [12] *((const dword*) main::screen+(byte) 1*(const byte) SIZEOF_DWORD) ← (dword~) main::$1 -- _deref_pduc1=vduz1 
    lda.z __1
    sta screen+1*SIZEOF_DWORD
    lda.z __1+1
    sta screen+1*SIZEOF_DWORD+1
    lda.z __1+2
    sta screen+1*SIZEOF_DWORD+2
    lda.z __1+3
    sta screen+1*SIZEOF_DWORD+3
    jmp __breturn
    // main::@return
  __breturn:
    // [13] return 
    rts
}
  // mul16u
// mul16u(word zp(2) b, word zp(4) a)
mul16u: {
    .label return = 6
    .label mb = 6
    .label b = 2
    .label a = 4
    // [15] (dword) mul16u::mb#0 ← (dword)(word) mul16u::b#2 -- vduz1=_dword_vwuz2 
    lda.z b
    sta.z mb
    lda.z b+1
    sta.z mb+1
    lda #0
    sta.z mb+2
    sta.z mb+3
    // [16] (dword) mul16u::return#2 ← (dword) mul16u::mb#0 + (word) mul16u::a#2 -- vduz1=vduz1_plus_vwuz2 
    lda.z return
    clc
    adc.z a
    sta.z return
    lda.z return+1
    adc.z a+1
    sta.z return+1
    lda.z return+2
    adc #0
    sta.z return+2
    lda.z return+3
    adc #0
    sta.z return+3
    jmp __breturn
    // mul16u::@return
  __breturn:
    // [17] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
Removing instruction main_from___b1:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction mul16u_from_main:
Removing instruction __b1:
Removing instruction mul16u_from___b1:
Removing instruction __b2:
Removing instruction __breturn:
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) SIZEOF_DWORD = (byte) 4
(void()) main()
(dword~) main::$0 zp[4]:6 4.0
(dword~) main::$1 zp[4]:6 4.0
(label) main::@1
(label) main::@2
(label) main::@return
(const dword*) main::screen = (dword*) 1024
(word) main::w
(dword()) mul16u((word) mul16u::b , (word) mul16u::a)
(label) mul16u::@return
(word) mul16u::a
(word) mul16u::a#2 a zp[2]:4 1.0
(word) mul16u::b
(word) mul16u::b#2 b zp[2]:2
(dword) mul16u::mb
(dword) mul16u::mb#0 mb zp[4]:6 4.0
(dword) mul16u::return
(dword) mul16u::return#0 return zp[4]:6 4.0
(dword) mul16u::return#1 return zp[4]:6 4.0
(dword) mul16u::return#2 return zp[4]:6 1.5

zp[2]:2 [ mul16u::b#2 ]
zp[2]:4 [ mul16u::a#2 ]
zp[4]:6 [ mul16u::return#0 main::$0 mul16u::return#2 mul16u::return#1 main::$1 mul16u::mb#0 ]


FINAL ASSEMBLER
Score: 176

  // File Comments
// Tests that ASM fragment variations works
// ASM fragment variations "cast" constants to different types
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  .const SIZEOF_DWORD = 4
  // @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: {
    .label screen = $400
    .label __0 = 6
    .label __1 = 6
    // mul16u(w, w)
    // [5] call mul16u 
    // [14] phi from main to mul16u [phi:main->mul16u]
    // [14] phi (word) mul16u::a#2 = (word) $a [phi:main->mul16u#0] -- vwuz1=vwuc1 
    lda #<$a
    sta.z mul16u.a
    lda #>$a
    sta.z mul16u.a+1
    // [14] phi (word) mul16u::b#2 = (word) $a [phi:main->mul16u#1] -- vwuz1=vwuc1 
    lda #<$a
    sta.z mul16u.b
    lda #>$a
    sta.z mul16u.b+1
    jsr mul16u
    // mul16u(w, w)
    // [6] (dword) mul16u::return#0 ← (dword) mul16u::return#2
    // main::@1
    // [7] (dword~) main::$0 ← (dword) mul16u::return#0
    // screen[0] = mul16u(w, w)
    // [8] *((const dword*) main::screen) ← (dword~) main::$0 -- _deref_pduc1=vduz1 
    lda.z __0
    sta screen
    lda.z __0+1
    sta screen+1
    lda.z __0+2
    sta screen+2
    lda.z __0+3
    sta screen+3
    // mul16u(w, w)
    // [9] call mul16u 
    // [14] phi from main::@1 to mul16u [phi:main::@1->mul16u]
    // [14] phi (word) mul16u::a#2 = (word) $3e8 [phi:main::@1->mul16u#0] -- vwuz1=vwuc1 
    lda #<$3e8
    sta.z mul16u.a
    lda #>$3e8
    sta.z mul16u.a+1
    // [14] phi (word) mul16u::b#2 = (word) $3e8 [phi:main::@1->mul16u#1] -- vwuz1=vwuc1 
    lda #<$3e8
    sta.z mul16u.b
    lda #>$3e8
    sta.z mul16u.b+1
    jsr mul16u
    // mul16u(w, w)
    // [10] (dword) mul16u::return#1 ← (dword) mul16u::return#2
    // main::@2
    // [11] (dword~) main::$1 ← (dword) mul16u::return#1
    // screen[1] = mul16u(w, w)
    // [12] *((const dword*) main::screen+(byte) 1*(const byte) SIZEOF_DWORD) ← (dword~) main::$1 -- _deref_pduc1=vduz1 
    lda.z __1
    sta screen+1*SIZEOF_DWORD
    lda.z __1+1
    sta screen+1*SIZEOF_DWORD+1
    lda.z __1+2
    sta screen+1*SIZEOF_DWORD+2
    lda.z __1+3
    sta screen+1*SIZEOF_DWORD+3
    // main::@return
    // }
    // [13] return 
    rts
}
  // mul16u
// mul16u(word zp(2) b, word zp(4) a)
mul16u: {
    .label return = 6
    .label mb = 6
    .label b = 2
    .label a = 4
    // mb = b
    // [15] (dword) mul16u::mb#0 ← (dword)(word) mul16u::b#2 -- vduz1=_dword_vwuz2 
    lda.z b
    sta.z mb
    lda.z b+1
    sta.z mb+1
    lda #0
    sta.z mb+2
    sta.z mb+3
    // mb+a
    // [16] (dword) mul16u::return#2 ← (dword) mul16u::mb#0 + (word) mul16u::a#2 -- vduz1=vduz1_plus_vwuz2 
    lda.z return
    clc
    adc.z a
    sta.z return
    lda.z return+1
    adc.z a+1
    sta.z return+1
    lda.z return+2
    adc #0
    sta.z return+2
    lda.z return+3
    adc #0
    sta.z return+3
    // mul16u::@return
    // }
    // [17] return 
    rts
}
  // File Data

