Added struct type cast to parameter value list call printf_string (byte*) "Jesper" (struct printf_format_string){ (byte) 0, (byte) 0 } Added struct type cast to parameter value list call printf_uint (word) main::age (struct printf_format_number){ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (const byte) HEXADECIMAL } Created struct value member variable (byte) printf_string::format_min_length Created struct value member variable (byte) printf_string::format_justify_left Converted struct value to member variables (struct printf_format_string) printf_string::format Created struct value member variable (byte) printf_uint::format_min_length Created struct value member variable (byte) printf_uint::format_justify_left Created struct value member variable (byte) printf_uint::format_sign_always Created struct value member variable (byte) printf_uint::format_zero_padding Created struct value member variable (byte) printf_uint::format_radix Converted struct value to member variables (struct printf_format_number) printf_uint::format Converted procedure struct value parameter to member unwinding (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left) Converted procedure struct value parameter to member unwinding (void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix) Converted call struct value parameter to member unwinding call printf_string (byte*) "Jesper" (byte) 0 (byte) 0 Converted call struct value parameter to member unwinding call printf_uint (word) main::age (byte) 0 (byte) 0 (byte) 0 (byte) 0 (const byte) HEXADECIMAL Warning! Adding boolean cast to non-boolean condition *((byte*) printf_str::str) Identified constant variable (byte) idx Identified constant variable (word) main::age Eliminating unused variable with no statement (void~) main::$0 Eliminating unused variable with no statement (void~) main::$1 Culled Empty Block (label) printf_str::@4 Culled Empty Block (label) printf_str::@3 Culled Empty Block (label) printf_str::@5 Culled Empty Block (label) printf_str::@6 Culled Empty Block (label) @1 Culled Empty Block (label) @2 Culled Empty Block (label) @3 CONTROL FLOW GRAPH SSA @begin: scope:[] from (byte*) screen#0 ← (byte*)(number) $400 to:@4 (void()) printf_str((byte*) printf_str::str) printf_str: scope:[printf_str] from main main::@2 main::@3 main::@5 printf_string (byte*) screen#36 ← phi( main/(byte*) screen#34 main::@2/(byte*) screen#11 main::@3/(byte*) screen#12 main::@5/(byte*) screen#14 printf_string/(byte*) screen#33 ) (byte*) printf_str::str#8 ← phi( main/(byte*) printf_str::str#2 main::@2/(byte*) printf_str::str#3 main::@3/(byte*) printf_str::str#4 main::@5/(byte*) printf_str::str#5 printf_string/(byte*) printf_str::str#1 ) to:printf_str::@1 printf_str::@1: scope:[printf_str] from printf_str printf_str::@2 (byte*) screen#32 ← phi( printf_str/(byte*) screen#36 printf_str::@2/(byte*) screen#1 ) (byte*) printf_str::str#6 ← phi( printf_str/(byte*) printf_str::str#8 printf_str::@2/(byte*) printf_str::str#0 ) (bool~) printf_str::$0 ← (number) 0 != *((byte*) printf_str::str#6) if((bool~) printf_str::$0) goto printf_str::@2 to:printf_str::@return printf_str::@2: scope:[printf_str] from printf_str::@1 (byte*) screen#18 ← phi( printf_str::@1/(byte*) screen#32 ) (byte*) printf_str::str#7 ← phi( printf_str::@1/(byte*) printf_str::str#6 ) *((byte*) screen#18) ← *((byte*) printf_str::str#7) (byte*) screen#1 ← ++ (byte*) screen#18 (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#7 to:printf_str::@1 printf_str::@return: scope:[printf_str] from printf_str::@1 (byte*) screen#19 ← phi( printf_str::@1/(byte*) screen#32 ) (byte*) screen#2 ← (byte*) screen#19 return to:@return (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left) printf_string: scope:[printf_string] from main::@1 (byte*) screen#33 ← phi( main::@1/(byte*) screen#10 ) (byte*) printf_string::str#1 ← phi( main::@1/(byte*) printf_string::str#0 ) (byte*) printf_str::str#1 ← (byte*) printf_string::str#1 call printf_str to:printf_string::@1 printf_string::@1: scope:[printf_string] from printf_string (byte*) screen#20 ← phi( printf_string/(byte*) screen#2 ) (byte*) screen#3 ← (byte*) screen#20 to:printf_string::@return printf_string::@return: scope:[printf_string] from printf_string::@1 (byte*) screen#21 ← phi( printf_string::@1/(byte*) screen#3 ) (byte*) screen#4 ← (byte*) screen#21 return to:@return (void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix) printf_uint: scope:[printf_uint] from main::@4 (byte*) screen#22 ← phi( main::@4/(byte*) screen#13 ) (word) printf_uint::uvalue#1 ← phi( main::@4/(word) printf_uint::uvalue#0 ) (byte~) printf_uint::$0 ← > (word) printf_uint::uvalue#1 (byte~) printf_uint::$1 ← (byte~) printf_uint::$0 >> (number) 4 *((byte*) screen#22) ← *((const to_nomodify byte*) printf_hextab + (byte~) printf_uint::$1) (byte*) screen#5 ← ++ (byte*) screen#22 (byte~) printf_uint::$2 ← > (word) printf_uint::uvalue#1 (number~) printf_uint::$3 ← (byte~) printf_uint::$2 & (number) $f *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab + (number~) printf_uint::$3) (byte*) screen#6 ← ++ (byte*) screen#5 (byte~) printf_uint::$4 ← < (word) printf_uint::uvalue#1 (byte~) printf_uint::$5 ← (byte~) printf_uint::$4 >> (number) 4 *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab + (byte~) printf_uint::$5) (byte*) screen#7 ← ++ (byte*) screen#6 (byte~) printf_uint::$6 ← < (word) printf_uint::uvalue#1 (number~) printf_uint::$7 ← (byte~) printf_uint::$6 & (number) $f *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab + (number~) printf_uint::$7) (byte*) screen#8 ← ++ (byte*) screen#7 to:printf_uint::@return printf_uint::@return: scope:[printf_uint] from printf_uint (byte*) screen#23 ← phi( printf_uint/(byte*) screen#8 ) (byte*) screen#9 ← (byte*) screen#23 return to:@return (void()) main() main: scope:[main] from @4 (byte*) screen#34 ← phi( @4/(byte*) screen#35 ) (byte*) printf_str::str#2 ← (const byte*) main::str call printf_str to:main::@1 main::@1: scope:[main] from main (byte*) screen#24 ← phi( main/(byte*) screen#2 ) (byte*) screen#10 ← (byte*) screen#24 (byte*) printf_string::str#0 ← (const byte*) main::str1 (byte) printf_string::format_min_length#0 ← (byte) 0 (byte) printf_string::format_justify_left#0 ← (byte) 0 call printf_string to:main::@2 main::@2: scope:[main] from main::@1 (byte*) screen#25 ← phi( main::@1/(byte*) screen#4 ) (byte*) screen#11 ← (byte*) screen#25 (byte*) printf_str::str#3 ← (const byte*) main::str2 call printf_str to:main::@3 main::@3: scope:[main] from main::@2 (byte*) screen#26 ← phi( main::@2/(byte*) screen#2 ) (byte*) screen#12 ← (byte*) screen#26 (byte*) printf_str::str#4 ← (const byte*) main::str3 call printf_str to:main::@4 main::@4: scope:[main] from main::@3 (byte*) screen#27 ← phi( main::@3/(byte*) screen#2 ) (byte*) screen#13 ← (byte*) screen#27 (word) printf_uint::uvalue#0 ← (const word) main::age (byte) printf_uint::format_min_length#0 ← (byte) 0 (byte) printf_uint::format_justify_left#0 ← (byte) 0 (byte) printf_uint::format_sign_always#0 ← (byte) 0 (byte) printf_uint::format_zero_padding#0 ← (byte) 0 (byte) printf_uint::format_radix#0 ← (const byte) HEXADECIMAL call printf_uint to:main::@5 main::@5: scope:[main] from main::@4 (byte*) screen#28 ← phi( main::@4/(byte*) screen#9 ) (byte*) screen#14 ← (byte*) screen#28 (byte*) printf_str::str#5 ← (const byte*) main::str4 call printf_str to:main::@6 main::@6: scope:[main] from main::@5 (byte*) screen#29 ← phi( main::@5/(byte*) screen#2 ) (byte*) screen#15 ← (byte*) screen#29 to:main::@return main::@return: scope:[main] from main::@6 (byte*) screen#30 ← phi( main::@6/(byte*) screen#15 ) (byte*) screen#16 ← (byte*) screen#30 return to:@return @4: scope:[] from @begin (byte*) screen#35 ← phi( @begin/(byte*) screen#0 ) call main to:@5 @5: scope:[] from @4 (byte*) screen#31 ← phi( @4/(byte*) screen#16 ) (byte*) screen#17 ← (byte*) screen#31 to:@end @end: scope:[] from @5 SYMBOL TABLE SSA (label) @4 (label) @5 (label) @begin (label) @end (const byte) HEXADECIMAL = (number) $10 (const byte) RADIX::BINARY = (number) 2 (const byte) RADIX::DECIMAL = (number) $a (const byte) RADIX::HEXADECIMAL = (number) $10 (const byte) RADIX::OCTAL = (number) 8 (void()) main() (label) main::@1 (label) main::@2 (label) main::@3 (label) main::@4 (label) main::@5 (label) main::@6 (label) main::@return (const word) main::age = (word) $2e (const byte*) main::str[(byte) $d] = (byte*) "Hello, I am " (const byte*) main::str1[(byte) 7] = (byte*) "Jesper" (const byte*) main::str2[(byte) $f] = (byte*) ". who are you?" (const byte*) main::str3[(byte) 6] = (byte*) "I am " (const byte*) main::str4[(byte) $b] = (byte*) " years old" (byte) printf_format_number::justify_left (byte) printf_format_number::min_length (byte) printf_format_number::radix (byte) printf_format_number::sign_always (byte) printf_format_number::zero_padding (byte) printf_format_string::justify_left (byte) printf_format_string::min_length (const to_nomodify byte*) printf_hextab[] = (byte*) "0123456789abcdef"z (void()) printf_str((byte*) printf_str::str) (bool~) printf_str::$0 (label) printf_str::@1 (label) printf_str::@2 (label) printf_str::@return (byte*) printf_str::str (byte*) printf_str::str#0 (byte*) printf_str::str#1 (byte*) printf_str::str#2 (byte*) printf_str::str#3 (byte*) printf_str::str#4 (byte*) printf_str::str#5 (byte*) printf_str::str#6 (byte*) printf_str::str#7 (byte*) printf_str::str#8 (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left) (label) printf_string::@1 (label) printf_string::@return (struct printf_format_string) printf_string::format (byte) printf_string::format_justify_left (byte) printf_string::format_justify_left#0 (byte) printf_string::format_min_length (byte) printf_string::format_min_length#0 (byte*) printf_string::str (byte*) printf_string::str#0 (byte*) printf_string::str#1 (void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix) (byte~) printf_uint::$0 (byte~) printf_uint::$1 (byte~) printf_uint::$2 (number~) printf_uint::$3 (byte~) printf_uint::$4 (byte~) printf_uint::$5 (byte~) printf_uint::$6 (number~) printf_uint::$7 (label) printf_uint::@return (struct printf_format_number) printf_uint::format (byte) printf_uint::format_justify_left (byte) printf_uint::format_justify_left#0 (byte) printf_uint::format_min_length (byte) printf_uint::format_min_length#0 (byte) printf_uint::format_radix (byte) printf_uint::format_radix#0 (byte) printf_uint::format_sign_always (byte) printf_uint::format_sign_always#0 (byte) printf_uint::format_zero_padding (byte) printf_uint::format_zero_padding#0 (word) printf_uint::uvalue (word) printf_uint::uvalue#0 (word) printf_uint::uvalue#1 (byte*) screen (byte*) screen#0 (byte*) screen#1 (byte*) screen#10 (byte*) screen#11 (byte*) screen#12 (byte*) screen#13 (byte*) screen#14 (byte*) screen#15 (byte*) screen#16 (byte*) screen#17 (byte*) screen#18 (byte*) screen#19 (byte*) screen#2 (byte*) screen#20 (byte*) screen#21 (byte*) screen#22 (byte*) screen#23 (byte*) screen#24 (byte*) screen#25 (byte*) screen#26 (byte*) screen#27 (byte*) screen#28 (byte*) screen#29 (byte*) screen#3 (byte*) screen#30 (byte*) screen#31 (byte*) screen#32 (byte*) screen#33 (byte*) screen#34 (byte*) screen#35 (byte*) screen#36 (byte*) screen#4 (byte*) screen#5 (byte*) screen#6 (byte*) screen#7 (byte*) screen#8 (byte*) screen#9 Adding number conversion cast (unumber) 0 in (bool~) printf_str::$0 ← (number) 0 != *((byte*) printf_str::str#6) Adding number conversion cast (unumber) 4 in (byte~) printf_uint::$1 ← (byte~) printf_uint::$0 >> (number) 4 Adding number conversion cast (unumber) $f in (number~) printf_uint::$3 ← (byte~) printf_uint::$2 & (number) $f Adding number conversion cast (unumber) printf_uint::$3 in (number~) printf_uint::$3 ← (byte~) printf_uint::$2 & (unumber)(number) $f Adding number conversion cast (unumber) 4 in (byte~) printf_uint::$5 ← (byte~) printf_uint::$4 >> (number) 4 Adding number conversion cast (unumber) $f in (number~) printf_uint::$7 ← (byte~) printf_uint::$6 & (number) $f Adding number conversion cast (unumber) printf_uint::$7 in (number~) printf_uint::$7 ← (byte~) printf_uint::$6 & (unumber)(number) $f Successful SSA optimization PassNAddNumberTypeConversions Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 0 Simplifying constant integer cast 4 Simplifying constant integer cast $f Simplifying constant integer cast 4 Simplifying constant integer cast $f Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 4 Finalized unsigned number type (byte) $f Finalized unsigned number type (byte) 4 Finalized unsigned number type (byte) $f Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to byte in (unumber~) printf_uint::$3 ← (byte~) printf_uint::$2 & (byte) $f Inferred type updated to byte in (unumber~) printf_uint::$7 ← (byte~) printf_uint::$6 & (byte) $f Alias printf_str::str#6 = printf_str::str#7 Alias screen#18 = screen#32 screen#19 screen#2 Alias screen#20 = screen#3 screen#21 screen#4 Alias screen#23 = screen#8 screen#9 Alias screen#10 = screen#24 Alias screen#11 = screen#25 Alias screen#12 = screen#26 Alias screen#13 = screen#27 Alias screen#14 = screen#28 Alias screen#15 = screen#29 screen#30 screen#16 Alias screen#0 = screen#35 Alias screen#17 = screen#31 Successful SSA optimization Pass2AliasElimination Identical Phi Values (byte*) printf_string::str#1 (byte*) printf_string::str#0 Identical Phi Values (byte*) screen#33 (byte*) screen#10 Identical Phi Values (byte*) screen#20 (byte*) screen#18 Identical Phi Values (word) printf_uint::uvalue#1 (word) printf_uint::uvalue#0 Identical Phi Values (byte*) screen#22 (byte*) screen#13 Identical Phi Values (byte*) screen#34 (byte*) screen#0 Identical Phi Values (byte*) screen#10 (byte*) screen#18 Identical Phi Values (byte*) screen#11 (byte*) screen#20 Identical Phi Values (byte*) screen#12 (byte*) screen#18 Identical Phi Values (byte*) screen#13 (byte*) screen#18 Identical Phi Values (byte*) screen#14 (byte*) screen#23 Identical Phi Values (byte*) screen#15 (byte*) screen#18 Identical Phi Values (byte*) screen#17 (byte*) screen#15 Successful SSA optimization Pass2IdenticalPhiElimination Identified duplicate assignment right side [25] (byte~) printf_uint::$2 ← > (word) printf_uint::uvalue#0 Identified duplicate assignment right side [33] (byte~) printf_uint::$6 ← < (word) printf_uint::uvalue#0 Successful SSA optimization Pass2DuplicateRValueIdentification Simple Condition (bool~) printf_str::$0 [4] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte*) screen#0 = (byte*) 1024 Constant (const byte*) printf_str::str#2 = main::str Constant (const byte*) printf_string::str#0 = main::str1 Constant (const byte) printf_string::format_min_length#0 = 0 Constant (const byte) printf_string::format_justify_left#0 = 0 Constant (const byte*) printf_str::str#3 = main::str2 Constant (const byte*) printf_str::str#4 = main::str3 Constant (const word) printf_uint::uvalue#0 = main::age Constant (const byte) printf_uint::format_min_length#0 = 0 Constant (const byte) printf_uint::format_justify_left#0 = 0 Constant (const byte) printf_uint::format_sign_always#0 = 0 Constant (const byte) printf_uint::format_zero_padding#0 = 0 Constant (const byte) printf_uint::format_radix#0 = HEXADECIMAL Constant (const byte*) printf_str::str#5 = main::str4 Successful SSA optimization Pass2ConstantIdentification Constant (const byte*) printf_str::str#1 = printf_string::str#0 Successful SSA optimization Pass2ConstantIdentification Eliminating unused constant (const byte) printf_string::format_min_length#0 Eliminating unused constant (const byte) printf_string::format_justify_left#0 Eliminating unused constant (const byte) printf_uint::format_min_length#0 Eliminating unused constant (const byte) printf_uint::format_justify_left#0 Eliminating unused constant (const byte) printf_uint::format_sign_always#0 Eliminating unused constant (const byte) printf_uint::format_zero_padding#0 Eliminating unused constant (const byte) printf_uint::format_radix#0 Successful SSA optimization PassNEliminateUnusedVars Eliminating unused constant (const byte) HEXADECIMAL Successful SSA optimization PassNEliminateUnusedVars Alias printf_uint::$2 = printf_uint::$0 Alias printf_uint::$6 = printf_uint::$4 Successful SSA optimization Pass2AliasElimination Constant right-side identified [9] (byte~) printf_uint::$2 ← > (const word) printf_uint::uvalue#0 Constant right-side identified [16] (byte~) printf_uint::$6 ← < (const word) printf_uint::uvalue#0 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) printf_uint::$2 = >printf_uint::uvalue#0 Constant (const byte) printf_uint::$6 = (const word) printf_uint::uvalue#0 in Successful SSA optimization PassNSimplifyConstantZero Constant right-side identified [9] (byte~) printf_uint::$1 ← (const byte) printf_uint::$2 >> (byte) 4 Constant right-side identified [12] (byte~) printf_uint::$3 ← (const byte) printf_uint::$2 & (byte) $f Constant right-side identified [15] (byte~) printf_uint::$5 ← (const byte) printf_uint::$6 >> (byte) 4 Constant right-side identified [18] (byte~) printf_uint::$7 ← (const byte) printf_uint::$6 & (byte) $f Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte) printf_uint::$1 = printf_uint::$2>>4 Constant (const byte) printf_uint::$3 = printf_uint::$2&$f Constant (const byte) printf_uint::$5 = printf_uint::$6>>4 Constant (const byte) printf_uint::$7 = printf_uint::$6&$f Successful SSA optimization Pass2ConstantIdentification Simplifying constant evaluating to zero (const byte) printf_uint::$2>>(byte) 4 in Simplifying constant evaluating to zero (const byte) printf_uint::$2&(byte) $f in Successful SSA optimization PassNSimplifyConstantZero Simplifying expression containing zero printf_hextab in [10] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab + (const byte) printf_uint::$1) Simplifying expression containing zero printf_hextab in [13] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab + (const byte) printf_uint::$3) Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused constant (const byte) printf_uint::$2 Eliminating unused constant (const byte) printf_uint::$1 Eliminating unused constant (const byte) printf_uint::$3 Successful SSA optimization PassNEliminateUnusedVars Inlining constant with var siblings (const byte*) printf_str::str#2 Inlining constant with var siblings (const byte*) printf_str::str#3 Inlining constant with var siblings (const byte*) printf_str::str#4 Inlining constant with var siblings (const byte*) printf_str::str#5 Inlining constant with var siblings (const byte*) printf_str::str#1 Inlining constant with var siblings (const byte*) screen#0 Constant inlined printf_str::str#5 = (const byte*) main::str4 Constant inlined printf_string::str#0 = (const byte*) main::str1 Constant inlined printf_uint::uvalue#0 = (const word) main::age Constant inlined printf_uint::$5 = <(const word) main::age>>(byte) 4 Constant inlined printf_uint::$7 = <(const word) main::age&(byte) $f Constant inlined printf_uint::$6 = <(const word) main::age Constant inlined printf_str::str#2 = (const byte*) main::str Constant inlined printf_str::str#1 = (const byte*) main::str1 Constant inlined printf_str::str#4 = (const byte*) main::str3 Constant inlined screen#0 = (byte*) 1024 Constant inlined printf_str::str#3 = (const byte*) main::str2 Successful SSA optimization Pass2ConstantInlining Consolidated array index constant in *(printf_hextab+>4) Consolidated array index constant in *(printf_hextab+>(byte) 4) [29] (byte*) screen#7 ← ++ (byte*) screen#6 [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) [31] (byte*) screen#23 ← ++ (byte*) screen#7 to:printf_uint::@return printf_uint::@return: scope:[printf_uint] from printf_uint [32] return to:@return (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left) printf_string: scope:[printf_string] from main::@1 [33] phi() [34] call printf_str to:printf_string::@return printf_string::@return: scope:[printf_string] from printf_string [35] return to:@return VARIABLE REGISTER WEIGHTS (void()) main() (byte) printf_format_number::justify_left (byte) printf_format_number::min_length (byte) printf_format_number::radix (byte) printf_format_number::sign_always (byte) printf_format_number::zero_padding (byte) printf_format_string::justify_left (byte) printf_format_string::min_length (void()) printf_str((byte*) printf_str::str) (byte*) printf_str::str (byte*) printf_str::str#0 20002.0 (byte*) printf_str::str#6 10251.25 (byte*) printf_str::str#8 1001.0 (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left) (struct printf_format_string) printf_string::format (byte) printf_string::format_justify_left (byte) printf_string::format_min_length (byte*) printf_string::str (void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix) (struct printf_format_number) printf_uint::format (byte) printf_uint::format_justify_left (byte) printf_uint::format_min_length (byte) printf_uint::format_radix (byte) printf_uint::format_sign_always (byte) printf_uint::format_zero_padding (word) printf_uint::uvalue (byte*) screen (byte*) screen#1 10001.0 (byte*) screen#18 1958.0625 (byte*) screen#23 28.0 (byte*) screen#36 1135.0 (byte*) screen#5 151.5 (byte*) screen#6 151.5 (byte*) screen#7 151.5 Initial phi equivalence classes [ screen#36 screen#18 screen#23 screen#1 ] [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] Added variable screen#5 to live range equivalence class [ screen#5 ] Added variable screen#6 to live range equivalence class [ screen#6 ] Added variable screen#7 to live range equivalence class [ screen#7 ] Complete equivalence classes [ screen#36 screen#18 screen#23 screen#1 ] [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] [ screen#5 ] [ screen#6 ] [ screen#7 ] Allocated zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] Allocated zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] Allocated zp[2]:6 [ screen#5 ] Allocated zp[2]:8 [ screen#6 ] Allocated zp[2]:10 [ screen#7 ] INITIAL ASM Target platform is c64basic / MOS6502X // File Comments // Tests printf function call rewriting // A simple string - with the printf-sub cuntions in the same file. // Upstart .pc = $801 "Basic" :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels .label screen = 2 .label screen_1 = 6 .label screen_2 = 8 .label screen_3 = $a // @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 age = $2e // [5] call printf_str // [17] phi from main to printf_str [phi:main->printf_str] printf_str_from_main: // [17] phi (byte*) screen#36 = (byte*) 1024 [phi:main->printf_str#0] -- pbuz1=pbuc1 lda #<$400 sta.z screen lda #>$400 sta.z screen+1 // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str [phi:main->printf_str#1] -- pbuz1=pbuc1 lda #str sta.z printf_str.str+1 jsr printf_str // [6] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: jmp __b1 // main::@1 __b1: // [7] call printf_string // [33] phi from main::@1 to printf_string [phi:main::@1->printf_string] printf_string_from___b1: jsr printf_string // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2] __b2_from___b1: jmp __b2 // main::@2 __b2: // [9] call printf_str // [17] phi from main::@2 to printf_str [phi:main::@2->printf_str] printf_str_from___b2: // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@2->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str2 [phi:main::@2->printf_str#1] -- pbuz1=pbuc1 lda #str2 sta.z printf_str.str+1 jsr printf_str // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3] __b3_from___b2: jmp __b3 // main::@3 __b3: // [11] call printf_str // [17] phi from main::@3 to printf_str [phi:main::@3->printf_str] printf_str_from___b3: // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@3->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str3 [phi:main::@3->printf_str#1] -- pbuz1=pbuc1 lda #str3 sta.z printf_str.str+1 jsr printf_str // [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4] __b4_from___b3: jmp __b4 // main::@4 __b4: // [13] call printf_uint jsr printf_uint // [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5] __b5_from___b4: jmp __b5 // main::@5 __b5: // [15] call printf_str // [17] phi from main::@5 to printf_str [phi:main::@5->printf_str] printf_str_from___b5: // [17] phi (byte*) screen#36 = (byte*) screen#23 [phi:main::@5->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str4 [phi:main::@5->printf_str#1] -- pbuz1=pbuc1 lda #str4 sta.z printf_str.str+1 jsr printf_str jmp __breturn // main::@return __breturn: // [16] return rts str: .text "Hello, I am " .byte 0 str1: .text "Jesper" .byte 0 str2: .text ". who are you?" .byte 0 str3: .text "I am " .byte 0 str4: .text " years old" .byte 0 } // printf_str // printf_str(byte* zp(4) str) printf_str: { .label str = 4 // [18] phi from printf_str printf_str::@2 to printf_str::@1 [phi:printf_str/printf_str::@2->printf_str::@1] __b1_from_printf_str: __b1_from___b2: // [18] phi (byte*) screen#18 = (byte*) screen#36 [phi:printf_str/printf_str::@2->printf_str::@1#0] -- register_copy // [18] phi (byte*) printf_str::str#6 = (byte*) printf_str::str#8 [phi:printf_str/printf_str::@2->printf_str::@1#1] -- register_copy jmp __b1 // printf_str::@1 __b1: // [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 ldy #0 lda (str),y cmp #0 bne __b2 jmp __breturn // printf_str::@return __breturn: // [20] return rts // printf_str::@2 __b2: // [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) -- _deref_pbuz1=_deref_pbuz2 ldy #0 lda (str),y ldy #0 sta (screen),y // [22] (byte*) screen#1 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // [23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6 -- pbuz1=_inc_pbuz1 inc.z str bne !+ inc.z str+1 !: jmp __b1_from___b2 } // printf_uint // Print an unsigned int using a specific format // Always prints hexadecimals - ignores min_length and flags printf_uint: { // [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab ldy #0 sta (screen),y // [25] (byte*) screen#5 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz2 lda.z screen clc adc #1 sta.z screen_1 lda.z screen+1 adc #0 sta.z screen_1+1 // [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab ldy #0 sta (screen_1),y // [27] (byte*) screen#6 ← ++ (byte*) screen#5 -- pbuz1=_inc_pbuz2 lda.z screen_1 clc adc #1 sta.z screen_2 lda.z screen_1+1 adc #0 sta.z screen_2+1 // [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab+((>4) ldy #0 sta (screen_2),y // [29] (byte*) screen#7 ← ++ (byte*) screen#6 -- pbuz1=_inc_pbuz2 lda.z screen_2 clc adc #1 sta.z screen_3 lda.z screen_2+1 adc #0 sta.z screen_3+1 // [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab+((printf_str] printf_str_from_printf_string: // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:printf_string->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str1 [phi:printf_string->printf_str#1] -- pbuz1=pbuc1 lda #main.str1 sta.z printf_str.str+1 jsr printf_str jmp __breturn // printf_string::@return __breturn: // [35] return rts } // File Data printf_hextab: .text "0123456789abcdef" REGISTER UPLIFT POTENTIAL REGISTERS Statement [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 [ screen#18 printf_str::str#6 ] ( main:2::printf_str:5 [ screen#18 printf_str::str#6 ] { } main:2::printf_str:9 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:11 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:15 [ screen#18 printf_str::str#6 ] { { screen#23 = screen#36 } } main:2::printf_string:7::printf_str:34 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } ) always clobbers reg byte a reg byte y Statement [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) [ screen#18 printf_str::str#6 ] ( main:2::printf_str:5 [ screen#18 printf_str::str#6 ] { } main:2::printf_str:9 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:11 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:15 [ screen#18 printf_str::str#6 ] { { screen#23 = screen#36 } } main:2::printf_string:7::printf_str:34 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } ) always clobbers reg byte a reg byte y Statement [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) [ screen#18 ] ( main:2::printf_uint:13 [ screen#18 ] { } ) always clobbers reg byte a reg byte y Statement [25] (byte*) screen#5 ← ++ (byte*) screen#18 [ screen#5 ] ( main:2::printf_uint:13 [ screen#5 ] { } ) always clobbers reg byte a Statement [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) [ screen#5 ] ( main:2::printf_uint:13 [ screen#5 ] { } ) always clobbers reg byte a reg byte y Statement [27] (byte*) screen#6 ← ++ (byte*) screen#5 [ screen#6 ] ( main:2::printf_uint:13 [ screen#6 ] { } ) always clobbers reg byte a Statement [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) [ screen#6 ] ( main:2::printf_uint:13 [ screen#6 ] { } ) always clobbers reg byte a reg byte y Statement [29] (byte*) screen#7 ← ++ (byte*) screen#6 [ screen#7 ] ( main:2::printf_uint:13 [ screen#7 ] { } ) always clobbers reg byte a Statement [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) [ screen#7 ] ( main:2::printf_uint:13 [ screen#7 ] { } ) always clobbers reg byte a reg byte y Statement [31] (byte*) screen#23 ← ++ (byte*) screen#7 [ screen#23 ] ( main:2::printf_uint:13 [ screen#23 ] { } ) always clobbers reg byte a Potential registers zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] : zp[2]:2 , Potential registers zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] : zp[2]:4 , Potential registers zp[2]:6 [ screen#5 ] : zp[2]:6 , Potential registers zp[2]:8 [ screen#6 ] : zp[2]:8 , Potential registers zp[2]:10 [ screen#7 ] : zp[2]:10 , REGISTER UPLIFT SCOPES Uplift Scope [printf_str] 31,254.25: zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] Uplift Scope [] 13,122.06: zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] 151.5: zp[2]:6 [ screen#5 ] 151.5: zp[2]:8 [ screen#6 ] 151.5: zp[2]:10 [ screen#7 ] Uplift Scope [printf_format_string] Uplift Scope [printf_string] Uplift Scope [RADIX] Uplift Scope [printf_format_number] Uplift Scope [printf_uint] Uplift Scope [main] Uplifting [printf_str] best 897 combination zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] Uplifting [] best 897 combination zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] zp[2]:6 [ screen#5 ] zp[2]:8 [ screen#6 ] zp[2]:10 [ screen#7 ] Uplifting [printf_format_string] best 897 combination Uplifting [printf_string] best 897 combination Uplifting [RADIX] best 897 combination Uplifting [printf_format_number] best 897 combination Uplifting [printf_uint] best 897 combination Uplifting [main] best 897 combination Coalescing zero page register [ zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] ] with [ zp[2]:6 [ screen#5 ] ] - score: 1 Coalescing zero page register [ zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 screen#5 ] ] with [ zp[2]:10 [ screen#7 ] ] - score: 1 Coalescing zero page register [ zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 screen#5 screen#7 ] ] with [ zp[2]:8 [ screen#6 ] ] - score: 2 ASSEMBLER BEFORE OPTIMIZATION // File Comments // Tests printf function call rewriting // A simple string - with the printf-sub cuntions in the same file. // Upstart .pc = $801 "Basic" :BasicUpstart(__bbegin) .pc = $80d "Program" // Global Constants & labels .label screen = 2 // @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 age = $2e // [5] call printf_str // [17] phi from main to printf_str [phi:main->printf_str] printf_str_from_main: // [17] phi (byte*) screen#36 = (byte*) 1024 [phi:main->printf_str#0] -- pbuz1=pbuc1 lda #<$400 sta.z screen lda #>$400 sta.z screen+1 // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str [phi:main->printf_str#1] -- pbuz1=pbuc1 lda #str sta.z printf_str.str+1 jsr printf_str // [6] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: jmp __b1 // main::@1 __b1: // [7] call printf_string // [33] phi from main::@1 to printf_string [phi:main::@1->printf_string] printf_string_from___b1: jsr printf_string // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2] __b2_from___b1: jmp __b2 // main::@2 __b2: // [9] call printf_str // [17] phi from main::@2 to printf_str [phi:main::@2->printf_str] printf_str_from___b2: // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@2->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str2 [phi:main::@2->printf_str#1] -- pbuz1=pbuc1 lda #str2 sta.z printf_str.str+1 jsr printf_str // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3] __b3_from___b2: jmp __b3 // main::@3 __b3: // [11] call printf_str // [17] phi from main::@3 to printf_str [phi:main::@3->printf_str] printf_str_from___b3: // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@3->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str3 [phi:main::@3->printf_str#1] -- pbuz1=pbuc1 lda #str3 sta.z printf_str.str+1 jsr printf_str // [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4] __b4_from___b3: jmp __b4 // main::@4 __b4: // [13] call printf_uint jsr printf_uint // [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5] __b5_from___b4: jmp __b5 // main::@5 __b5: // [15] call printf_str // [17] phi from main::@5 to printf_str [phi:main::@5->printf_str] printf_str_from___b5: // [17] phi (byte*) screen#36 = (byte*) screen#23 [phi:main::@5->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str4 [phi:main::@5->printf_str#1] -- pbuz1=pbuc1 lda #str4 sta.z printf_str.str+1 jsr printf_str jmp __breturn // main::@return __breturn: // [16] return rts str: .text "Hello, I am " .byte 0 str1: .text "Jesper" .byte 0 str2: .text ". who are you?" .byte 0 str3: .text "I am " .byte 0 str4: .text " years old" .byte 0 } // printf_str // printf_str(byte* zp(4) str) printf_str: { .label str = 4 // [18] phi from printf_str printf_str::@2 to printf_str::@1 [phi:printf_str/printf_str::@2->printf_str::@1] __b1_from_printf_str: __b1_from___b2: // [18] phi (byte*) screen#18 = (byte*) screen#36 [phi:printf_str/printf_str::@2->printf_str::@1#0] -- register_copy // [18] phi (byte*) printf_str::str#6 = (byte*) printf_str::str#8 [phi:printf_str/printf_str::@2->printf_str::@1#1] -- register_copy jmp __b1 // printf_str::@1 __b1: // [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 ldy #0 lda (str),y cmp #0 bne __b2 jmp __breturn // printf_str::@return __breturn: // [20] return rts // printf_str::@2 __b2: // [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) -- _deref_pbuz1=_deref_pbuz2 ldy #0 lda (str),y ldy #0 sta (screen),y // [22] (byte*) screen#1 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // [23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6 -- pbuz1=_inc_pbuz1 inc.z str bne !+ inc.z str+1 !: jmp __b1_from___b2 } // printf_uint // Print an unsigned int using a specific format // Always prints hexadecimals - ignores min_length and flags printf_uint: { // [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab ldy #0 sta (screen),y // [25] (byte*) screen#5 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab ldy #0 sta (screen),y // [27] (byte*) screen#6 ← ++ (byte*) screen#5 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab+((>4) ldy #0 sta (screen),y // [29] (byte*) screen#7 ← ++ (byte*) screen#6 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab+((printf_str] printf_str_from_printf_string: // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:printf_string->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str1 [phi:printf_string->printf_str#1] -- pbuz1=pbuc1 lda #main.str1 sta.z printf_str.str+1 jsr printf_str jmp __breturn // printf_string::@return __breturn: // [35] return rts } // File Data printf_hextab: .text "0123456789abcdef" 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 __b5 Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __breturn Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction ldy #0 Succesful ASM optimization Pass5UnnecesaryLoadElimination Replacing label __b1_from___b2 with __b1 Removing instruction __b1_from___bbegin: Removing instruction __b1: Removing instruction main_from___b1: Removing instruction __bend_from___b1: Removing instruction __b1_from_main: Removing instruction printf_string_from___b1: Removing instruction __b2_from___b1: Removing instruction printf_str_from___b2: Removing instruction __b3_from___b2: Removing instruction printf_str_from___b3: Removing instruction __b4_from___b3: Removing instruction __b5_from___b4: Removing instruction printf_str_from___b5: Removing instruction __b1_from_printf_str: Removing instruction __b1_from___b2: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __bend: Removing instruction printf_str_from_main: Removing instruction __b1: Removing instruction __b2: Removing instruction __b3: Removing instruction __b4: Removing instruction __b5: Removing instruction __breturn: Removing instruction __breturn: Removing instruction __breturn: Removing instruction printf_str_from_printf_string: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main Succesful ASM optimization Pass5SkipBegin Removing instruction __bbegin: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE (label) @1 (label) @begin (label) @end (const byte) RADIX::BINARY = (number) 2 (const byte) RADIX::DECIMAL = (number) $a (const byte) RADIX::HEXADECIMAL = (number) $10 (const byte) RADIX::OCTAL = (number) 8 (void()) main() (label) main::@1 (label) main::@2 (label) main::@3 (label) main::@4 (label) main::@5 (label) main::@return (const word) main::age = (word) $2e (const byte*) main::str[(byte) $d] = (byte*) "Hello, I am " (const byte*) main::str1[(byte) 7] = (byte*) "Jesper" (const byte*) main::str2[(byte) $f] = (byte*) ". who are you?" (const byte*) main::str3[(byte) 6] = (byte*) "I am " (const byte*) main::str4[(byte) $b] = (byte*) " years old" (byte) printf_format_number::justify_left (byte) printf_format_number::min_length (byte) printf_format_number::radix (byte) printf_format_number::sign_always (byte) printf_format_number::zero_padding (byte) printf_format_string::justify_left (byte) printf_format_string::min_length (const to_nomodify byte*) printf_hextab[] = (byte*) "0123456789abcdef"z (void()) printf_str((byte*) printf_str::str) (label) printf_str::@1 (label) printf_str::@2 (label) printf_str::@return (byte*) printf_str::str (byte*) printf_str::str#0 str zp[2]:4 20002.0 (byte*) printf_str::str#6 str zp[2]:4 10251.25 (byte*) printf_str::str#8 str zp[2]:4 1001.0 (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left) (label) printf_string::@return (struct printf_format_string) printf_string::format (byte) printf_string::format_justify_left (byte) printf_string::format_min_length (byte*) printf_string::str (void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix) (label) printf_uint::@return (struct printf_format_number) printf_uint::format (byte) printf_uint::format_justify_left (byte) printf_uint::format_min_length (byte) printf_uint::format_radix (byte) printf_uint::format_sign_always (byte) printf_uint::format_zero_padding (word) printf_uint::uvalue (byte*) screen (byte*) screen#1 screen zp[2]:2 10001.0 (byte*) screen#18 screen zp[2]:2 1958.0625 (byte*) screen#23 screen zp[2]:2 28.0 (byte*) screen#36 screen zp[2]:2 1135.0 (byte*) screen#5 screen zp[2]:2 151.5 (byte*) screen#6 screen zp[2]:2 151.5 (byte*) screen#7 screen zp[2]:2 151.5 zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 screen#5 screen#7 screen#6 ] zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] FINAL ASSEMBLER Score: 757 // File Comments // Tests printf function call rewriting // A simple string - with the printf-sub cuntions in the same file. // Upstart .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels .label screen = 2 // @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 age = $2e // printf("Hello, I am %s. who are you?", "Jesper") // [5] call printf_str // [17] phi from main to printf_str [phi:main->printf_str] // [17] phi (byte*) screen#36 = (byte*) 1024 [phi:main->printf_str#0] -- pbuz1=pbuc1 lda #<$400 sta.z screen lda #>$400 sta.z screen+1 // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str [phi:main->printf_str#1] -- pbuz1=pbuc1 lda #str sta.z printf_str.str+1 jsr printf_str // [6] phi from main to main::@1 [phi:main->main::@1] // main::@1 // printf("Hello, I am %s. who are you?", "Jesper") // [7] call printf_string // [33] phi from main::@1 to printf_string [phi:main::@1->printf_string] jsr printf_string // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2] // main::@2 // printf("Hello, I am %s. who are you?", "Jesper") // [9] call printf_str // [17] phi from main::@2 to printf_str [phi:main::@2->printf_str] // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@2->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str2 [phi:main::@2->printf_str#1] -- pbuz1=pbuc1 lda #str2 sta.z printf_str.str+1 jsr printf_str // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3] // main::@3 // printf("I am %x years old", age) // [11] call printf_str // [17] phi from main::@3 to printf_str [phi:main::@3->printf_str] // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@3->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str3 [phi:main::@3->printf_str#1] -- pbuz1=pbuc1 lda #str3 sta.z printf_str.str+1 jsr printf_str // [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4] // main::@4 // printf("I am %x years old", age) // [13] call printf_uint jsr printf_uint // [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5] // main::@5 // printf("I am %x years old", age) // [15] call printf_str // [17] phi from main::@5 to printf_str [phi:main::@5->printf_str] // [17] phi (byte*) screen#36 = (byte*) screen#23 [phi:main::@5->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str4 [phi:main::@5->printf_str#1] -- pbuz1=pbuc1 lda #str4 sta.z printf_str.str+1 jsr printf_str // main::@return // } // [16] return rts str: .text "Hello, I am " .byte 0 str1: .text "Jesper" .byte 0 str2: .text ". who are you?" .byte 0 str3: .text "I am " .byte 0 str4: .text " years old" .byte 0 } // printf_str // printf_str(byte* zp(4) str) printf_str: { .label str = 4 // [18] phi from printf_str printf_str::@2 to printf_str::@1 [phi:printf_str/printf_str::@2->printf_str::@1] // [18] phi (byte*) screen#18 = (byte*) screen#36 [phi:printf_str/printf_str::@2->printf_str::@1#0] -- register_copy // [18] phi (byte*) printf_str::str#6 = (byte*) printf_str::str#8 [phi:printf_str/printf_str::@2->printf_str::@1#1] -- register_copy // printf_str::@1 __b1: // while(*str) // [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 ldy #0 lda (str),y cmp #0 bne __b2 // printf_str::@return // } // [20] return rts // printf_str::@2 __b2: // *screen++ = *str++ // [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) -- _deref_pbuz1=_deref_pbuz2 ldy #0 lda (str),y sta (screen),y // *screen++ = *str++; // [22] (byte*) screen#1 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // [23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6 -- pbuz1=_inc_pbuz1 inc.z str bne !+ inc.z str+1 !: jmp __b1 } // printf_uint // Print an unsigned int using a specific format // Always prints hexadecimals - ignores min_length and flags printf_uint: { // *screen++ = printf_hextab[(>uvalue)>>4] // [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab ldy #0 sta (screen),y // *screen++ = printf_hextab[(>uvalue)>>4]; // [25] (byte*) screen#5 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // *screen++ = printf_hextab[(>uvalue)&0xf] // [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab ldy #0 sta (screen),y // *screen++ = printf_hextab[(>uvalue)&0xf]; // [27] (byte*) screen#6 ← ++ (byte*) screen#5 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // *screen++ = printf_hextab[(>4] // [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) -- _deref_pbuz1=_deref_pbuc1 lda printf_hextab+((>4) ldy #0 sta (screen),y // *screen++ = printf_hextab[(>4]; // [29] (byte*) screen#7 ← ++ (byte*) screen#6 -- pbuz1=_inc_pbuz1 inc.z screen bne !+ inc.z screen+1 !: // *screen++ = printf_hextab[(printf_str] // [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:printf_string->printf_str#0] -- register_copy // [17] phi (byte*) printf_str::str#8 = (const byte*) main::str1 [phi:printf_string->printf_str#1] -- pbuz1=pbuc1 lda #main.str1 sta.z printf_str.str+1 jsr printf_str // printf_string::@return // } // [35] return rts } // File Data printf_hextab: .text "0123456789abcdef"