From 8d7b0385cbb76d77795f05d48e911f688bcfab37 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Tue, 13 Aug 2019 08:08:43 +0200 Subject: [PATCH] Fixed type inference error message. Closes #260 --- .../model/types/SymbolTypeInference.java | 2 +- .../PassNAddTypeConversionAssignment.java | 21 +- .../dk/camelot64/kickc/test/TestPrograms.java | 10 + src/test/kc/struct-11.kc | 24 + src/test/ref/struct-11.asm | 281 ++ src/test/ref/struct-11.cfg | 160 + src/test/ref/struct-11.log | 3534 +++++++++++++++++ src/test/ref/struct-11.sym | 143 + 8 files changed, 4167 insertions(+), 8 deletions(-) create mode 100644 src/test/kc/struct-11.kc create mode 100644 src/test/ref/struct-11.asm create mode 100644 src/test/ref/struct-11.cfg create mode 100644 src/test/ref/struct-11.log create mode 100644 src/test/ref/struct-11.sym diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java index c68d9a3f0..8fa237f03 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java @@ -50,7 +50,7 @@ public class SymbolTypeInference { } else if(pointerType.equals(SymbolType.STRING)) { return SymbolType.BYTE; } else { - throw new InternalError("Cannot infer pointer element type from pointer type " + pointerType); + throw new CompileError("Cannot infer pointer element type from type: " + pointerType); } } else if(rValue instanceof ConstantArrayList) { return new SymbolTypeArray(((ConstantArrayList) rValue).getElementType()); diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java index 3eaa37e1f..1ee34c0fe 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java @@ -1,5 +1,6 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary; import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; @@ -31,8 +32,14 @@ public class PassNAddTypeConversionAssignment extends Pass2SsaOptimization { ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression; RValue left = binary.getLeft(); RValue right = binary.getRight(); - SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); - SymbolType rightType = SymbolTypeInference.inferType(getProgram().getScope(), right); + SymbolType leftType; + SymbolType rightType; + try { + leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); + rightType = SymbolTypeInference.inferType(getProgram().getScope(), right); + } catch(CompileError e) { + throw new CompileError(e.getMessage(), currentStmt.getSource()); + } if(!SymbolTypeConversion.assignmentTypeMatch(leftType, rightType) || SymbolType.VAR.equals(rightType)) { // Assigning a pointer from an unsigned word if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryAssignmentLValue || programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryCallParameter) { @@ -43,33 +50,33 @@ public class PassNAddTypeConversionAssignment extends Pass2SsaOptimization { modified.set(true); } else if((leftType instanceof SymbolTypePointer) && rightType instanceof SymbolTypePointer && SymbolType.VOID.equals(((SymbolTypePointer) leftType).getElementType())) { if(pass2 || getLog().isVerbosePass1CreateSsa()) - getLog().append("Adding void pointer type conversion cast (" + leftType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false)); + getLog().append("Adding void pointer type conversion cast (" + leftType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false)); binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope()); modified.set(true); } else if((leftType instanceof SymbolTypePointer) && rightType instanceof SymbolTypePointer && SymbolType.VOID.equals(((SymbolTypePointer) rightType).getElementType())) { if(pass2 || getLog().isVerbosePass1CreateSsa()) - getLog().append("Adding pointer type conversion cast to void pointer (" + leftType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false)); + getLog().append("Adding pointer type conversion cast to void pointer (" + leftType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false)); binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope()); modified.set(true); } else if(SymbolType.WORD.equals(leftType) && isLiteralWordCandidate(right)) { // Detect word literal constructor SymbolType conversionType = SymbolType.WORD; if(pass2 || getLog().isVerbosePass1CreateSsa()) - getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope()); modified.set(true); } else if(leftType instanceof SymbolTypePointer && !(leftType instanceof SymbolTypeArray) && isLiteralWordCandidate(right)) { // Detect word literal constructor SymbolType conversionType = SymbolType.WORD; if(pass2 || getLog().isVerbosePass1CreateSsa()) - getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope()); modified.set(true); } else if(SymbolType.DWORD.equals(leftType) && isLiteralWordCandidate(right)) { // Detect dword literal constructor SymbolType conversionType = SymbolType.DWORD; if(pass2 || getLog().isVerbosePass1CreateSsa()) - getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope()); modified.set(true); } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 11f16d206..01e1e0776 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -41,6 +41,11 @@ public class TestPrograms { compileAndCompare("switch-0"); } + @Test + public void testCastError() throws IOException, URISyntaxException { + assertError("cast-error", "Cannot infer pointer element type from type"); + } + @Test public void testInlineAsmParam() throws IOException, URISyntaxException { compileAndCompare("inline-asm-param"); @@ -580,6 +585,11 @@ public class TestPrograms { public void testStructError0() throws IOException, URISyntaxException { assertError("struct-err-0", "Unknown struct type"); } + + @Test + public void testStruct11() throws IOException, URISyntaxException { + compileAndCompare("struct-11"); + } @Test public void testStruct10() throws IOException, URISyntaxException { diff --git a/src/test/kc/struct-11.kc b/src/test/kc/struct-11.kc new file mode 100644 index 000000000..a2ebc5ced --- /dev/null +++ b/src/test/kc/struct-11.kc @@ -0,0 +1,24 @@ +// Example of a struct containing an array + +import "stdlib" +import "print" + +struct Person { + unsigned long id; + char[2] initials; +}; + +struct Person jesper = { 111172, "jg" }; +struct Person henry = { 280173, "hg" }; + +void main() { + print_person(jesper); + print_person(henry); +} + +void print_person(struct Person person) { + print_dword_decimal(person.id); + print_char(' '); + print_str(person.initials); + print_ln(); +} \ No newline at end of file diff --git a/src/test/ref/struct-11.asm b/src/test/ref/struct-11.asm new file mode 100644 index 000000000..084672d95 --- /dev/null +++ b/src/test/ref/struct-11.asm @@ -0,0 +1,281 @@ +// Example of a struct containing an array +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const jesper_id = $1b244 + .const henry_id = $4466d + .label print_char_cursor = $a + .label print_line_cursor = 8 +main: { + lda #<$400 + sta.z print_line_cursor + lda #>$400 + sta.z print_line_cursor+1 + lda #jesper_initials + sta.z print_person.person_initials+1 + lda #<$400 + sta.z print_char_cursor + lda #>$400 + sta.z print_char_cursor+1 + lda #jesper_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>jesper_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + lda.z print_line_cursor + sta.z print_char_cursor + lda.z print_line_cursor+1 + sta.z print_char_cursor+1 + lda #henry_initials + sta.z print_person.person_initials+1 + lda #henry_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>henry_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + rts +} +// print_person(dword zeropage(2) person_id, byte[2] zeropage(6) person_initials) +print_person: { + .label person_id = 2 + .label person_initials = 6 + jsr print_dword_decimal + jsr print_char + lda.z person_initials + sta.z print_str.str + lda.z person_initials+1 + sta.z print_str.str+1 + jsr print_str + jsr print_ln + rts +} +// Print a newline +print_ln: { + b1: + lda #$28 + clc + adc.z print_line_cursor + sta.z print_line_cursor + bcc !+ + inc.z print_line_cursor+1 + !: + lda.z print_line_cursor+1 + cmp.z print_char_cursor+1 + bcc b1 + bne !+ + lda.z print_line_cursor + cmp.z print_char_cursor + bcc b1 + !: + rts +} +// Print a zero-terminated string +// print_str(byte* zeropage($d) str) +print_str: { + .label str = $d + b1: + ldy #0 + lda (str),y + cmp #0 + bne b2 + rts + b2: + ldy #0 + lda (str),y + sta (print_char_cursor),y + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + inc.z str + bne !+ + inc.z str+1 + !: + jmp b1 +} +// Print a single char +print_char: { + .const ch = ' ' + lda #ch + ldy #0 + sta (print_char_cursor),y + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + rts +} +// Print a dword as DECIMAL +// print_dword_decimal(dword zeropage(2) w) +print_dword_decimal: { + .label w = 2 + jsr ultoa + lda #decimal_digits_long + sta.z print_str.str+1 + jsr print_str + rts +} +// Converts unsigned number value to a string representing it in RADIX format. +// If the leading digits are zero they are not included in the string. +// - value : The number to be converted to RADIX +// - buffer : receives the string representing the number and zero-termination. +// - radix : The radix to convert the number to (from the enum RADIX) +// ultoa(dword zeropage(2) value, byte* zeropage($d) buffer) +ultoa: { + .const max_digits = $a + .label digit_value = $f + .label buffer = $d + .label digit = $c + .label value = 2 + lda RADIX_DECIMAL_VALUES_LONG + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1 + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2 + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3 + sta.z digit_value+3 + lda #decimal_digits_long + sta.z buffer+1 + ldx #0 + txa + sta.z digit + b7: + lda.z value+3 + cmp.z digit_value+3 + bcc !+ + bne b5 + lda.z value+2 + cmp.z digit_value+2 + bcc !+ + bne b5 + lda.z value+1 + cmp.z digit_value+1 + bcc !+ + bne b5 + lda.z value + cmp.z digit_value + bcs b5 + !: + b4: + inc.z digit + lda.z digit + cmp #max_digits-1 + bcc b2 + lda.z value + tay + lda DIGITS,y + ldy #0 + sta (buffer),y + inc.z buffer + bne !+ + inc.z buffer+1 + !: + lda #0 + tay + sta (buffer),y + rts + b2: + lda.z digit + asl + asl + tay + lda RADIX_DECIMAL_VALUES_LONG,y + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1,y + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2,y + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3,y + sta.z digit_value+3 + cpx #0 + bne b5 + jmp b7 + b5: + jsr ultoa_append + inc.z buffer + bne !+ + inc.z buffer+1 + !: + ldx #1 + jmp b4 +} +// Used to convert a single digit of an unsigned number value to a string representation +// Counts a single digit up from '0' as long as the value is larger than sub. +// Each time the digit is increased sub is subtracted from value. +// - buffer : pointer to the char that receives the digit +// - value : The value where the digit will be derived from +// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. +// (For decimal the subs used are 10000, 1000, 100, 10, 1) +// returns : the value reduced by sub * digit so that it is less than sub. +// ultoa_append(byte* zeropage($d) buffer, dword zeropage(2) value, dword zeropage($f) sub) +ultoa_append: { + .label buffer = $d + .label value = 2 + .label sub = $f + .label return = 2 + ldx #0 + b1: + lda.z value+3 + cmp.z sub+3 + bcc !+ + bne b2 + lda.z value+2 + cmp.z sub+2 + bcc !+ + bne b2 + lda.z value+1 + cmp.z sub+1 + bcc !+ + bne b2 + lda.z value + cmp.z sub + bcs b2 + !: + lda DIGITS,x + ldy #0 + sta (buffer),y + rts + b2: + inx + lda.z value + sec + sbc.z sub + sta.z value + lda.z value+1 + sbc.z sub+1 + sta.z value+1 + lda.z value+2 + sbc.z sub+2 + sta.z value+2 + lda.z value+3 + sbc.z sub+3 + sta.z value+3 + jmp b1 +} + // The digits used for numbers + DIGITS: .text "0123456789abcdef" + // Values of decimal digits + RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a + // Digits used for storing the decimal word + decimal_digits_long: .fill $b, 0 + jesper_initials: .text "jg" + .byte 0 + henry_initials: .text "hg" + .byte 0 diff --git a/src/test/ref/struct-11.cfg b/src/test/ref/struct-11.cfg new file mode 100644 index 000000000..02c1dd875 --- /dev/null +++ b/src/test/ref/struct-11.cfg @@ -0,0 +1,160 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call print_person + to:main::@1 +main::@1: scope:[main] from main + [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 + [7] call print_person + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return +print_person: scope:[print_person] from main main::@1 + [9] (byte*) print_line_cursor#20 ← phi( main/(byte*) 1024 main::@1/(byte*) print_line_cursor#1 ) + [9] (byte[2]) print_person::person_initials#2 ← phi( main/(const byte[2]) jesper_initials#0 main::@1/(const byte[2]) henry_initials#0 ) + [9] (byte*) print_char_cursor#39 ← phi( main/(byte*) 1024 main::@1/(byte*~) print_char_cursor#49 ) + [9] (dword) print_person::person_id#2 ← phi( main/(const dword) jesper_id#0 main::@1/(const dword) henry_id#0 ) + [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 + [11] call print_dword_decimal + to:print_person::@1 +print_person::@1: scope:[print_person] from print_person + [12] phi() + [13] call print_char + to:print_person::@2 +print_person::@2: scope:[print_person] from print_person::@1 + [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 + [15] call print_str + to:print_person::@3 +print_person::@3: scope:[print_person] from print_person::@2 + [16] phi() + [17] call print_ln + to:print_person::@return +print_person::@return: scope:[print_person] from print_person::@3 + [18] return + to:@return +print_ln: scope:[print_ln] from print_person::@3 + [19] phi() + to:print_ln::@1 +print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 + [20] (byte*) print_line_cursor#9 ← phi( print_ln/(byte*) print_line_cursor#20 print_ln::@1/(byte*) print_line_cursor#1 ) + [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 + [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 + to:print_ln::@return +print_ln::@return: scope:[print_ln] from print_ln::@1 + [23] return + to:@return +print_str: scope:[print_str] from print_dword_decimal::@1 print_person::@2 + [24] (byte*) print_char_cursor#41 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#39 print_person::@2/(byte*) print_char_cursor#25 ) + [24] (byte*) print_str::str#5 ← phi( print_dword_decimal::@1/(const byte[$b]) decimal_digits_long#0 print_person::@2/(byte*) print_str::str#2 ) + to:print_str::@1 +print_str::@1: scope:[print_str] from print_str print_str::@2 + [25] (byte*) print_char_cursor#18 ← phi( print_str/(byte*) print_char_cursor#41 print_str::@2/(byte*) print_char_cursor#1 ) + [25] (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 ) + [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 + to:print_str::@return +print_str::@return: scope:[print_str] from print_str::@1 + [27] return + to:@return +print_str::@2: scope:[print_str] from print_str::@1 + [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) + [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 + [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 + to:print_str::@1 +print_char: scope:[print_char] from print_person::@1 + [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 + [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 + to:print_char::@return +print_char::@return: scope:[print_char] from print_char + [33] return + to:@return +print_dword_decimal: scope:[print_dword_decimal] from print_person + [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 + [35] call ultoa + to:print_dword_decimal::@1 +print_dword_decimal::@1: scope:[print_dword_decimal] from print_dword_decimal + [36] phi() + [37] call print_str + to:print_dword_decimal::@return +print_dword_decimal::@return: scope:[print_dword_decimal] from print_dword_decimal::@1 + [38] return + to:@return +ultoa: scope:[ultoa] from print_dword_decimal + [39] phi() + to:ultoa::@19_1 +ultoa::@19_1: scope:[ultoa] from ultoa + [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) + to:ultoa::@7 +ultoa::@7: scope:[ultoa] from ultoa::@19_1 ultoa::@2 + [41] (dword) ultoa::digit_value#3 ← phi( ultoa::@2/(dword) ultoa::digit_value#0 ultoa::@19_1/(dword) ultoa::digit_value#4 ) + [41] (byte*) ultoa::buffer#28 ← phi( ultoa::@2/(byte*) ultoa::buffer#11 ultoa::@19_1/(const byte[$b]) decimal_digits_long#0 ) + [41] (byte) ultoa::started#8 ← phi( ultoa::@2/(byte) ultoa::started#2 ultoa::@19_1/(byte) 0 ) + [41] (dword) ultoa::value#21 ← phi( ultoa::@2/(dword) ultoa::value#16 ultoa::@19_1/(dword) ultoa::value#1 ) + [41] (byte) ultoa::digit#15 ← phi( ultoa::@2/(byte) ultoa::digit#1 ultoa::@19_1/(byte) 0 ) + [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 + to:ultoa::@4 +ultoa::@4: scope:[ultoa] from ultoa::@6 ultoa::@7 + [43] (byte) ultoa::digit#13 ← phi( ultoa::@6/(byte) ultoa::digit#14 ultoa::@7/(byte) ultoa::digit#15 ) + [43] (byte*) ultoa::buffer#11 ← phi( ultoa::@7/(byte*) ultoa::buffer#28 ultoa::@6/(byte*) ultoa::buffer#4 ) + [43] (byte) ultoa::started#2 ← phi( ultoa::@7/(byte) ultoa::started#8 ultoa::@6/(byte) 1 ) + [43] (dword) ultoa::value#16 ← phi( ultoa::@7/(dword) ultoa::value#21 ultoa::@6/(dword) ultoa::value#0 ) + [44] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#13 + to:ultoa::@1 +ultoa::@1: scope:[ultoa] from ultoa::@4 + [45] if((byte) ultoa::digit#1<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 + to:ultoa::@3 +ultoa::@3: scope:[ultoa] from ultoa::@1 + [46] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#16 + [47] *((byte*) ultoa::buffer#11) ← *((const byte[]) DIGITS#0 + (byte~) ultoa::$4) + [48] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 + [49] *((byte*) ultoa::buffer#3) ← (byte) 0 + to:ultoa::@return +ultoa::@return: scope:[ultoa] from ultoa::@3 + [50] return + to:@return +ultoa::@2: scope:[ultoa] from ultoa::@1 + [51] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 << (byte) 2 + [52] (dword) ultoa::digit_value#0 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0 + (byte~) ultoa::$11) + [53] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 + to:ultoa::@7 +ultoa::@5: scope:[ultoa] from ultoa::@2 ultoa::@7 + [54] (dword) ultoa::digit_value#2 ← phi( ultoa::@2/(dword) ultoa::digit_value#0 ultoa::@7/(dword) ultoa::digit_value#3 ) + [54] (byte*) ultoa::buffer#29 ← phi( ultoa::@2/(byte*) ultoa::buffer#11 ultoa::@7/(byte*) ultoa::buffer#28 ) + [54] (dword) ultoa::value#22 ← phi( ultoa::@2/(dword) ultoa::value#16 ultoa::@7/(dword) ultoa::value#21 ) + [54] (byte) ultoa::digit#14 ← phi( ultoa::@2/(byte) ultoa::digit#1 ultoa::@7/(byte) ultoa::digit#15 ) + [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 + [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 + [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 + [58] call ultoa_append + [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 + to:ultoa::@6 +ultoa::@6: scope:[ultoa] from ultoa::@5 + [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 + [61] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#29 + to:ultoa::@4 +ultoa_append: scope:[ultoa_append] from ultoa::@5 + [62] phi() + to:ultoa_append::@1 +ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2 + [63] (byte) ultoa_append::digit#2 ← phi( ultoa_append/(byte) 0 ultoa_append::@2/(byte) ultoa_append::digit#1 ) + [63] (dword) ultoa_append::value#2 ← phi( ultoa_append/(dword) ultoa_append::value#0 ultoa_append::@2/(dword) ultoa_append::value#1 ) + [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 + to:ultoa_append::@3 +ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1 + [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) + to:ultoa_append::@return +ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3 + [66] return + to:@return +ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1 + [67] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 + [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 + to:ultoa_append::@1 diff --git a/src/test/ref/struct-11.log b/src/test/ref/struct-11.log new file mode 100644 index 000000000..43efa86c1 --- /dev/null +++ b/src/test/ref/struct-11.log @@ -0,0 +1,3534 @@ +Fixing pointer addition (word*~) bsearch16u::$7 ← (word*) bsearch16u::items + (byte~) bsearch16u::$6 +Fixing pointer addition (word*~) bsearch16u::$15 ← (word*) bsearch16u::pivot + (number) 1 +Fixing pointer addition (word*~) bsearch16u::$1 ← (word*) bsearch16u::items - (number) 1 +Fixing pointer array-indexing *((word*) utoa::digit_values + (byte) utoa::digit) +Fixing pointer array-indexing *((dword*) ultoa::digit_values + (byte) ultoa::digit) +Created struct value member variable (dword) jesper_id +Created struct value member variable (byte[2]) jesper_initials +Converted struct value to member variables (struct Person) jesper +Created struct value member variable (dword) henry_id +Created struct value member variable (byte[2]) henry_initials +Converted struct value to member variables (struct Person) henry +Created struct value member variable (dword) print_person::person_id +Created struct value member variable (byte[2]) print_person::person_initials +Converted struct value to member variables (struct Person) print_person::person +Converted procedure struct value parameter to member unwinding (void()) print_person((dword) print_person::person_id , (byte[2]) print_person::person_initials) +Adding struct value list initializer (dword) jesper_id ← (number) $1b244 +Adding struct value list initializer (byte[2]) jesper_initials ← (string) "jg" +Adding struct value list initializer (dword) henry_id ← (number) $4466d +Adding struct value list initializer (byte[2]) henry_initials ← (string) "hg" +Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (dword) jesper_id (byte[2]) jesper_initials +Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (dword) henry_id (byte[2]) henry_initials +Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (dword) print_person::person_id +Replacing struct member reference (struct Person) print_person::person.initials with member unwinding reference (byte[2]) print_person::person_initials +Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src) +Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_lines::str) +Warning! Adding boolean cast to non-boolean condition (byte) print_str_lines::ch +Warning! Adding boolean cast to non-boolean condition *((byte*) print_str::str) +Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_at::str) +Warning! Adding boolean cast to non-boolean sub-expression (byte) print_str_lines::ch +Identified constant variable (byte*) HEAP_TOP +Identified constant variable (dword) jesper_id +Identified constant variable (byte[2]) jesper_initials +Identified constant variable (dword) henry_id +Identified constant variable (byte[2]) henry_initials +Culled Empty Block (label) @1 +Culled Empty Block (label) @2 +Culled Empty Block (label) @3 +Culled Empty Block (label) @4 +Culled Empty Block (label) @5 +Culled Empty Block (label) @6 +Culled Empty Block (label) @7 +Culled Empty Block (label) @9 +Culled Empty Block (label) ultoa::@13 +Culled Empty Block (label) ultoa::@5 +Culled Empty Block (label) ultoa::@14 +Culled Empty Block (label) ultoa::@6 +Culled Empty Block (label) ultoa::@15 +Culled Empty Block (label) ultoa::@7 +Culled Empty Block (label) ultoa::@16 +Culled Empty Block (label) ultoa::@17 +Culled Empty Block (label) ultoa::@22 +Culled Empty Block (label) ultoa::@23 +Culled Empty Block (label) ultoa::@25 +Culled Empty Block (label) @11 +Culled Empty Block (label) ultoa_append::@4 +Culled Empty Block (label) ultoa_append::@5 +Culled Empty Block (label) ultoa_append::@6 +Culled Empty Block (label) ultoa_append::@7 +Culled Empty Block (label) @13 +Culled Empty Block (label) @14 +Culled Empty Block (label) print_str::@4 +Culled Empty Block (label) print_str::@3 +Culled Empty Block (label) print_str::@5 +Culled Empty Block (label) print_str::@6 +Culled Empty Block (label) @15 +Culled Empty Block (label) @16 +Culled Empty Block (label) @17 +Culled Empty Block (label) @18 +Culled Empty Block (label) @19 +Culled Empty Block (label) @20 +Culled Empty Block (label) @21 +Culled Empty Block (label) @22 +Culled Empty Block (label) @23 +Culled Empty Block (label) @24 +Culled Empty Block (label) @25 +Culled Empty Block (label) @27 +Culled Empty Block (label) @28 +Culled Empty Block (label) @29 +Culled Empty Block (label) @30 +Culled Empty Block (label) @31 +Culled Empty Block (label) @32 +Culled Empty Block (label) @33 +Culled Empty Block (label) @34 +Culled Empty Block (label) @35 +Culled Empty Block (label) @37 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@8 +@8: scope:[] from @begin + (byte[]) DIGITS#0 ← (const string) $0 + to:@10 +@10: scope:[] from @8 + (dword[]) RADIX_BINARY_VALUES_LONG#0 ← { (number) $80000000, (number) $40000000, (number) $20000000, (number) $10000000, (number) $8000000, (number) $4000000, (number) $2000000, (number) $1000000, (number) $800000, (number) $400000, (number) $200000, (number) $100000, (number) $80000, (number) $40000, (number) $20000, (number) $10000, (number) $8000, (number) $4000, (number) $2000, (number) $1000, (number) $800, (number) $400, (number) $200, (number) $100, (number) $80, (number) $40, (number) $20, (number) $10, (number) 8, (number) 4, (number) 2 } + (dword[]) RADIX_OCTAL_VALUES_LONG#0 ← { (number) $40000000, (number) $8000000, (number) $1000000, (number) $200000, (number) $40000, (number) $8000, (number) $1000, (number) $200, (number) $40, (number) 8 } + (dword[]) RADIX_DECIMAL_VALUES_LONG#0 ← { (number) $3b9aca00, (number) $5f5e100, (number) $989680, (number) $f4240, (number) $186a0, (number) $2710, (number) $3e8, (number) $64, (number) $a } + (dword[]) RADIX_HEXADECIMAL_VALUES_LONG#0 ← { (number) $10000000, (number) $1000000, (number) $100000, (number) $10000, (number) $1000, (number) $100, (number) $10 } + to:@12 +ultoa: scope:[ultoa] from print_dword_decimal + (byte*) ultoa::buffer#21 ← phi( print_dword_decimal/(byte*) ultoa::buffer#5 ) + (dword) ultoa::value#12 ← phi( print_dword_decimal/(dword) ultoa::value#1 ) + (byte) ultoa::radix#1 ← phi( print_dword_decimal/(byte) ultoa::radix#0 ) + (byte) ultoa::max_digits#0 ← (byte) 0 + (dword*) ultoa::digit_values#0 ← (dword*) 0 + (bool~) ultoa::$0 ← (byte) ultoa::radix#1 == (const byte) DECIMAL + if((bool~) ultoa::$0) goto ultoa::@1 + to:ultoa::@9 +ultoa::@1: scope:[ultoa] from ultoa + (byte*) ultoa::buffer#17 ← phi( ultoa/(byte*) ultoa::buffer#21 ) + (dword) ultoa::value#8 ← phi( ultoa/(dword) ultoa::value#12 ) + (byte) ultoa::max_digits#1 ← (number) $a + (dword*) ultoa::digit_values#1 ← (dword[]) RADIX_DECIMAL_VALUES_LONG#0 + to:ultoa::@8 +ultoa::@9: scope:[ultoa] from ultoa + (dword) ultoa::value#13 ← phi( ultoa/(dword) ultoa::value#12 ) + (byte*) ultoa::buffer#16 ← phi( ultoa/(byte*) ultoa::buffer#21 ) + (byte) ultoa::radix#2 ← phi( ultoa/(byte) ultoa::radix#1 ) + (bool~) ultoa::$1 ← (byte) ultoa::radix#2 == (const byte) HEXADECIMAL + if((bool~) ultoa::$1) goto ultoa::@2 + to:ultoa::@10 +ultoa::@2: scope:[ultoa] from ultoa::@9 + (byte*) ultoa::buffer#18 ← phi( ultoa::@9/(byte*) ultoa::buffer#16 ) + (dword) ultoa::value#9 ← phi( ultoa::@9/(dword) ultoa::value#13 ) + (byte) ultoa::max_digits#2 ← (number) 8 + (dword*) ultoa::digit_values#2 ← (dword[]) RADIX_HEXADECIMAL_VALUES_LONG#0 + to:ultoa::@8 +ultoa::@10: scope:[ultoa] from ultoa::@9 + (dword) ultoa::value#14 ← phi( ultoa::@9/(dword) ultoa::value#13 ) + (byte*) ultoa::buffer#13 ← phi( ultoa::@9/(byte*) ultoa::buffer#16 ) + (byte) ultoa::radix#3 ← phi( ultoa::@9/(byte) ultoa::radix#2 ) + (bool~) ultoa::$2 ← (byte) ultoa::radix#3 == (const byte) OCTAL + if((bool~) ultoa::$2) goto ultoa::@3 + to:ultoa::@11 +ultoa::@3: scope:[ultoa] from ultoa::@10 + (byte*) ultoa::buffer#19 ← phi( ultoa::@10/(byte*) ultoa::buffer#13 ) + (dword) ultoa::value#10 ← phi( ultoa::@10/(dword) ultoa::value#14 ) + (byte) ultoa::max_digits#3 ← (number) $b + (dword*) ultoa::digit_values#3 ← (dword[]) RADIX_OCTAL_VALUES_LONG#0 + to:ultoa::@8 +ultoa::@11: scope:[ultoa] from ultoa::@10 + (dword) ultoa::value#15 ← phi( ultoa::@10/(dword) ultoa::value#14 ) + (byte*) ultoa::buffer#10 ← phi( ultoa::@10/(byte*) ultoa::buffer#13 ) + (byte) ultoa::radix#4 ← phi( ultoa::@10/(byte) ultoa::radix#3 ) + (bool~) ultoa::$3 ← (byte) ultoa::radix#4 == (const byte) BINARY + if((bool~) ultoa::$3) goto ultoa::@4 + to:ultoa::@12 +ultoa::@4: scope:[ultoa] from ultoa::@11 + (byte*) ultoa::buffer#20 ← phi( ultoa::@11/(byte*) ultoa::buffer#10 ) + (dword) ultoa::value#11 ← phi( ultoa::@11/(dword) ultoa::value#15 ) + (byte) ultoa::max_digits#4 ← (number) $20 + (dword*) ultoa::digit_values#4 ← (dword[]) RADIX_BINARY_VALUES_LONG#0 + to:ultoa::@8 +ultoa::@12: scope:[ultoa] from ultoa::@11 + (byte*) ultoa::buffer#6 ← phi( ultoa::@11/(byte*) ultoa::buffer#10 ) + *((byte*) ultoa::buffer#6) ← (byte) 'e' + (byte*) ultoa::buffer#0 ← ++ (byte*) ultoa::buffer#6 + *((byte*) ultoa::buffer#0) ← (byte) 'r' + (byte*) ultoa::buffer#1 ← ++ (byte*) ultoa::buffer#0 + *((byte*) ultoa::buffer#1) ← (byte) 'r' + (byte*) ultoa::buffer#2 ← ++ (byte*) ultoa::buffer#1 + *((byte*) ultoa::buffer#2) ← (number) 0 + to:ultoa::@return +ultoa::@return: scope:[ultoa] from ultoa::@12 ultoa::@20 + return + to:@return +ultoa::@8: scope:[ultoa] from ultoa::@1 ultoa::@2 ultoa::@3 ultoa::@4 + (byte*) ultoa::buffer#15 ← phi( ultoa::@1/(byte*) ultoa::buffer#17 ultoa::@2/(byte*) ultoa::buffer#18 ultoa::@3/(byte*) ultoa::buffer#19 ultoa::@4/(byte*) ultoa::buffer#20 ) + (dword) ultoa::value#7 ← phi( ultoa::@1/(dword) ultoa::value#8 ultoa::@2/(dword) ultoa::value#9 ultoa::@3/(dword) ultoa::value#10 ultoa::@4/(dword) ultoa::value#11 ) + (dword*) ultoa::digit_values#8 ← phi( ultoa::@1/(dword*) ultoa::digit_values#1 ultoa::@2/(dword*) ultoa::digit_values#2 ultoa::@3/(dword*) ultoa::digit_values#3 ultoa::@4/(dword*) ultoa::digit_values#4 ) + (byte) ultoa::max_digits#7 ← phi( ultoa::@1/(byte) ultoa::max_digits#1 ultoa::@2/(byte) ultoa::max_digits#2 ultoa::@3/(byte) ultoa::max_digits#3 ultoa::@4/(byte) ultoa::max_digits#4 ) + (byte) ultoa::started#0 ← (number) 0 + (byte) ultoa::digit#0 ← (number) 0 + to:ultoa::@18 +ultoa::@18: scope:[ultoa] from ultoa::@21 ultoa::@8 + (byte*) ultoa::buffer#11 ← phi( ultoa::@21/(byte*) ultoa::buffer#14 ultoa::@8/(byte*) ultoa::buffer#15 ) + (byte) ultoa::started#3 ← phi( ultoa::@21/(byte) ultoa::started#4 ultoa::@8/(byte) ultoa::started#0 ) + (dword) ultoa::value#5 ← phi( ultoa::@21/(dword) ultoa::value#6 ultoa::@8/(dword) ultoa::value#7 ) + (dword*) ultoa::digit_values#6 ← phi( ultoa::@21/(dword*) ultoa::digit_values#7 ultoa::@8/(dword*) ultoa::digit_values#8 ) + (byte) ultoa::digit#2 ← phi( ultoa::@21/(byte) ultoa::digit#1 ultoa::@8/(byte) ultoa::digit#0 ) + (byte) ultoa::max_digits#5 ← phi( ultoa::@21/(byte) ultoa::max_digits#6 ultoa::@8/(byte) ultoa::max_digits#7 ) + (number~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (number) 1 + (bool~) ultoa::$6 ← (byte) ultoa::digit#2 < (number~) ultoa::$5 + if((bool~) ultoa::$6) goto ultoa::@19 + to:ultoa::@20 +ultoa::@19: scope:[ultoa] from ultoa::@18 + (byte) ultoa::max_digits#8 ← phi( ultoa::@18/(byte) ultoa::max_digits#5 ) + (byte*) ultoa::buffer#12 ← phi( ultoa::@18/(byte*) ultoa::buffer#11 ) + (byte) ultoa::started#2 ← phi( ultoa::@18/(byte) ultoa::started#3 ) + (dword) ultoa::value#2 ← phi( ultoa::@18/(dword) ultoa::value#5 ) + (dword*) ultoa::digit_values#5 ← phi( ultoa::@18/(dword*) ultoa::digit_values#6 ) + (byte) ultoa::digit#3 ← phi( ultoa::@18/(byte) ultoa::digit#2 ) + (byte~) ultoa::$11 ← (byte) ultoa::digit#3 * (const byte) SIZEOF_DWORD + (dword) ultoa::digit_value#0 ← *((dword*) ultoa::digit_values#5 + (byte~) ultoa::$11) + (bool~) ultoa::$7 ← (dword) ultoa::value#2 >= (dword) ultoa::digit_value#0 + (bool~) ultoa::$8 ← (byte) ultoa::started#2 || (bool~) ultoa::$7 + (bool~) ultoa::$9 ← ! (bool~) ultoa::$8 + if((bool~) ultoa::$9) goto ultoa::@21 + to:ultoa::@24 +ultoa::@20: scope:[ultoa] from ultoa::@18 + (byte*) ultoa::buffer#7 ← phi( ultoa::@18/(byte*) ultoa::buffer#11 ) + (dword) ultoa::value#3 ← phi( ultoa::@18/(dword) ultoa::value#5 ) + (byte~) ultoa::$4 ← ((byte)) (dword) ultoa::value#3 + *((byte*) ultoa::buffer#7) ← *((byte[]) DIGITS#0 + (byte~) ultoa::$4) + (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#7 + *((byte*) ultoa::buffer#3) ← (number) 0 + to:ultoa::@return +ultoa::@21: scope:[ultoa] from ultoa::@19 ultoa::@26 + (byte*) ultoa::buffer#14 ← phi( ultoa::@19/(byte*) ultoa::buffer#12 ultoa::@26/(byte*) ultoa::buffer#4 ) + (byte) ultoa::started#4 ← phi( ultoa::@19/(byte) ultoa::started#2 ultoa::@26/(byte) ultoa::started#1 ) + (dword) ultoa::value#6 ← phi( ultoa::@19/(dword) ultoa::value#2 ultoa::@26/(dword) ultoa::value#0 ) + (dword*) ultoa::digit_values#7 ← phi( ultoa::@19/(dword*) ultoa::digit_values#5 ultoa::@26/(dword*) ultoa::digit_values#9 ) + (byte) ultoa::max_digits#6 ← phi( ultoa::@19/(byte) ultoa::max_digits#8 ultoa::@26/(byte) ultoa::max_digits#9 ) + (byte) ultoa::digit#4 ← phi( ultoa::@19/(byte) ultoa::digit#3 ultoa::@26/(byte) ultoa::digit#5 ) + (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#4 + to:ultoa::@18 +ultoa::@24: scope:[ultoa] from ultoa::@19 + (dword*) ultoa::digit_values#10 ← phi( ultoa::@19/(dword*) ultoa::digit_values#5 ) + (byte) ultoa::max_digits#10 ← phi( ultoa::@19/(byte) ultoa::max_digits#8 ) + (byte) ultoa::digit#6 ← phi( ultoa::@19/(byte) ultoa::digit#3 ) + (dword) ultoa::digit_value#1 ← phi( ultoa::@19/(dword) ultoa::digit_value#0 ) + (dword) ultoa::value#4 ← phi( ultoa::@19/(dword) ultoa::value#2 ) + (byte*) ultoa::buffer#8 ← phi( ultoa::@19/(byte*) ultoa::buffer#12 ) + (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#8 + (dword) ultoa_append::value#0 ← (dword) ultoa::value#4 + (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#1 + call ultoa_append + (dword) ultoa_append::return#0 ← (dword) ultoa_append::return#2 + to:ultoa::@26 +ultoa::@26: scope:[ultoa] from ultoa::@24 + (dword*) ultoa::digit_values#9 ← phi( ultoa::@24/(dword*) ultoa::digit_values#10 ) + (byte) ultoa::max_digits#9 ← phi( ultoa::@24/(byte) ultoa::max_digits#10 ) + (byte) ultoa::digit#5 ← phi( ultoa::@24/(byte) ultoa::digit#6 ) + (byte*) ultoa::buffer#9 ← phi( ultoa::@24/(byte*) ultoa::buffer#8 ) + (dword) ultoa_append::return#3 ← phi( ultoa::@24/(dword) ultoa_append::return#0 ) + (dword~) ultoa::$10 ← (dword) ultoa_append::return#3 + (dword) ultoa::value#0 ← (dword~) ultoa::$10 + (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#9 + (byte) ultoa::started#1 ← (number) 1 + to:ultoa::@21 +ultoa_append: scope:[ultoa_append] from ultoa::@24 + (byte*) ultoa_append::buffer#3 ← phi( ultoa::@24/(byte*) ultoa_append::buffer#0 ) + (dword) ultoa_append::sub#3 ← phi( ultoa::@24/(dword) ultoa_append::sub#0 ) + (dword) ultoa_append::value#5 ← phi( ultoa::@24/(dword) ultoa_append::value#0 ) + (byte) ultoa_append::digit#0 ← (number) 0 + to:ultoa_append::@1 +ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2 + (byte*) ultoa_append::buffer#2 ← phi( ultoa_append/(byte*) ultoa_append::buffer#3 ultoa_append::@2/(byte*) ultoa_append::buffer#4 ) + (byte) ultoa_append::digit#4 ← phi( ultoa_append/(byte) ultoa_append::digit#0 ultoa_append::@2/(byte) ultoa_append::digit#1 ) + (dword) ultoa_append::sub#1 ← phi( ultoa_append/(dword) ultoa_append::sub#3 ultoa_append::@2/(dword) ultoa_append::sub#2 ) + (dword) ultoa_append::value#2 ← phi( ultoa_append/(dword) ultoa_append::value#5 ultoa_append::@2/(dword) ultoa_append::value#1 ) + (bool~) ultoa_append::$0 ← (dword) ultoa_append::value#2 >= (dword) ultoa_append::sub#1 + if((bool~) ultoa_append::$0) goto ultoa_append::@2 + to:ultoa_append::@3 +ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1 + (byte*) ultoa_append::buffer#4 ← phi( ultoa_append::@1/(byte*) ultoa_append::buffer#2 ) + (dword) ultoa_append::sub#2 ← phi( ultoa_append::@1/(dword) ultoa_append::sub#1 ) + (dword) ultoa_append::value#3 ← phi( ultoa_append::@1/(dword) ultoa_append::value#2 ) + (byte) ultoa_append::digit#2 ← phi( ultoa_append::@1/(byte) ultoa_append::digit#4 ) + (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 + (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#3 - (dword) ultoa_append::sub#2 + to:ultoa_append::@1 +ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1 + (dword) ultoa_append::value#4 ← phi( ultoa_append::@1/(dword) ultoa_append::value#2 ) + (byte*) ultoa_append::buffer#1 ← phi( ultoa_append::@1/(byte*) ultoa_append::buffer#2 ) + (byte) ultoa_append::digit#3 ← phi( ultoa_append::@1/(byte) ultoa_append::digit#4 ) + *((byte*) ultoa_append::buffer#1) ← *((byte[]) DIGITS#0 + (byte) ultoa_append::digit#3) + (dword) ultoa_append::return#1 ← (dword) ultoa_append::value#4 + to:ultoa_append::@return +ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3 + (dword) ultoa_append::return#4 ← phi( ultoa_append::@3/(dword) ultoa_append::return#1 ) + (dword) ultoa_append::return#2 ← (dword) ultoa_append::return#4 + return + to:@return +@12: scope:[] from @10 + (byte*) print_screen#0 ← ((byte*)) (number) $400 + (byte*) print_line_cursor#0 ← (byte*) print_screen#0 + (byte*) print_char_cursor#0 ← (byte*) print_line_cursor#0 + to:@26 +print_str: scope:[print_str] from print_dword_decimal::@1 print_person::@2 + (byte*) print_char_cursor#41 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#37 print_person::@2/(byte*) print_char_cursor#13 ) + (byte*) print_str::str#5 ← phi( print_dword_decimal::@1/(byte*) print_str::str#1 print_person::@2/(byte*) print_str::str#2 ) + to:print_str::@1 +print_str::@1: scope:[print_str] from print_str print_str::@2 + (byte*) print_char_cursor#35 ← phi( print_str/(byte*) print_char_cursor#41 print_str::@2/(byte*) print_char_cursor#1 ) + (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 ) + (bool~) print_str::$0 ← (number) 0 != *((byte*) print_str::str#3) + if((bool~) print_str::$0) goto print_str::@2 + to:print_str::@return +print_str::@2: scope:[print_str] from print_str::@1 + (byte*) print_char_cursor#18 ← phi( print_str::@1/(byte*) print_char_cursor#35 ) + (byte*) print_str::str#4 ← phi( print_str::@1/(byte*) print_str::str#3 ) + *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#4) + (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 + (byte*) print_str::str#0 ← ++ (byte*) print_str::str#4 + to:print_str::@1 +print_str::@return: scope:[print_str] from print_str::@1 + (byte*) print_char_cursor#19 ← phi( print_str::@1/(byte*) print_char_cursor#35 ) + (byte*) print_char_cursor#2 ← (byte*) print_char_cursor#19 + return + to:@return +print_ln: scope:[print_ln] from print_person::@3 + (byte*) print_char_cursor#36 ← phi( print_person::@3/(byte*) print_char_cursor#14 ) + (byte*) print_line_cursor#18 ← phi( print_person::@3/(byte*) print_line_cursor#20 ) + to:print_ln::@1 +print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 + (byte*) print_char_cursor#20 ← phi( print_ln/(byte*) print_char_cursor#36 print_ln::@1/(byte*) print_char_cursor#20 ) + (byte*) print_line_cursor#9 ← phi( print_ln/(byte*) print_line_cursor#18 print_ln::@1/(byte*) print_line_cursor#1 ) + (byte*~) print_ln::$0 ← (byte*) print_line_cursor#9 + (number) $28 + (byte*) print_line_cursor#1 ← (byte*~) print_ln::$0 + (bool~) print_ln::$1 ← (byte*) print_line_cursor#1 < (byte*) print_char_cursor#20 + if((bool~) print_ln::$1) goto print_ln::@1 + to:print_ln::@2 +print_ln::@2: scope:[print_ln] from print_ln::@1 + (byte*) print_line_cursor#10 ← phi( print_ln::@1/(byte*) print_line_cursor#1 ) + (byte*) print_char_cursor#3 ← (byte*) print_line_cursor#10 + to:print_ln::@return +print_ln::@return: scope:[print_ln] from print_ln::@2 + (byte*) print_char_cursor#21 ← phi( print_ln::@2/(byte*) print_char_cursor#3 ) + (byte*) print_line_cursor#11 ← phi( print_ln::@2/(byte*) print_line_cursor#10 ) + (byte*) print_line_cursor#2 ← (byte*) print_line_cursor#11 + (byte*) print_char_cursor#4 ← (byte*) print_char_cursor#21 + return + to:@return +@26: scope:[] from @12 + (byte*) print_line_cursor#24 ← phi( @12/(byte*) print_line_cursor#0 ) + (byte*) print_char_cursor#44 ← phi( @12/(byte*) print_char_cursor#0 ) + (byte[$b]) decimal_digits_long#0 ← { fill( $b, 0) } + to:@36 +print_dword_decimal: scope:[print_dword_decimal] from print_person + (byte*) print_char_cursor#42 ← phi( print_person/(byte*) print_char_cursor#39 ) + (dword) print_dword_decimal::w#1 ← phi( print_person/(dword) print_dword_decimal::w#0 ) + (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#1 + (byte*) ultoa::buffer#5 ← (byte[$b]) decimal_digits_long#0 + (byte) ultoa::radix#0 ← (const byte) DECIMAL + call ultoa + to:print_dword_decimal::@1 +print_dword_decimal::@1: scope:[print_dword_decimal] from print_dword_decimal + (byte*) print_char_cursor#37 ← phi( print_dword_decimal/(byte*) print_char_cursor#42 ) + (byte*) print_str::str#1 ← (byte[$b]) decimal_digits_long#0 + call print_str + to:print_dword_decimal::@2 +print_dword_decimal::@2: scope:[print_dword_decimal] from print_dword_decimal::@1 + (byte*) print_char_cursor#22 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#2 ) + (byte*) print_char_cursor#5 ← (byte*) print_char_cursor#22 + to:print_dword_decimal::@return +print_dword_decimal::@return: scope:[print_dword_decimal] from print_dword_decimal::@2 + (byte*) print_char_cursor#23 ← phi( print_dword_decimal::@2/(byte*) print_char_cursor#5 ) + (byte*) print_char_cursor#6 ← (byte*) print_char_cursor#23 + return + to:@return +print_char: scope:[print_char] from print_person::@1 + (byte*) print_char_cursor#24 ← phi( print_person::@1/(byte*) print_char_cursor#12 ) + (byte) print_char::ch#1 ← phi( print_person::@1/(byte) print_char::ch#0 ) + *((byte*) print_char_cursor#24) ← (byte) print_char::ch#1 + (byte*) print_char_cursor#7 ← ++ (byte*) print_char_cursor#24 + to:print_char::@return +print_char::@return: scope:[print_char] from print_char + (byte*) print_char_cursor#25 ← phi( print_char/(byte*) print_char_cursor#7 ) + (byte*) print_char_cursor#8 ← (byte*) print_char_cursor#25 + return + to:@return +@36: scope:[] from @26 + (byte*) print_line_cursor#23 ← phi( @26/(byte*) print_line_cursor#24 ) + (byte*) print_char_cursor#43 ← phi( @26/(byte*) print_char_cursor#44 ) + (dword) jesper_id#0 ← (number) $1b244 + (byte[2]) jesper_initials#0 ← (const string) $1 + (dword) henry_id#0 ← (number) $4466d + (byte[2]) henry_initials#0 ← (const string) $2 + to:@38 +main: scope:[main] from @38 + (byte*) print_line_cursor#19 ← phi( @38/(byte*) print_line_cursor#21 ) + (byte*) print_char_cursor#38 ← phi( @38/(byte*) print_char_cursor#40 ) + (dword) print_person::person_id#0 ← (dword) jesper_id#0 + (byte[2]) print_person::person_initials#0 ← (byte[2]) jesper_initials#0 + call print_person + to:main::@1 +main::@1: scope:[main] from main + (byte*) print_line_cursor#12 ← phi( main/(byte*) print_line_cursor#7 ) + (byte*) print_char_cursor#26 ← phi( main/(byte*) print_char_cursor#16 ) + (byte*) print_char_cursor#9 ← (byte*) print_char_cursor#26 + (byte*) print_line_cursor#3 ← (byte*) print_line_cursor#12 + (dword) print_person::person_id#1 ← (dword) henry_id#0 + (byte[2]) print_person::person_initials#1 ← (byte[2]) henry_initials#0 + call print_person + to:main::@2 +main::@2: scope:[main] from main::@1 + (byte*) print_line_cursor#13 ← phi( main::@1/(byte*) print_line_cursor#7 ) + (byte*) print_char_cursor#27 ← phi( main::@1/(byte*) print_char_cursor#16 ) + (byte*) print_char_cursor#10 ← (byte*) print_char_cursor#27 + (byte*) print_line_cursor#4 ← (byte*) print_line_cursor#13 + to:main::@return +main::@return: scope:[main] from main::@2 + (byte*) print_line_cursor#14 ← phi( main::@2/(byte*) print_line_cursor#4 ) + (byte*) print_char_cursor#28 ← phi( main::@2/(byte*) print_char_cursor#10 ) + (byte*) print_char_cursor#11 ← (byte*) print_char_cursor#28 + (byte*) print_line_cursor#5 ← (byte*) print_line_cursor#14 + return + to:@return +print_person: scope:[print_person] from main main::@1 + (byte*) print_line_cursor#26 ← phi( main/(byte*) print_line_cursor#19 main::@1/(byte*) print_line_cursor#3 ) + (byte[2]) print_person::person_initials#4 ← phi( main/(byte[2]) print_person::person_initials#0 main::@1/(byte[2]) print_person::person_initials#1 ) + (byte*) print_char_cursor#39 ← phi( main/(byte*) print_char_cursor#38 main::@1/(byte*) print_char_cursor#9 ) + (dword) print_person::person_id#2 ← phi( main/(dword) print_person::person_id#0 main::@1/(dword) print_person::person_id#1 ) + (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 + call print_dword_decimal + to:print_person::@1 +print_person::@1: scope:[print_person] from print_person + (byte*) print_line_cursor#25 ← phi( print_person/(byte*) print_line_cursor#26 ) + (byte[2]) print_person::person_initials#3 ← phi( print_person/(byte[2]) print_person::person_initials#4 ) + (byte*) print_char_cursor#29 ← phi( print_person/(byte*) print_char_cursor#6 ) + (byte*) print_char_cursor#12 ← (byte*) print_char_cursor#29 + (byte) print_char::ch#0 ← (byte) ' ' + call print_char + to:print_person::@2 +print_person::@2: scope:[print_person] from print_person::@1 + (byte*) print_line_cursor#22 ← phi( print_person::@1/(byte*) print_line_cursor#25 ) + (byte[2]) print_person::person_initials#2 ← phi( print_person::@1/(byte[2]) print_person::person_initials#3 ) + (byte*) print_char_cursor#30 ← phi( print_person::@1/(byte*) print_char_cursor#8 ) + (byte*) print_char_cursor#13 ← (byte*) print_char_cursor#30 + (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 + call print_str + to:print_person::@3 +print_person::@3: scope:[print_person] from print_person::@2 + (byte*) print_line_cursor#20 ← phi( print_person::@2/(byte*) print_line_cursor#22 ) + (byte*) print_char_cursor#31 ← phi( print_person::@2/(byte*) print_char_cursor#2 ) + (byte*) print_char_cursor#14 ← (byte*) print_char_cursor#31 + call print_ln + to:print_person::@4 +print_person::@4: scope:[print_person] from print_person::@3 + (byte*) print_char_cursor#32 ← phi( print_person::@3/(byte*) print_char_cursor#4 ) + (byte*) print_line_cursor#15 ← phi( print_person::@3/(byte*) print_line_cursor#2 ) + (byte*) print_line_cursor#6 ← (byte*) print_line_cursor#15 + (byte*) print_char_cursor#15 ← (byte*) print_char_cursor#32 + to:print_person::@return +print_person::@return: scope:[print_person] from print_person::@4 + (byte*) print_line_cursor#16 ← phi( print_person::@4/(byte*) print_line_cursor#6 ) + (byte*) print_char_cursor#33 ← phi( print_person::@4/(byte*) print_char_cursor#15 ) + (byte*) print_char_cursor#16 ← (byte*) print_char_cursor#33 + (byte*) print_line_cursor#7 ← (byte*) print_line_cursor#16 + return + to:@return +@38: scope:[] from @36 + (byte*) print_line_cursor#21 ← phi( @36/(byte*) print_line_cursor#23 ) + (byte*) print_char_cursor#40 ← phi( @36/(byte*) print_char_cursor#43 ) + call main + to:@39 +@39: scope:[] from @38 + (byte*) print_line_cursor#17 ← phi( @38/(byte*) print_line_cursor#5 ) + (byte*) print_char_cursor#34 ← phi( @38/(byte*) print_char_cursor#11 ) + (byte*) print_char_cursor#17 ← (byte*) print_char_cursor#34 + (byte*) print_line_cursor#8 ← (byte*) print_line_cursor#17 + to:@end +@end: scope:[] from @39 + +SYMBOL TABLE SSA +(const string) $0 = (string) "0123456789abcdef"z +(const string) $1 = (string) "jg" +(const string) $2 = (string) "hg" +(label) @10 +(label) @12 +(label) @26 +(label) @36 +(label) @38 +(label) @39 +(label) @8 +(label) @begin +(label) @end +(const byte) BINARY = (number) 2 +(const byte) DECIMAL = (number) $a +(byte[]) DIGITS +(byte[]) DIGITS#0 +(const byte) HEXADECIMAL = (number) $10 +(const byte) OCTAL = (number) 8 +(dword) Person::id +(byte[2]) Person::initials +(const byte) RADIX::BINARY = (number) 2 +(const byte) RADIX::DECIMAL = (number) $a +(const byte) RADIX::HEXADECIMAL = (number) $10 +(const byte) RADIX::OCTAL = (number) 8 +(dword[]) RADIX_BINARY_VALUES_LONG +(dword[]) RADIX_BINARY_VALUES_LONG#0 +(dword[]) RADIX_DECIMAL_VALUES_LONG +(dword[]) RADIX_DECIMAL_VALUES_LONG#0 +(dword[]) RADIX_HEXADECIMAL_VALUES_LONG +(dword[]) RADIX_HEXADECIMAL_VALUES_LONG#0 +(dword[]) RADIX_OCTAL_VALUES_LONG +(dword[]) RADIX_OCTAL_VALUES_LONG#0 +(const byte) SIZEOF_DWORD = (byte) 4 +(byte[$b]) decimal_digits_long +(byte[$b]) decimal_digits_long#0 +(dword) henry_id +(dword) henry_id#0 +(byte[2]) henry_initials +(byte[2]) henry_initials#0 +(dword) jesper_id +(dword) jesper_id#0 +(byte[2]) jesper_initials +(byte[2]) jesper_initials#0 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return +(void()) print_char((byte) print_char::ch) +(label) print_char::@return +(byte) print_char::ch +(byte) print_char::ch#0 +(byte) print_char::ch#1 +(byte*) print_char_cursor +(byte*) print_char_cursor#0 +(byte*) print_char_cursor#1 +(byte*) print_char_cursor#10 +(byte*) print_char_cursor#11 +(byte*) print_char_cursor#12 +(byte*) print_char_cursor#13 +(byte*) print_char_cursor#14 +(byte*) print_char_cursor#15 +(byte*) print_char_cursor#16 +(byte*) print_char_cursor#17 +(byte*) print_char_cursor#18 +(byte*) print_char_cursor#19 +(byte*) print_char_cursor#2 +(byte*) print_char_cursor#20 +(byte*) print_char_cursor#21 +(byte*) print_char_cursor#22 +(byte*) print_char_cursor#23 +(byte*) print_char_cursor#24 +(byte*) print_char_cursor#25 +(byte*) print_char_cursor#26 +(byte*) print_char_cursor#27 +(byte*) print_char_cursor#28 +(byte*) print_char_cursor#29 +(byte*) print_char_cursor#3 +(byte*) print_char_cursor#30 +(byte*) print_char_cursor#31 +(byte*) print_char_cursor#32 +(byte*) print_char_cursor#33 +(byte*) print_char_cursor#34 +(byte*) print_char_cursor#35 +(byte*) print_char_cursor#36 +(byte*) print_char_cursor#37 +(byte*) print_char_cursor#38 +(byte*) print_char_cursor#39 +(byte*) print_char_cursor#4 +(byte*) print_char_cursor#40 +(byte*) print_char_cursor#41 +(byte*) print_char_cursor#42 +(byte*) print_char_cursor#43 +(byte*) print_char_cursor#44 +(byte*) print_char_cursor#5 +(byte*) print_char_cursor#6 +(byte*) print_char_cursor#7 +(byte*) print_char_cursor#8 +(byte*) print_char_cursor#9 +(void()) print_dword_decimal((dword) print_dword_decimal::w) +(label) print_dword_decimal::@1 +(label) print_dword_decimal::@2 +(label) print_dword_decimal::@return +(dword) print_dword_decimal::w +(dword) print_dword_decimal::w#0 +(dword) print_dword_decimal::w#1 +(byte*) print_line_cursor +(byte*) print_line_cursor#0 +(byte*) print_line_cursor#1 +(byte*) print_line_cursor#10 +(byte*) print_line_cursor#11 +(byte*) print_line_cursor#12 +(byte*) print_line_cursor#13 +(byte*) print_line_cursor#14 +(byte*) print_line_cursor#15 +(byte*) print_line_cursor#16 +(byte*) print_line_cursor#17 +(byte*) print_line_cursor#18 +(byte*) print_line_cursor#19 +(byte*) print_line_cursor#2 +(byte*) print_line_cursor#20 +(byte*) print_line_cursor#21 +(byte*) print_line_cursor#22 +(byte*) print_line_cursor#23 +(byte*) print_line_cursor#24 +(byte*) print_line_cursor#25 +(byte*) print_line_cursor#26 +(byte*) print_line_cursor#3 +(byte*) print_line_cursor#4 +(byte*) print_line_cursor#5 +(byte*) print_line_cursor#6 +(byte*) print_line_cursor#7 +(byte*) print_line_cursor#8 +(byte*) print_line_cursor#9 +(void()) print_ln() +(byte*~) print_ln::$0 +(bool~) print_ln::$1 +(label) print_ln::@1 +(label) print_ln::@2 +(label) print_ln::@return +(void()) print_person((dword) print_person::person_id , (byte[2]) print_person::person_initials) +(label) print_person::@1 +(label) print_person::@2 +(label) print_person::@3 +(label) print_person::@4 +(label) print_person::@return +(struct Person) print_person::person +(dword) print_person::person_id +(dword) print_person::person_id#0 +(dword) print_person::person_id#1 +(dword) print_person::person_id#2 +(byte[2]) print_person::person_initials +(byte[2]) print_person::person_initials#0 +(byte[2]) print_person::person_initials#1 +(byte[2]) print_person::person_initials#2 +(byte[2]) print_person::person_initials#3 +(byte[2]) print_person::person_initials#4 +(byte*) print_screen +(byte*) print_screen#0 +(void()) print_str((byte*) print_str::str) +(bool~) print_str::$0 +(label) print_str::@1 +(label) print_str::@2 +(label) print_str::@return +(byte*) print_str::str +(byte*) print_str::str#0 +(byte*) print_str::str#1 +(byte*) print_str::str#2 +(byte*) print_str::str#3 +(byte*) print_str::str#4 +(byte*) print_str::str#5 +(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) +(bool~) ultoa::$0 +(bool~) ultoa::$1 +(dword~) ultoa::$10 +(byte~) ultoa::$11 +(bool~) ultoa::$2 +(bool~) ultoa::$3 +(byte~) ultoa::$4 +(number~) ultoa::$5 +(bool~) ultoa::$6 +(bool~) ultoa::$7 +(bool~) ultoa::$8 +(bool~) ultoa::$9 +(label) ultoa::@1 +(label) ultoa::@10 +(label) ultoa::@11 +(label) ultoa::@12 +(label) ultoa::@18 +(label) ultoa::@19 +(label) ultoa::@2 +(label) ultoa::@20 +(label) ultoa::@21 +(label) ultoa::@24 +(label) ultoa::@26 +(label) ultoa::@3 +(label) ultoa::@4 +(label) ultoa::@8 +(label) ultoa::@9 +(label) ultoa::@return +(byte*) ultoa::buffer +(byte*) ultoa::buffer#0 +(byte*) ultoa::buffer#1 +(byte*) ultoa::buffer#10 +(byte*) ultoa::buffer#11 +(byte*) ultoa::buffer#12 +(byte*) ultoa::buffer#13 +(byte*) ultoa::buffer#14 +(byte*) ultoa::buffer#15 +(byte*) ultoa::buffer#16 +(byte*) ultoa::buffer#17 +(byte*) ultoa::buffer#18 +(byte*) ultoa::buffer#19 +(byte*) ultoa::buffer#2 +(byte*) ultoa::buffer#20 +(byte*) ultoa::buffer#21 +(byte*) ultoa::buffer#3 +(byte*) ultoa::buffer#4 +(byte*) ultoa::buffer#5 +(byte*) ultoa::buffer#6 +(byte*) ultoa::buffer#7 +(byte*) ultoa::buffer#8 +(byte*) ultoa::buffer#9 +(byte) ultoa::digit +(byte) ultoa::digit#0 +(byte) ultoa::digit#1 +(byte) ultoa::digit#2 +(byte) ultoa::digit#3 +(byte) ultoa::digit#4 +(byte) ultoa::digit#5 +(byte) ultoa::digit#6 +(dword) ultoa::digit_value +(dword) ultoa::digit_value#0 +(dword) ultoa::digit_value#1 +(dword*) ultoa::digit_values +(dword*) ultoa::digit_values#0 +(dword*) ultoa::digit_values#1 +(dword*) ultoa::digit_values#10 +(dword*) ultoa::digit_values#2 +(dword*) ultoa::digit_values#3 +(dword*) ultoa::digit_values#4 +(dword*) ultoa::digit_values#5 +(dword*) ultoa::digit_values#6 +(dword*) ultoa::digit_values#7 +(dword*) ultoa::digit_values#8 +(dword*) ultoa::digit_values#9 +(byte) ultoa::max_digits +(byte) ultoa::max_digits#0 +(byte) ultoa::max_digits#1 +(byte) ultoa::max_digits#10 +(byte) ultoa::max_digits#2 +(byte) ultoa::max_digits#3 +(byte) ultoa::max_digits#4 +(byte) ultoa::max_digits#5 +(byte) ultoa::max_digits#6 +(byte) ultoa::max_digits#7 +(byte) ultoa::max_digits#8 +(byte) ultoa::max_digits#9 +(byte) ultoa::radix +(byte) ultoa::radix#0 +(byte) ultoa::radix#1 +(byte) ultoa::radix#2 +(byte) ultoa::radix#3 +(byte) ultoa::radix#4 +(byte) ultoa::started +(byte) ultoa::started#0 +(byte) ultoa::started#1 +(byte) ultoa::started#2 +(byte) ultoa::started#3 +(byte) ultoa::started#4 +(dword) ultoa::value +(dword) ultoa::value#0 +(dword) ultoa::value#1 +(dword) ultoa::value#10 +(dword) ultoa::value#11 +(dword) ultoa::value#12 +(dword) ultoa::value#13 +(dword) ultoa::value#14 +(dword) ultoa::value#15 +(dword) ultoa::value#2 +(dword) ultoa::value#3 +(dword) ultoa::value#4 +(dword) ultoa::value#5 +(dword) ultoa::value#6 +(dword) ultoa::value#7 +(dword) ultoa::value#8 +(dword) ultoa::value#9 +(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) +(bool~) ultoa_append::$0 +(label) ultoa_append::@1 +(label) ultoa_append::@2 +(label) ultoa_append::@3 +(label) ultoa_append::@return +(byte*) ultoa_append::buffer +(byte*) ultoa_append::buffer#0 +(byte*) ultoa_append::buffer#1 +(byte*) ultoa_append::buffer#2 +(byte*) ultoa_append::buffer#3 +(byte*) ultoa_append::buffer#4 +(byte) ultoa_append::digit +(byte) ultoa_append::digit#0 +(byte) ultoa_append::digit#1 +(byte) ultoa_append::digit#2 +(byte) ultoa_append::digit#3 +(byte) ultoa_append::digit#4 +(dword) ultoa_append::return +(dword) ultoa_append::return#0 +(dword) ultoa_append::return#1 +(dword) ultoa_append::return#2 +(dword) ultoa_append::return#3 +(dword) ultoa_append::return#4 +(dword) ultoa_append::sub +(dword) ultoa_append::sub#0 +(dword) ultoa_append::sub#1 +(dword) ultoa_append::sub#2 +(dword) ultoa_append::sub#3 +(dword) ultoa_append::value +(dword) ultoa_append::value#0 +(dword) ultoa_append::value#1 +(dword) ultoa_append::value#2 +(dword) ultoa_append::value#3 +(dword) ultoa_append::value#4 +(dword) ultoa_append::value#5 + +Adding number conversion cast (unumber) $a in (byte) ultoa::max_digits#1 ← (number) $a +Adding number conversion cast (unumber) 8 in (byte) ultoa::max_digits#2 ← (number) 8 +Adding number conversion cast (unumber) $b in (byte) ultoa::max_digits#3 ← (number) $b +Adding number conversion cast (unumber) $20 in (byte) ultoa::max_digits#4 ← (number) $20 +Adding number conversion cast (unumber) 0 in *((byte*) ultoa::buffer#2) ← (number) 0 +Adding number conversion cast (unumber) 0 in (byte) ultoa::started#0 ← (number) 0 +Adding number conversion cast (unumber) 0 in (byte) ultoa::digit#0 ← (number) 0 +Adding number conversion cast (unumber) 1 in (number~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (number) 1 +Adding number conversion cast (unumber) ultoa::$5 in (number~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (unumber)(number) 1 +Adding number conversion cast (unumber) 0 in *((byte*) ultoa::buffer#3) ← (number) 0 +Adding number conversion cast (unumber) 1 in (byte) ultoa::started#1 ← (number) 1 +Adding number conversion cast (unumber) 0 in (byte) ultoa_append::digit#0 ← (number) 0 +Adding number conversion cast (unumber) 0 in (bool~) print_str::$0 ← (number) 0 != *((byte*) print_str::str#3) +Adding number conversion cast (unumber) $28 in (byte*~) print_ln::$0 ← (byte*) print_line_cursor#9 + (number) $28 +Adding number conversion cast (unumber) $1b244 in (dword) jesper_id#0 ← (number) $1b244 +Adding number conversion cast (unumber) $4466d in (dword) henry_id#0 ← (number) $4466d +Successful SSA optimization PassNAddNumberTypeConversions +Added casts to value list in (dword[]) RADIX_BINARY_VALUES_LONG#0 ← (dword[]){ (dword)(number) $80000000, (dword)(number) $40000000, (dword)(number) $20000000, (dword)(number) $10000000, (dword)(number) $8000000, (dword)(number) $4000000, (dword)(number) $2000000, (dword)(number) $1000000, (dword)(number) $800000, (dword)(number) $400000, (dword)(number) $200000, (dword)(number) $100000, (dword)(number) $80000, (dword)(number) $40000, (dword)(number) $20000, (dword)(number) $10000, (dword)(number) $8000, (dword)(number) $4000, (dword)(number) $2000, (dword)(number) $1000, (dword)(number) $800, (dword)(number) $400, (dword)(number) $200, (dword)(number) $100, (dword)(number) $80, (dword)(number) $40, (dword)(number) $20, (dword)(number) $10, (dword)(number) 8, (dword)(number) 4, (dword)(number) 2 } +Added casts to value list in (dword[]) RADIX_OCTAL_VALUES_LONG#0 ← (dword[]){ (dword)(number) $40000000, (dword)(number) $8000000, (dword)(number) $1000000, (dword)(number) $200000, (dword)(number) $40000, (dword)(number) $8000, (dword)(number) $1000, (dword)(number) $200, (dword)(number) $40, (dword)(number) 8 } +Added casts to value list in (dword[]) RADIX_DECIMAL_VALUES_LONG#0 ← (dword[]){ (dword)(number) $3b9aca00, (dword)(number) $5f5e100, (dword)(number) $989680, (dword)(number) $f4240, (dword)(number) $186a0, (dword)(number) $2710, (dword)(number) $3e8, (dword)(number) $64, (dword)(number) $a } +Added casts to value list in (dword[]) RADIX_HEXADECIMAL_VALUES_LONG#0 ← (dword[]){ (dword)(number) $10000000, (dword)(number) $1000000, (dword)(number) $100000, (dword)(number) $10000, (dword)(number) $1000, (dword)(number) $100, (dword)(number) $10 } +Successful SSA optimization PassNAddInitializerValueListTypeCasts +Inlining cast (byte) ultoa::max_digits#1 ← (unumber)(number) $a +Inlining cast (byte) ultoa::max_digits#2 ← (unumber)(number) 8 +Inlining cast (byte) ultoa::max_digits#3 ← (unumber)(number) $b +Inlining cast (byte) ultoa::max_digits#4 ← (unumber)(number) $20 +Inlining cast *((byte*) ultoa::buffer#2) ← (unumber)(number) 0 +Inlining cast (byte) ultoa::started#0 ← (unumber)(number) 0 +Inlining cast (byte) ultoa::digit#0 ← (unumber)(number) 0 +Inlining cast (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#3 +Inlining cast *((byte*) ultoa::buffer#3) ← (unumber)(number) 0 +Inlining cast (byte) ultoa::started#1 ← (unumber)(number) 1 +Inlining cast (byte) ultoa_append::digit#0 ← (unumber)(number) 0 +Inlining cast (byte*) print_screen#0 ← (byte*)(number) $400 +Inlining cast (dword) jesper_id#0 ← (unumber)(number) $1b244 +Inlining cast (dword) henry_id#0 ← (unumber)(number) $4466d +Successful SSA optimization Pass2InlineCast +Simplifying constant integer cast $80000000 +Simplifying constant integer cast $40000000 +Simplifying constant integer cast $20000000 +Simplifying constant integer cast $10000000 +Simplifying constant integer cast $8000000 +Simplifying constant integer cast $4000000 +Simplifying constant integer cast $2000000 +Simplifying constant integer cast $1000000 +Simplifying constant integer cast $800000 +Simplifying constant integer cast $400000 +Simplifying constant integer cast $200000 +Simplifying constant integer cast $100000 +Simplifying constant integer cast $80000 +Simplifying constant integer cast $40000 +Simplifying constant integer cast $20000 +Simplifying constant integer cast $10000 +Simplifying constant integer cast $8000 +Simplifying constant integer cast $4000 +Simplifying constant integer cast $2000 +Simplifying constant integer cast $1000 +Simplifying constant integer cast $800 +Simplifying constant integer cast $400 +Simplifying constant integer cast $200 +Simplifying constant integer cast $100 +Simplifying constant integer cast $80 +Simplifying constant integer cast $40 +Simplifying constant integer cast $20 +Simplifying constant integer cast $10 +Simplifying constant integer cast 8 +Simplifying constant integer cast 4 +Simplifying constant integer cast 2 +Simplifying constant integer cast $40000000 +Simplifying constant integer cast $8000000 +Simplifying constant integer cast $1000000 +Simplifying constant integer cast $200000 +Simplifying constant integer cast $40000 +Simplifying constant integer cast $8000 +Simplifying constant integer cast $1000 +Simplifying constant integer cast $200 +Simplifying constant integer cast $40 +Simplifying constant integer cast 8 +Simplifying constant integer cast $3b9aca00 +Simplifying constant integer cast $5f5e100 +Simplifying constant integer cast $989680 +Simplifying constant integer cast $f4240 +Simplifying constant integer cast $186a0 +Simplifying constant integer cast $2710 +Simplifying constant integer cast $3e8 +Simplifying constant integer cast $64 +Simplifying constant integer cast $a +Simplifying constant integer cast $10000000 +Simplifying constant integer cast $1000000 +Simplifying constant integer cast $100000 +Simplifying constant integer cast $10000 +Simplifying constant integer cast $1000 +Simplifying constant integer cast $100 +Simplifying constant integer cast $10 +Simplifying constant integer cast $a +Simplifying constant integer cast 8 +Simplifying constant integer cast $b +Simplifying constant integer cast $20 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Simplifying constant integer cast 0 +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast $28 +Simplifying constant integer cast $1b244 +Simplifying constant integer cast $4466d +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) $a +Finalized unsigned number type (byte) 8 +Finalized unsigned number type (byte) $b +Finalized unsigned number type (byte) $20 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $28 +Finalized unsigned number type (dword) $1b244 +Finalized unsigned number type (dword) $4466d +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to byte in (unumber~) ultoa::$5 ← (byte) ultoa::max_digits#5 - (byte) 1 +Alias (dword) ultoa::value#10 = (dword) ultoa::value#8 (dword) ultoa::value#12 (dword) ultoa::value#13 (dword) ultoa::value#9 (dword) ultoa::value#14 (dword) ultoa::value#15 (dword) ultoa::value#11 +Alias (byte*) ultoa::buffer#10 = (byte*) ultoa::buffer#17 (byte*) ultoa::buffer#21 (byte*) ultoa::buffer#16 (byte*) ultoa::buffer#18 (byte*) ultoa::buffer#13 (byte*) ultoa::buffer#19 (byte*) ultoa::buffer#20 (byte*) ultoa::buffer#6 +Alias (byte) ultoa::radix#1 = (byte) ultoa::radix#2 (byte) ultoa::radix#3 (byte) ultoa::radix#4 +Alias (byte) ultoa::digit#2 = (byte) ultoa::digit#3 (byte) ultoa::digit#6 (byte) ultoa::digit#5 +Alias (dword*) ultoa::digit_values#10 = (dword*) ultoa::digit_values#5 (dword*) ultoa::digit_values#6 (dword*) ultoa::digit_values#9 +Alias (dword) ultoa::value#2 = (dword) ultoa::value#5 (dword) ultoa::value#3 (dword) ultoa::value#4 +Alias (byte) ultoa::started#2 = (byte) ultoa::started#3 +Alias (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#12 (byte*) ultoa::buffer#7 (byte*) ultoa::buffer#8 (byte*) ultoa::buffer#9 +Alias (byte) ultoa::max_digits#10 = (byte) ultoa::max_digits#8 (byte) ultoa::max_digits#5 (byte) ultoa::max_digits#9 +Alias (dword) ultoa::digit_value#0 = (dword) ultoa::digit_value#1 +Alias (dword) ultoa_append::return#0 = (dword) ultoa_append::return#3 +Alias (dword) ultoa::value#0 = (dword~) ultoa::$10 +Alias (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#4 (byte) ultoa_append::digit#3 +Alias (dword) ultoa_append::value#2 = (dword) ultoa_append::value#3 (dword) ultoa_append::value#4 (dword) ultoa_append::return#1 (dword) ultoa_append::return#4 (dword) ultoa_append::return#2 +Alias (dword) ultoa_append::sub#1 = (dword) ultoa_append::sub#2 +Alias (byte*) ultoa_append::buffer#1 = (byte*) ultoa_append::buffer#4 (byte*) ultoa_append::buffer#2 +Alias (byte*) print_char_cursor#0 = (byte*) print_line_cursor#0 (byte*) print_screen#0 (byte*) print_char_cursor#44 (byte*) print_line_cursor#24 (byte*) print_char_cursor#43 (byte*) print_line_cursor#23 (byte*) print_char_cursor#40 (byte*) print_line_cursor#21 +Alias (byte*) print_str::str#3 = (byte*) print_str::str#4 +Alias (byte*) print_char_cursor#18 = (byte*) print_char_cursor#35 (byte*) print_char_cursor#19 (byte*) print_char_cursor#2 +Alias (byte*) print_line_cursor#1 = (byte*~) print_ln::$0 (byte*) print_line_cursor#10 (byte*) print_char_cursor#3 (byte*) print_line_cursor#11 (byte*) print_char_cursor#21 (byte*) print_line_cursor#2 (byte*) print_char_cursor#4 +Alias (byte*) print_char_cursor#37 = (byte*) print_char_cursor#42 +Alias (byte*) print_char_cursor#22 = (byte*) print_char_cursor#5 (byte*) print_char_cursor#23 (byte*) print_char_cursor#6 +Alias (byte*) print_char_cursor#25 = (byte*) print_char_cursor#7 (byte*) print_char_cursor#8 +Alias (byte*) print_char_cursor#26 = (byte*) print_char_cursor#9 +Alias (byte*) print_line_cursor#12 = (byte*) print_line_cursor#3 +Alias (byte*) print_char_cursor#10 = (byte*) print_char_cursor#27 (byte*) print_char_cursor#28 (byte*) print_char_cursor#11 +Alias (byte*) print_line_cursor#13 = (byte*) print_line_cursor#4 (byte*) print_line_cursor#14 (byte*) print_line_cursor#5 +Alias (byte[2]) print_person::person_initials#2 = (byte[2]) print_person::person_initials#3 (byte[2]) print_person::person_initials#4 +Alias (byte*) print_line_cursor#20 = (byte*) print_line_cursor#25 (byte*) print_line_cursor#26 (byte*) print_line_cursor#22 +Alias (byte*) print_char_cursor#12 = (byte*) print_char_cursor#29 +Alias (byte*) print_char_cursor#13 = (byte*) print_char_cursor#30 +Alias (byte*) print_char_cursor#14 = (byte*) print_char_cursor#31 +Alias (byte*) print_line_cursor#15 = (byte*) print_line_cursor#6 (byte*) print_line_cursor#16 (byte*) print_line_cursor#7 +Alias (byte*) print_char_cursor#15 = (byte*) print_char_cursor#32 (byte*) print_char_cursor#33 (byte*) print_char_cursor#16 +Alias (byte*) print_char_cursor#17 = (byte*) print_char_cursor#34 +Alias (byte*) print_line_cursor#17 = (byte*) print_line_cursor#8 +Successful SSA optimization Pass2AliasElimination +Alias (dword) ultoa::value#10 = (dword) ultoa::value#7 +Alias (byte*) ultoa::buffer#10 = (byte*) ultoa::buffer#15 +Alias (byte) ultoa::digit#2 = (byte) ultoa::digit#4 +Alias (byte) ultoa::max_digits#10 = (byte) ultoa::max_digits#6 +Alias (dword*) ultoa::digit_values#10 = (dword*) ultoa::digit_values#7 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) ultoa::radix#1 (byte) ultoa::radix#0 +Identical Phi Values (dword) ultoa::value#10 (dword) ultoa::value#1 +Identical Phi Values (byte*) ultoa::buffer#10 (byte*) ultoa::buffer#5 +Identical Phi Values (byte) ultoa::max_digits#10 (byte) ultoa::max_digits#7 +Identical Phi Values (dword*) ultoa::digit_values#10 (dword*) ultoa::digit_values#8 +Identical Phi Values (dword) ultoa_append::value#5 (dword) ultoa_append::value#0 +Identical Phi Values (dword) ultoa_append::sub#3 (dword) ultoa_append::sub#0 +Identical Phi Values (byte*) ultoa_append::buffer#3 (byte*) ultoa_append::buffer#0 +Identical Phi Values (dword) ultoa_append::sub#1 (dword) ultoa_append::sub#3 +Identical Phi Values (byte*) ultoa_append::buffer#1 (byte*) ultoa_append::buffer#3 +Identical Phi Values (byte*) print_line_cursor#18 (byte*) print_line_cursor#20 +Identical Phi Values (byte*) print_char_cursor#36 (byte*) print_char_cursor#14 +Identical Phi Values (byte*) print_char_cursor#20 (byte*) print_char_cursor#36 +Identical Phi Values (dword) print_dword_decimal::w#1 (dword) print_dword_decimal::w#0 +Identical Phi Values (byte*) print_char_cursor#37 (byte*) print_char_cursor#39 +Identical Phi Values (byte*) print_char_cursor#22 (byte*) print_char_cursor#18 +Identical Phi Values (byte) print_char::ch#1 (byte) print_char::ch#0 +Identical Phi Values (byte*) print_char_cursor#24 (byte*) print_char_cursor#12 +Identical Phi Values (byte*) print_char_cursor#38 (byte*) print_char_cursor#0 +Identical Phi Values (byte*) print_line_cursor#19 (byte*) print_char_cursor#0 +Identical Phi Values (byte*) print_char_cursor#26 (byte*) print_char_cursor#15 +Identical Phi Values (byte*) print_line_cursor#12 (byte*) print_line_cursor#15 +Identical Phi Values (byte*) print_char_cursor#10 (byte*) print_char_cursor#15 +Identical Phi Values (byte*) print_line_cursor#13 (byte*) print_line_cursor#15 +Identical Phi Values (byte*) print_char_cursor#12 (byte*) print_char_cursor#22 +Identical Phi Values (byte*) print_char_cursor#13 (byte*) print_char_cursor#25 +Identical Phi Values (byte*) print_char_cursor#14 (byte*) print_char_cursor#18 +Identical Phi Values (byte*) print_line_cursor#15 (byte*) print_line_cursor#1 +Identical Phi Values (byte*) print_char_cursor#15 (byte*) print_line_cursor#1 +Identical Phi Values (byte*) print_char_cursor#17 (byte*) print_char_cursor#10 +Identical Phi Values (byte*) print_line_cursor#17 (byte*) print_line_cursor#13 +Successful SSA optimization Pass2IdenticalPhiElimination +Simple Condition (bool~) ultoa::$0 [9] if((byte) ultoa::radix#0==(const byte) DECIMAL) goto ultoa::@1 +Simple Condition (bool~) ultoa::$1 [15] if((byte) ultoa::radix#0==(const byte) HEXADECIMAL) goto ultoa::@2 +Simple Condition (bool~) ultoa::$2 [21] if((byte) ultoa::radix#0==(const byte) OCTAL) goto ultoa::@3 +Simple Condition (bool~) ultoa::$3 [27] if((byte) ultoa::radix#0==(const byte) BINARY) goto ultoa::@4 +Simple Condition (bool~) ultoa::$6 [46] if((byte) ultoa::digit#2<(byte~) ultoa::$5) goto ultoa::@19 +Simple Condition (bool~) ultoa_append::$0 [76] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 +Simple Condition (bool~) print_str::$0 [92] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 +Simple Condition (bool~) print_ln::$1 [105] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 +Successful SSA optimization Pass2ConditionalJumpSimplification +Rewriting ! if()-condition to reversed if() [52] (bool~) ultoa::$9 ← ! (bool~) ultoa::$8 +Successful SSA optimization Pass2ConditionalAndOrRewriting +Rewriting || if()-condition to two if()s [51] (bool~) ultoa::$8 ← (byte) ultoa::started#2 || (bool~) ultoa::$7 +Successful SSA optimization Pass2ConditionalAndOrRewriting +Warning! Adding boolean cast to non-boolean condition (byte) ultoa::started#2 +Constant right-side identified [113] (byte[$b]) decimal_digits_long#0 ← { fill( $b, 0) } +Successful SSA optimization Pass2ConstantRValueConsolidation +Identified constant from value list (dword[]) { (dword) $80000000, (dword) $40000000, (dword) $20000000, (dword) $10000000, (dword) $8000000, (dword) $4000000, (dword) $2000000, (dword) $1000000, (dword) $800000, (dword) $400000, (dword) $200000, (dword) $100000, (dword) $80000, (dword) $40000, (dword) $20000, (dword) $10000, (dword) $8000, (dword) $4000, (dword) $2000, (dword) $1000, (dword) $800, (dword) $400, (dword) $200, (dword) $100, (dword) $80, (dword) $40, (dword) $20, (dword) $10, (dword) 8, (dword) 4, (dword) 2 } +Identified constant from value list (dword[]) { (dword) $40000000, (dword) $8000000, (dword) $1000000, (dword) $200000, (dword) $40000, (dword) $8000, (dword) $1000, (dword) $200, (dword) $40, (dword) 8 } +Identified constant from value list (dword[]) { (dword) $3b9aca00, (dword) $5f5e100, (dword) $989680, (dword) $f4240, (dword) $186a0, (dword) $2710, (dword) $3e8, (dword) $64, (dword) $a } +Identified constant from value list (dword[]) { (dword) $10000000, (dword) $1000000, (dword) $100000, (dword) $10000, (dword) $1000, (dword) $100, (dword) $10 } +Successful SSA optimization Pass2ConstantInitializerValueLists +Constant (const byte[]) DIGITS#0 = $0 +Constant (const dword[]) RADIX_BINARY_VALUES_LONG#0 = { $80000000, $40000000, $20000000, $10000000, $8000000, $4000000, $2000000, $1000000, $800000, $400000, $200000, $100000, $80000, $40000, $20000, $10000, $8000, $4000, $2000, $1000, $800, $400, $200, $100, $80, $40, $20, $10, 8, 4, 2 } +Constant (const dword[]) RADIX_OCTAL_VALUES_LONG#0 = { $40000000, $8000000, $1000000, $200000, $40000, $8000, $1000, $200, $40, 8 } +Constant (const dword[]) RADIX_DECIMAL_VALUES_LONG#0 = { $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a } +Constant (const dword[]) RADIX_HEXADECIMAL_VALUES_LONG#0 = { $10000000, $1000000, $100000, $10000, $1000, $100, $10 } +Constant (const byte) ultoa::max_digits#0 = 0 +Constant (const dword*) ultoa::digit_values#0 = (dword*) 0 +Constant (const byte) ultoa::max_digits#1 = $a +Constant (const byte) ultoa::max_digits#2 = 8 +Constant (const byte) ultoa::max_digits#3 = $b +Constant (const byte) ultoa::max_digits#4 = $20 +Constant (const byte) ultoa::started#0 = 0 +Constant (const byte) ultoa::digit#0 = 0 +Constant (const byte) ultoa::started#1 = 1 +Constant (const byte) ultoa_append::digit#0 = 0 +Constant (const byte*) print_char_cursor#0 = (byte*) 1024 +Constant (const byte[$b]) decimal_digits_long#0 = { fill( $b, 0) } +Constant (const byte) ultoa::radix#0 = DECIMAL +Constant (const dword) jesper_id#0 = $1b244 +Constant (const byte[2]) jesper_initials#0 = $1 +Constant (const dword) henry_id#0 = $4466d +Constant (const byte[2]) henry_initials#0 = $2 +Constant (const byte) print_char::ch#0 = ' ' +Successful SSA optimization Pass2ConstantIdentification +Constant (const dword*) ultoa::digit_values#1 = RADIX_DECIMAL_VALUES_LONG#0 +Constant (const dword*) ultoa::digit_values#2 = RADIX_HEXADECIMAL_VALUES_LONG#0 +Constant (const dword*) ultoa::digit_values#3 = RADIX_OCTAL_VALUES_LONG#0 +Constant (const dword*) ultoa::digit_values#4 = RADIX_BINARY_VALUES_LONG#0 +Constant (const byte*) ultoa::buffer#5 = decimal_digits_long#0 +Constant (const byte*) print_str::str#1 = decimal_digits_long#0 +Constant (const dword) print_person::person_id#0 = jesper_id#0 +Constant (const byte[2]) print_person::person_initials#0 = jesper_initials#0 +Constant (const dword) print_person::person_id#1 = henry_id#0 +Constant (const byte[2]) print_person::person_initials#1 = henry_initials#0 +Successful SSA optimization Pass2ConstantIdentification +if() condition always true - replacing block destination [9] if((const byte) ultoa::radix#0==(const byte) DECIMAL) goto ultoa::@1 +if() condition always false - eliminating [15] if((const byte) ultoa::radix#0==(const byte) HEXADECIMAL) goto ultoa::@2 +if() condition always false - eliminating [21] if((const byte) ultoa::radix#0==(const byte) OCTAL) goto ultoa::@3 +if() condition always false - eliminating [27] if((const byte) ultoa::radix#0==(const byte) BINARY) goto ultoa::@4 +Successful SSA optimization Pass2ConstantIfs +Eliminating unused constant (const byte) BINARY +Eliminating unused constant (const byte) OCTAL +Eliminating unused constant (const byte) HEXADECIMAL +Eliminating unused constant (const byte) ultoa::max_digits#0 +Eliminating unused constant (const dword*) ultoa::digit_values#0 +Eliminating unused constant (const byte) ultoa::radix#0 +Successful SSA optimization PassNEliminateUnusedVars +Eliminating unused constant (const byte) DECIMAL +Successful SSA optimization PassNEliminateUnusedVars +Eliminating variable (byte*) ultoa::buffer#0 from unused block ultoa::@12 +Eliminating variable (byte*) ultoa::buffer#1 from unused block ultoa::@12 +Eliminating variable (byte*) ultoa::buffer#2 from unused block ultoa::@12 +Removing unused block ultoa::@9 +Removing PHI-reference to removed block (ultoa::@2) in block ultoa::@8 +Removing PHI-reference to removed block (ultoa::@2) in block ultoa::@8 +Removing unused block ultoa::@2 +Removing unused block ultoa::@10 +Removing PHI-reference to removed block (ultoa::@3) in block ultoa::@8 +Removing PHI-reference to removed block (ultoa::@3) in block ultoa::@8 +Removing unused block ultoa::@3 +Removing unused block ultoa::@11 +Removing PHI-reference to removed block (ultoa::@4) in block ultoa::@8 +Removing PHI-reference to removed block (ultoa::@4) in block ultoa::@8 +Removing unused block ultoa::@4 +Removing unused block ultoa::@12 +Successful SSA optimization Pass2EliminateUnusedBlocks +Adding number conversion cast (unumber) 0 in (bool~) ultoa::$12 ← (number) 0 != (byte) ultoa::started#2 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant integer cast 0 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Identical Phi Values (byte) ultoa::max_digits#7 (const byte) ultoa::max_digits#1 +Identical Phi Values (dword*) ultoa::digit_values#8 (const dword*) ultoa::digit_values#1 +Successful SSA optimization Pass2IdenticalPhiElimination +Simple Condition (bool~) ultoa::$12 [9] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@24 +Simple Condition (bool~) ultoa::$7 [59] if((dword) ultoa::value#2>=(dword) ultoa::digit_value#0) goto ultoa::@24 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [3] (byte~) ultoa::$5 ← (const byte) ultoa::max_digits#1 - (byte) 1 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) ultoa::$5 = ultoa::max_digits#1-1 +Successful SSA optimization Pass2ConstantIdentification +Eliminating unused constant (const byte) ultoa::max_digits#2 +Eliminating unused constant (const byte) ultoa::max_digits#3 +Eliminating unused constant (const byte) ultoa::max_digits#4 +Eliminating unused constant (const dword*) ultoa::digit_values#2 +Eliminating unused constant (const dword*) ultoa::digit_values#3 +Eliminating unused constant (const dword*) ultoa::digit_values#4 +Successful SSA optimization PassNEliminateUnusedVars +Eliminating unused constant (const dword[]) RADIX_BINARY_VALUES_LONG#0 +Eliminating unused constant (const dword[]) RADIX_OCTAL_VALUES_LONG#0 +Eliminating unused constant (const dword[]) RADIX_HEXADECIMAL_VALUES_LONG#0 +Successful SSA optimization PassNEliminateUnusedVars +Successful SSA optimization Pass2LoopHeadConstantIdentification +Alias (byte) ultoa::digit#1 = (byte) ultoa::digit#2 +Alias (dword) ultoa::value#2 = (dword) ultoa::value#6 +Alias (byte) ultoa::started#2 = (byte) ultoa::started#4 +Alias (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#14 +Alias (byte) ultoa::digit#11 = (byte) ultoa::digit#9 +Alias (byte*) ultoa::buffer#24 = (byte*) ultoa::buffer#25 +Alias (byte) ultoa::digit#10 = (byte) ultoa::digit#7 +Alias (dword) ultoa::value#17 = (dword) ultoa::value#19 +Alias (byte) ultoa::started#5 = (byte) ultoa::started#6 +Alias (byte*) ultoa::buffer#23 = (byte*) ultoa::buffer#26 +Successful SSA optimization Pass2AliasElimination +Alias (byte) ultoa::digit#10 = (byte) ultoa::digit#11 +Alias (dword) ultoa::value#17 = (dword) ultoa::value#18 +Alias (byte*) ultoa::buffer#23 = (byte*) ultoa::buffer#24 +Successful SSA optimization Pass2AliasElimination +Alias (byte) ultoa::digit#10 = (byte) ultoa::digit#8 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) ultoa::digit#12 (const byte) ultoa::digit#0 +Identical Phi Values (dword) ultoa::value#20 (dword) ultoa::value#1 +Identical Phi Values (byte) ultoa::started#7 (const byte) ultoa::started#0 +Identical Phi Values (byte*) ultoa::buffer#27 (const byte*) ultoa::buffer#5 +Successful SSA optimization Pass2IdenticalPhiElimination +Removing PHI-reference to removed block (ultoa::@18_1) in block ultoa::@20 +Removing PHI-reference to removed block (ultoa::@18_1) in block ultoa::@20 +if() condition always true - replacing block destination [62] if((const byte) ultoa::digit#0<(const byte) ultoa::$5) goto ultoa::@19 +Successful SSA optimization Pass2ConstantIfs +Successful SSA optimization Pass2LoopHeadConstantIdentification +Alias (byte) ultoa::digit#1 = (byte) ultoa::digit#10 +Alias (dword) ultoa::value#16 = (dword) ultoa::value#17 (dword) ultoa::value#2 +Alias (byte) ultoa::started#2 = (byte) ultoa::started#5 +Alias (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#23 (byte*) ultoa::buffer#22 +Alias (byte) ultoa::digit#14 = (byte) ultoa::digit#16 +Alias (byte*) ultoa::buffer#29 = (byte*) ultoa::buffer#30 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) ultoa::digit#17 (const byte) ultoa::digit#0 +Identical Phi Values (dword) ultoa::value#23 (dword) ultoa::value#1 +Identical Phi Values (byte) ultoa::started#9 (const byte) ultoa::started#0 +Identical Phi Values (byte*) ultoa::buffer#31 (const byte*) ultoa::buffer#5 +Successful SSA optimization Pass2IdenticalPhiElimination +Constant right-side identified [61] (byte~) ultoa::$13 ← (const byte) ultoa::digit#0 * (const byte) SIZEOF_DWORD +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) ultoa::$13 = ultoa::digit#0*SIZEOF_DWORD +Successful SSA optimization Pass2ConstantIdentification +Removing PHI-reference to removed block (ultoa::@19_1) in block ultoa::@24 +Removing PHI-reference to removed block (ultoa::@19_1) in block ultoa::@24 +Removing PHI-reference to removed block (ultoa::@19_1) in block ultoa::@24 +Removing PHI-reference to removed block (ultoa::@19_1) in block ultoa::@24 +if() condition always false - eliminating [63] if((byte) 0!=(const byte) ultoa::started#0) goto ultoa::@24 +Successful SSA optimization Pass2ConstantIfs +Simplifying constant evaluating to zero (const byte) ultoa::digit#0*(const byte) SIZEOF_DWORD in +Successful SSA optimization PassNSimplifyConstantZero +Simplifying expression containing zero ultoa::digit_values#1 in [62] (dword) ultoa::digit_value#4 ← *((const dword*) ultoa::digit_values#1 + (const byte) ultoa::$13) +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant (const byte) ultoa::$13 +Successful SSA optimization PassNEliminateUnusedVars +Rewriting multiplication to use shift [2] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 * (const byte) SIZEOF_DWORD +Successful SSA optimization Pass2MultiplyToShiftRewriting +Inlining constant with var siblings (const byte) ultoa::started#0 +Inlining constant with var siblings (const byte) ultoa::digit#0 +Inlining constant with var siblings (const byte) ultoa::started#1 +Inlining constant with var siblings (const byte*) ultoa::buffer#5 +Inlining constant with var siblings (const byte) ultoa_append::digit#0 +Inlining constant with var siblings (const byte*) print_str::str#1 +Inlining constant with var siblings (const dword) print_person::person_id#0 +Inlining constant with var siblings (const byte[2]) print_person::person_initials#0 +Inlining constant with var siblings (const dword) print_person::person_id#1 +Inlining constant with var siblings (const byte[2]) print_person::person_initials#1 +Inlining constant with var siblings (const byte*) print_char_cursor#0 +Constant inlined print_person::person_initials#1 = (const byte[2]) henry_initials#0 +Constant inlined ultoa::started#1 = (byte) 1 +Constant inlined $0 = (const byte[]) DIGITS#0 +Constant inlined $1 = (const byte[2]) jesper_initials#0 +Constant inlined $2 = (const byte[2]) henry_initials#0 +Constant inlined print_char_cursor#0 = (byte*) 1024 +Constant inlined ultoa::buffer#5 = (const byte[$b]) decimal_digits_long#0 +Constant inlined print_person::person_id#1 = (const dword) henry_id#0 +Constant inlined print_person::person_id#0 = (const dword) jesper_id#0 +Constant inlined ultoa::$5 = (const byte) ultoa::max_digits#1-(byte) 1 +Constant inlined ultoa::started#0 = (byte) 0 +Constant inlined ultoa::digit#0 = (byte) 0 +Constant inlined ultoa_append::digit#0 = (byte) 0 +Constant inlined ultoa::digit_values#1 = (const dword[]) RADIX_DECIMAL_VALUES_LONG#0 +Constant inlined print_str::str#1 = (const byte[$b]) decimal_digits_long#0 +Constant inlined print_person::person_initials#0 = (const byte[2]) jesper_initials#0 +Successful SSA optimization Pass2ConstantInlining +Eliminating unused constant (const byte) SIZEOF_DWORD +Successful SSA optimization PassNEliminateUnusedVars +Added new block during phi lifting ultoa::@28(between ultoa::@27 and ultoa::@21) +Added new block during phi lifting ultoa::@29(between ultoa::@19 and ultoa::@24) +Added new block during phi lifting ultoa::@30(between ultoa::@27 and ultoa::@24) +Added new block during phi lifting print_ln::@3(between print_ln::@1 and print_ln::@1) +Added new block during phi lifting ultoa::@31(between ultoa::@19 and ultoa::@27) +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @8 +Adding NOP phi() at start of @10 +Adding NOP phi() at start of @12 +Adding NOP phi() at start of @26 +Adding NOP phi() at start of @36 +Adding NOP phi() at start of @38 +Adding NOP phi() at start of @39 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@2 +Adding NOP phi() at start of print_person::@1 +Adding NOP phi() at start of print_person::@3 +Adding NOP phi() at start of print_person::@4 +Adding NOP phi() at start of print_ln::@2 +Adding NOP phi() at start of print_dword_decimal::@2 +Adding NOP phi() at start of ultoa +Adding NOP phi() at start of ultoa::@1 +Adding NOP phi() at start of ultoa::@8 +Adding NOP phi() at start of ultoa::@18_1 +CALL GRAPH +Calls in [] to main:7 +Calls in [main] to print_person:11 print_person:14 +Calls in [print_person] to print_dword_decimal:19 print_char:21 print_str:25 print_ln:27 +Calls in [print_dword_decimal] to ultoa:52 print_str:54 +Calls in [ultoa] to ultoa_append:94 + +Created 24 initial phi equivalence classes +Not coalescing [12] print_char_cursor#49 ← print_line_cursor#1 +Coalesced [13] print_line_cursor#29 ← print_line_cursor#1 +Coalesced [23] print_str::str#6 ← print_str::str#2 +Coalesced [24] print_char_cursor#46 ← print_char_cursor#25 +Coalesced [30] print_line_cursor#27 ← print_line_cursor#20 +Coalesced (already) [36] print_line_cursor#28 ← print_line_cursor#1 +Coalesced [38] print_str::str#7 ← print_str::str#5 +Coalesced [39] print_char_cursor#47 ← print_char_cursor#41 +Coalesced [46] print_str::str#8 ← print_str::str#0 +Coalesced [47] print_char_cursor#48 ← print_char_cursor#1 +Coalesced [53] print_char_cursor#45 ← print_char_cursor#39 +Coalesced [62] ultoa::value#29 ← ultoa::value#1 +Coalesced [63] ultoa::digit_value#8 ← ultoa::digit_value#4 +Coalesced [66] ultoa::value#24 ← ultoa::value#21 +Coalesced [67] ultoa::started#10 ← ultoa::started#8 +Coalesced [68] ultoa::buffer#32 ← ultoa::buffer#28 +Coalesced [69] ultoa::digit#19 ← ultoa::digit#15 +Coalesced [81] ultoa::digit#22 ← ultoa::digit#1 +Coalesced (already) [82] ultoa::value#28 ← ultoa::value#16 +Coalesced (already) [83] ultoa::started#11 ← ultoa::started#2 +Coalesced (already) [84] ultoa::buffer#36 ← ultoa::buffer#11 +Coalesced [85] ultoa::digit_value#7 ← ultoa::digit_value#0 +Coalesced [86] ultoa::digit#20 ← ultoa::digit#1 +Coalesced [87] ultoa::value#26 ← ultoa::value#16 +Coalesced [88] ultoa::buffer#34 ← ultoa::buffer#11 +Coalesced [89] ultoa::digit_value#5 ← ultoa::digit_value#0 +Coalesced [98] ultoa::value#25 ← ultoa::value#0 +Coalesced [99] ultoa::buffer#33 ← ultoa::buffer#4 +Coalesced (already) [100] ultoa::digit#18 ← ultoa::digit#14 +Coalesced (already) [101] ultoa::digit#21 ← ultoa::digit#15 +Coalesced (already) [102] ultoa::value#27 ← ultoa::value#21 +Coalesced (already) [103] ultoa::buffer#35 ← ultoa::buffer#28 +Coalesced (already) [104] ultoa::digit_value#6 ← ultoa::digit_value#3 +Coalesced [105] ultoa_append::value#6 ← ultoa_append::value#0 +Coalesced [112] ultoa_append::value#7 ← ultoa_append::value#1 +Coalesced [113] ultoa_append::digit#5 ← ultoa_append::digit#1 +Coalesced down to 12 phi equivalence classes +Culled Empty Block (label) @8 +Culled Empty Block (label) @10 +Culled Empty Block (label) @12 +Culled Empty Block (label) @26 +Culled Empty Block (label) @36 +Culled Empty Block (label) @39 +Culled Empty Block (label) main::@2 +Culled Empty Block (label) print_person::@4 +Culled Empty Block (label) print_ln::@2 +Culled Empty Block (label) print_ln::@3 +Culled Empty Block (label) print_dword_decimal::@2 +Culled Empty Block (label) ultoa::@1 +Culled Empty Block (label) ultoa::@8 +Culled Empty Block (label) ultoa::@18_1 +Culled Empty Block (label) ultoa::@28 +Culled Empty Block (label) ultoa::@31 +Culled Empty Block (label) ultoa::@29 +Culled Empty Block (label) ultoa::@30 +Renumbering block @38 to @1 +Renumbering block ultoa::@18 to ultoa::@1 +Renumbering block ultoa::@19 to ultoa::@2 +Renumbering block ultoa::@20 to ultoa::@3 +Renumbering block ultoa::@21 to ultoa::@4 +Renumbering block ultoa::@24 to ultoa::@5 +Renumbering block ultoa::@26 to ultoa::@6 +Renumbering block ultoa::@27 to ultoa::@7 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of print_person::@1 +Adding NOP phi() at start of print_person::@3 +Adding NOP phi() at start of print_ln +Adding NOP phi() at start of print_dword_decimal::@1 +Adding NOP phi() at start of ultoa +Adding NOP phi() at start of ultoa_append + +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() +main: scope:[main] from @1 + [4] phi() + [5] call print_person + to:main::@1 +main::@1: scope:[main] from main + [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 + [7] call print_person + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return +print_person: scope:[print_person] from main main::@1 + [9] (byte*) print_line_cursor#20 ← phi( main/(byte*) 1024 main::@1/(byte*) print_line_cursor#1 ) + [9] (byte[2]) print_person::person_initials#2 ← phi( main/(const byte[2]) jesper_initials#0 main::@1/(const byte[2]) henry_initials#0 ) + [9] (byte*) print_char_cursor#39 ← phi( main/(byte*) 1024 main::@1/(byte*~) print_char_cursor#49 ) + [9] (dword) print_person::person_id#2 ← phi( main/(const dword) jesper_id#0 main::@1/(const dword) henry_id#0 ) + [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 + [11] call print_dword_decimal + to:print_person::@1 +print_person::@1: scope:[print_person] from print_person + [12] phi() + [13] call print_char + to:print_person::@2 +print_person::@2: scope:[print_person] from print_person::@1 + [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 + [15] call print_str + to:print_person::@3 +print_person::@3: scope:[print_person] from print_person::@2 + [16] phi() + [17] call print_ln + to:print_person::@return +print_person::@return: scope:[print_person] from print_person::@3 + [18] return + to:@return +print_ln: scope:[print_ln] from print_person::@3 + [19] phi() + to:print_ln::@1 +print_ln::@1: scope:[print_ln] from print_ln print_ln::@1 + [20] (byte*) print_line_cursor#9 ← phi( print_ln/(byte*) print_line_cursor#20 print_ln::@1/(byte*) print_line_cursor#1 ) + [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 + [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 + to:print_ln::@return +print_ln::@return: scope:[print_ln] from print_ln::@1 + [23] return + to:@return +print_str: scope:[print_str] from print_dword_decimal::@1 print_person::@2 + [24] (byte*) print_char_cursor#41 ← phi( print_dword_decimal::@1/(byte*) print_char_cursor#39 print_person::@2/(byte*) print_char_cursor#25 ) + [24] (byte*) print_str::str#5 ← phi( print_dword_decimal::@1/(const byte[$b]) decimal_digits_long#0 print_person::@2/(byte*) print_str::str#2 ) + to:print_str::@1 +print_str::@1: scope:[print_str] from print_str print_str::@2 + [25] (byte*) print_char_cursor#18 ← phi( print_str/(byte*) print_char_cursor#41 print_str::@2/(byte*) print_char_cursor#1 ) + [25] (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 ) + [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 + to:print_str::@return +print_str::@return: scope:[print_str] from print_str::@1 + [27] return + to:@return +print_str::@2: scope:[print_str] from print_str::@1 + [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) + [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 + [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 + to:print_str::@1 +print_char: scope:[print_char] from print_person::@1 + [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 + [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 + to:print_char::@return +print_char::@return: scope:[print_char] from print_char + [33] return + to:@return +print_dword_decimal: scope:[print_dword_decimal] from print_person + [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 + [35] call ultoa + to:print_dword_decimal::@1 +print_dword_decimal::@1: scope:[print_dword_decimal] from print_dword_decimal + [36] phi() + [37] call print_str + to:print_dword_decimal::@return +print_dword_decimal::@return: scope:[print_dword_decimal] from print_dword_decimal::@1 + [38] return + to:@return +ultoa: scope:[ultoa] from print_dword_decimal + [39] phi() + to:ultoa::@19_1 +ultoa::@19_1: scope:[ultoa] from ultoa + [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) + to:ultoa::@7 +ultoa::@7: scope:[ultoa] from ultoa::@19_1 ultoa::@2 + [41] (dword) ultoa::digit_value#3 ← phi( ultoa::@2/(dword) ultoa::digit_value#0 ultoa::@19_1/(dword) ultoa::digit_value#4 ) + [41] (byte*) ultoa::buffer#28 ← phi( ultoa::@2/(byte*) ultoa::buffer#11 ultoa::@19_1/(const byte[$b]) decimal_digits_long#0 ) + [41] (byte) ultoa::started#8 ← phi( ultoa::@2/(byte) ultoa::started#2 ultoa::@19_1/(byte) 0 ) + [41] (dword) ultoa::value#21 ← phi( ultoa::@2/(dword) ultoa::value#16 ultoa::@19_1/(dword) ultoa::value#1 ) + [41] (byte) ultoa::digit#15 ← phi( ultoa::@2/(byte) ultoa::digit#1 ultoa::@19_1/(byte) 0 ) + [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 + to:ultoa::@4 +ultoa::@4: scope:[ultoa] from ultoa::@6 ultoa::@7 + [43] (byte) ultoa::digit#13 ← phi( ultoa::@6/(byte) ultoa::digit#14 ultoa::@7/(byte) ultoa::digit#15 ) + [43] (byte*) ultoa::buffer#11 ← phi( ultoa::@7/(byte*) ultoa::buffer#28 ultoa::@6/(byte*) ultoa::buffer#4 ) + [43] (byte) ultoa::started#2 ← phi( ultoa::@7/(byte) ultoa::started#8 ultoa::@6/(byte) 1 ) + [43] (dword) ultoa::value#16 ← phi( ultoa::@7/(dword) ultoa::value#21 ultoa::@6/(dword) ultoa::value#0 ) + [44] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#13 + to:ultoa::@1 +ultoa::@1: scope:[ultoa] from ultoa::@4 + [45] if((byte) ultoa::digit#1<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 + to:ultoa::@3 +ultoa::@3: scope:[ultoa] from ultoa::@1 + [46] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#16 + [47] *((byte*) ultoa::buffer#11) ← *((const byte[]) DIGITS#0 + (byte~) ultoa::$4) + [48] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 + [49] *((byte*) ultoa::buffer#3) ← (byte) 0 + to:ultoa::@return +ultoa::@return: scope:[ultoa] from ultoa::@3 + [50] return + to:@return +ultoa::@2: scope:[ultoa] from ultoa::@1 + [51] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 << (byte) 2 + [52] (dword) ultoa::digit_value#0 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0 + (byte~) ultoa::$11) + [53] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 + to:ultoa::@7 +ultoa::@5: scope:[ultoa] from ultoa::@2 ultoa::@7 + [54] (dword) ultoa::digit_value#2 ← phi( ultoa::@2/(dword) ultoa::digit_value#0 ultoa::@7/(dword) ultoa::digit_value#3 ) + [54] (byte*) ultoa::buffer#29 ← phi( ultoa::@2/(byte*) ultoa::buffer#11 ultoa::@7/(byte*) ultoa::buffer#28 ) + [54] (dword) ultoa::value#22 ← phi( ultoa::@2/(dword) ultoa::value#16 ultoa::@7/(dword) ultoa::value#21 ) + [54] (byte) ultoa::digit#14 ← phi( ultoa::@2/(byte) ultoa::digit#1 ultoa::@7/(byte) ultoa::digit#15 ) + [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 + [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 + [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 + [58] call ultoa_append + [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 + to:ultoa::@6 +ultoa::@6: scope:[ultoa] from ultoa::@5 + [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 + [61] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#29 + to:ultoa::@4 +ultoa_append: scope:[ultoa_append] from ultoa::@5 + [62] phi() + to:ultoa_append::@1 +ultoa_append::@1: scope:[ultoa_append] from ultoa_append ultoa_append::@2 + [63] (byte) ultoa_append::digit#2 ← phi( ultoa_append/(byte) 0 ultoa_append::@2/(byte) ultoa_append::digit#1 ) + [63] (dword) ultoa_append::value#2 ← phi( ultoa_append/(dword) ultoa_append::value#0 ultoa_append::@2/(dword) ultoa_append::value#1 ) + [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 + to:ultoa_append::@3 +ultoa_append::@3: scope:[ultoa_append] from ultoa_append::@1 + [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) + to:ultoa_append::@return +ultoa_append::@return: scope:[ultoa_append] from ultoa_append::@3 + [66] return + to:@return +ultoa_append::@2: scope:[ultoa_append] from ultoa_append::@1 + [67] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 + [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 + to:ultoa_append::@1 + + +VARIABLE REGISTER WEIGHTS +(byte[]) DIGITS +(dword) Person::id +(byte[2]) Person::initials +(dword[]) RADIX_BINARY_VALUES_LONG +(dword[]) RADIX_DECIMAL_VALUES_LONG +(dword[]) RADIX_HEXADECIMAL_VALUES_LONG +(dword[]) RADIX_OCTAL_VALUES_LONG +(byte[$b]) decimal_digits_long +(dword) henry_id +(byte[2]) henry_initials +(dword) jesper_id +(byte[2]) jesper_initials +(void()) main() +(void()) print_char((byte) print_char::ch) +(byte) print_char::ch +(byte*) print_char_cursor +(byte*) print_char_cursor#1 11.0 +(byte*) print_char_cursor#18 3.333333333333333 +(byte*) print_char_cursor#25 1.0 +(byte*) print_char_cursor#39 0.8 +(byte*) print_char_cursor#41 6.0 +(byte*~) print_char_cursor#49 4.0 +(void()) print_dword_decimal((dword) print_dword_decimal::w) +(dword) print_dword_decimal::w +(dword) print_dword_decimal::w#0 4.0 +(byte*) print_line_cursor +(byte*) print_line_cursor#1 5.285714285714286 +(byte*) print_line_cursor#20 0.4444444444444444 +(byte*) print_line_cursor#9 24.0 +(void()) print_ln() +(void()) print_person((dword) print_person::person_id , (byte[2]) print_person::person_initials) +(struct Person) print_person::person +(dword) print_person::person_id +(dword) print_person::person_id#2 2.0 +(byte[2]) print_person::person_initials +(byte[2]) print_person::person_initials#2 0.4 +(byte*) print_screen +(void()) print_str((byte*) print_str::str) +(byte*) print_str::str +(byte*) print_str::str#0 22.0 +(byte*) print_str::str#2 4.0 +(byte*) print_str::str#3 11.5 +(byte*) print_str::str#5 4.0 +(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) +(byte~) ultoa::$11 22.0 +(byte~) ultoa::$4 4.0 +(byte*) ultoa::buffer +(byte*) ultoa::buffer#11 6.0 +(byte*) ultoa::buffer#28 16.5 +(byte*) ultoa::buffer#29 6.285714285714286 +(byte*) ultoa::buffer#3 4.0 +(byte*) ultoa::buffer#4 22.0 +(byte) ultoa::digit +(byte) ultoa::digit#1 11.0 +(byte) ultoa::digit#13 33.0 +(byte) ultoa::digit#14 4.125 +(byte) ultoa::digit#15 16.5 +(dword) ultoa::digit_value +(dword) ultoa::digit_value#0 16.5 +(dword) ultoa::digit_value#2 11.0 +(dword) ultoa::digit_value#3 17.5 +(dword) ultoa::digit_value#4 4.0 +(dword*) ultoa::digit_values +(byte) ultoa::max_digits +(byte) ultoa::radix +(byte) ultoa::started +(byte) ultoa::started#2 5.5 +(byte) ultoa::started#8 11.0 +(dword) ultoa::value +(dword) ultoa::value#0 11.0 +(dword) ultoa::value#1 1.3333333333333333 +(dword) ultoa::value#16 7.333333333333333 +(dword) ultoa::value#21 23.0 +(dword) ultoa::value#22 16.5 +(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) +(byte*) ultoa_append::buffer +(byte*) ultoa_append::buffer#0 1.625 +(byte) ultoa_append::digit +(byte) ultoa_append::digit#1 101.0 +(byte) ultoa_append::digit#2 102.0 +(dword) ultoa_append::return +(dword) ultoa_append::return#0 22.0 +(dword) ultoa_append::sub +(dword) ultoa_append::sub#0 35.5 +(dword) ultoa_append::value +(dword) ultoa_append::value#0 4.333333333333333 +(dword) ultoa_append::value#1 202.0 +(dword) ultoa_append::value#2 52.66666666666666 + +Initial phi equivalence classes +[ print_person::person_id#2 ] +[ print_person::person_initials#2 ] +[ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] +[ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +[ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +[ ultoa::started#8 ultoa::started#2 ] +[ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +[ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] +[ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] +[ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] +[ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] +[ ultoa_append::digit#2 ultoa_append::digit#1 ] +Added variable print_dword_decimal::w#0 to zero page equivalence class [ print_dword_decimal::w#0 ] +Added variable ultoa::$4 to zero page equivalence class [ ultoa::$4 ] +Added variable ultoa::buffer#3 to zero page equivalence class [ ultoa::buffer#3 ] +Added variable ultoa::$11 to zero page equivalence class [ ultoa::$11 ] +Added variable ultoa_append::buffer#0 to zero page equivalence class [ ultoa_append::buffer#0 ] +Added variable ultoa_append::sub#0 to zero page equivalence class [ ultoa_append::sub#0 ] +Added variable ultoa_append::return#0 to zero page equivalence class [ ultoa_append::return#0 ] +Complete equivalence classes +[ print_person::person_id#2 ] +[ print_person::person_initials#2 ] +[ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] +[ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +[ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +[ ultoa::started#8 ultoa::started#2 ] +[ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +[ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] +[ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] +[ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] +[ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] +[ ultoa_append::digit#2 ultoa_append::digit#1 ] +[ print_dword_decimal::w#0 ] +[ ultoa::$4 ] +[ ultoa::buffer#3 ] +[ ultoa::$11 ] +[ ultoa_append::buffer#0 ] +[ ultoa_append::sub#0 ] +[ ultoa_append::return#0 ] +Allocated zp ZP_DWORD:2 [ print_person::person_id#2 ] +Allocated zp ZP_WORD:6 [ print_person::person_initials#2 ] +Allocated zp ZP_WORD:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] +Allocated zp ZP_WORD:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +Allocated zp ZP_WORD:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +Allocated zp ZP_BYTE:14 [ ultoa::started#8 ultoa::started#2 ] +Allocated zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +Allocated zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] +Allocated zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] +Allocated zp ZP_DWORD:22 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] +Allocated zp ZP_DWORD:26 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] +Allocated zp ZP_BYTE:30 [ ultoa_append::digit#2 ultoa_append::digit#1 ] +Allocated zp ZP_DWORD:31 [ print_dword_decimal::w#0 ] +Allocated zp ZP_BYTE:35 [ ultoa::$4 ] +Allocated zp ZP_WORD:36 [ ultoa::buffer#3 ] +Allocated zp ZP_BYTE:38 [ ultoa::$11 ] +Allocated zp ZP_WORD:39 [ ultoa_append::buffer#0 ] +Allocated zp ZP_DWORD:41 [ ultoa_append::sub#0 ] +Allocated zp ZP_DWORD:45 [ ultoa_append::return#0 ] + +INITIAL ASM +Target platform is c64basic + // File Comments +// Example of a struct containing an array + // Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" + // Global Constants & labels + .const jesper_id = $1b244 + .const henry_id = $4466d + .label print_char_cursor = $c + .label print_line_cursor = 8 + // @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: { + // [5] call print_person + // [9] phi from main to print_person [phi:main->print_person] + print_person_from_main: + // [9] phi (byte*) print_line_cursor#20 = (byte*) 1024 [phi:main->print_person#0] -- pbuz1=pbuc1 + lda #<$400 + sta.z print_line_cursor + lda #>$400 + sta.z print_line_cursor+1 + // [9] phi (byte[2]) print_person::person_initials#2 = (const byte[2]) jesper_initials#0 [phi:main->print_person#1] -- pbuz1=pbuc1 + lda #jesper_initials + sta.z print_person.person_initials+1 + // [9] phi (byte*) print_char_cursor#39 = (byte*) 1024 [phi:main->print_person#2] -- pbuz1=pbuc1 + lda #<$400 + sta.z print_char_cursor + lda #>$400 + sta.z print_char_cursor+1 + // [9] phi (dword) print_person::person_id#2 = (const dword) jesper_id#0 [phi:main->print_person#3] -- vduz1=vduc1 + lda #jesper_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>jesper_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + jmp b1 + // main::@1 + b1: + // [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 + lda.z print_line_cursor + sta.z print_char_cursor + lda.z print_line_cursor+1 + sta.z print_char_cursor+1 + // [7] call print_person + // [9] phi from main::@1 to print_person [phi:main::@1->print_person] + print_person_from_b1: + // [9] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#1 [phi:main::@1->print_person#0] -- register_copy + // [9] phi (byte[2]) print_person::person_initials#2 = (const byte[2]) henry_initials#0 [phi:main::@1->print_person#1] -- pbuz1=pbuc1 + lda #henry_initials + sta.z print_person.person_initials+1 + // [9] phi (byte*) print_char_cursor#39 = (byte*~) print_char_cursor#49 [phi:main::@1->print_person#2] -- register_copy + // [9] phi (dword) print_person::person_id#2 = (const dword) henry_id#0 [phi:main::@1->print_person#3] -- vduz1=vduc1 + lda #henry_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>henry_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + jmp breturn + // main::@return + breturn: + // [8] return + rts +} + // print_person +// print_person(dword zeropage(2) person_id, byte[2] zeropage(6) person_initials) +print_person: { + .label person_id = 2 + .label person_initials = 6 + // [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 -- vduz1=vduz2 + lda.z person_id + sta.z print_dword_decimal.w + lda.z person_id+1 + sta.z print_dword_decimal.w+1 + lda.z person_id+2 + sta.z print_dword_decimal.w+2 + lda.z person_id+3 + sta.z print_dword_decimal.w+3 + // [11] call print_dword_decimal + jsr print_dword_decimal + // [12] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] + b1_from_print_person: + jmp b1 + // print_person::@1 + b1: + // [13] call print_char + jsr print_char + jmp b2 + // print_person::@2 + b2: + // [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 -- pbuz1=pbuz2 + lda.z person_initials + sta.z print_str.str + lda.z person_initials+1 + sta.z print_str.str+1 + // [15] call print_str + // [24] phi from print_person::@2 to print_str [phi:print_person::@2->print_str] + print_str_from_b2: + // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#25 [phi:print_person::@2->print_str#0] -- register_copy + // [24] phi (byte*) print_str::str#5 = (byte*) print_str::str#2 [phi:print_person::@2->print_str#1] -- register_copy + jsr print_str + // [16] phi from print_person::@2 to print_person::@3 [phi:print_person::@2->print_person::@3] + b3_from_b2: + jmp b3 + // print_person::@3 + b3: + // [17] call print_ln + // [19] phi from print_person::@3 to print_ln [phi:print_person::@3->print_ln] + print_ln_from_b3: + jsr print_ln + jmp breturn + // print_person::@return + breturn: + // [18] return + rts +} + // print_ln +// Print a newline +print_ln: { + // [20] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] + b1_from_print_ln: + b1_from_b1: + // [20] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#20 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy + jmp b1 + // print_ln::@1 + b1: + // [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z print_line_cursor + sta.z print_line_cursor + bcc !+ + inc.z print_line_cursor+1 + !: + // [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 + lda.z print_line_cursor+1 + cmp.z print_char_cursor+1 + bcc b1_from_b1 + bne !+ + lda.z print_line_cursor + cmp.z print_char_cursor + bcc b1_from_b1 + !: + jmp breturn + // print_ln::@return + breturn: + // [23] return + rts +} + // print_str +// Print a zero-terminated string +// print_str(byte* zeropage($a) str) +print_str: { + .label str = $a + // [25] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] + b1_from_print_str: + b1_from_b2: + // [25] phi (byte*) print_char_cursor#18 = (byte*) print_char_cursor#41 [phi:print_str/print_str::@2->print_str::@1#0] -- register_copy + // [25] phi (byte*) print_str::str#3 = (byte*) print_str::str#5 [phi:print_str/print_str::@2->print_str::@1#1] -- register_copy + jmp b1 + // print_str::@1 + b1: + // [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 + ldy #0 + lda (str),y + cmp #0 + bne b2 + jmp breturn + // print_str::@return + breturn: + // [27] return + rts + // print_str::@2 + b2: + // [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (str),y + ldy #0 + sta (print_char_cursor),y + // [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + // [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 -- pbuz1=_inc_pbuz1 + inc.z str + bne !+ + inc.z str+1 + !: + jmp b1_from_b2 +} + // print_char +// Print a single char +print_char: { + .const ch = ' ' + // [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 -- _deref_pbuz1=vbuc1 + lda #ch + ldy #0 + sta (print_char_cursor),y + // [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + jmp breturn + // print_char::@return + breturn: + // [33] return + rts +} + // print_dword_decimal +// Print a dword as DECIMAL +// print_dword_decimal(dword zeropage($1f) w) +print_dword_decimal: { + .label w = $1f + // [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 -- vduz1=vduz2 + lda.z w + sta.z ultoa.value + lda.z w+1 + sta.z ultoa.value+1 + lda.z w+2 + sta.z ultoa.value+2 + lda.z w+3 + sta.z ultoa.value+3 + // [35] call ultoa + // [39] phi from print_dword_decimal to ultoa [phi:print_dword_decimal->ultoa] + ultoa_from_print_dword_decimal: + jsr ultoa + // [36] phi from print_dword_decimal to print_dword_decimal::@1 [phi:print_dword_decimal->print_dword_decimal::@1] + b1_from_print_dword_decimal: + jmp b1 + // print_dword_decimal::@1 + b1: + // [37] call print_str + // [24] phi from print_dword_decimal::@1 to print_str [phi:print_dword_decimal::@1->print_str] + print_str_from_b1: + // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#39 [phi:print_dword_decimal::@1->print_str#0] -- register_copy + // [24] phi (byte*) print_str::str#5 = (const byte[$b]) decimal_digits_long#0 [phi:print_dword_decimal::@1->print_str#1] -- pbuz1=pbuc1 + lda #decimal_digits_long + sta.z print_str.str+1 + jsr print_str + jmp breturn + // print_dword_decimal::@return + breturn: + // [38] return + rts +} + // ultoa +// Converts unsigned number value to a string representing it in RADIX format. +// If the leading digits are zero they are not included in the string. +// - value : The number to be converted to RADIX +// - buffer : receives the string representing the number and zero-termination. +// - radix : The radix to convert the number to (from the enum RADIX) +// ultoa(dword zeropage($10) value, byte* zeropage($24) buffer) +ultoa: { + .const max_digits = $a + .label _4 = $23 + .label _11 = $26 + .label digit_value = $16 + .label buffer = $24 + .label digit = $f + .label value = $10 + .label buffer_4 = $14 + .label started = $e + .label buffer_11 = $14 + .label buffer_28 = $14 + .label buffer_29 = $14 + jmp b19_1 + // ultoa::@19_1 + b19_1: + // [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) -- vduz1=_deref_pduc1 + lda RADIX_DECIMAL_VALUES_LONG + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1 + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2 + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3 + sta.z digit_value+3 + // [41] phi from ultoa::@19_1 to ultoa::@7 [phi:ultoa::@19_1->ultoa::@7] + b7_from_b19_1: + // [41] phi (dword) ultoa::digit_value#3 = (dword) ultoa::digit_value#4 [phi:ultoa::@19_1->ultoa::@7#0] -- register_copy + // [41] phi (byte*) ultoa::buffer#28 = (const byte[$b]) decimal_digits_long#0 [phi:ultoa::@19_1->ultoa::@7#1] -- pbuz1=pbuc1 + lda #decimal_digits_long + sta.z buffer_28+1 + // [41] phi (byte) ultoa::started#8 = (byte) 0 [phi:ultoa::@19_1->ultoa::@7#2] -- vbuz1=vbuc1 + lda #0 + sta.z started + // [41] phi (dword) ultoa::value#21 = (dword) ultoa::value#1 [phi:ultoa::@19_1->ultoa::@7#3] -- register_copy + // [41] phi (byte) ultoa::digit#15 = (byte) 0 [phi:ultoa::@19_1->ultoa::@7#4] -- vbuz1=vbuc1 + lda #0 + sta.z digit + jmp b7 + // ultoa::@7 + b7: + // [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 -- vduz1_ge_vduz2_then_la1 + lda.z value+3 + cmp.z digit_value+3 + bcc !+ + bne b5_from_b7 + lda.z value+2 + cmp.z digit_value+2 + bcc !+ + bne b5_from_b7 + lda.z value+1 + cmp.z digit_value+1 + bcc !+ + bne b5_from_b7 + lda.z value + cmp.z digit_value + bcs b5_from_b7 + !: + // [43] phi from ultoa::@7 to ultoa::@4 [phi:ultoa::@7->ultoa::@4] + b4_from_b7: + // [43] phi (byte) ultoa::digit#13 = (byte) ultoa::digit#15 [phi:ultoa::@7->ultoa::@4#0] -- register_copy + // [43] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#28 [phi:ultoa::@7->ultoa::@4#1] -- register_copy + // [43] phi (byte) ultoa::started#2 = (byte) ultoa::started#8 [phi:ultoa::@7->ultoa::@4#2] -- register_copy + // [43] phi (dword) ultoa::value#16 = (dword) ultoa::value#21 [phi:ultoa::@7->ultoa::@4#3] -- register_copy + jmp b4 + // ultoa::@4 + b4: + // [44] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#13 -- vbuz1=_inc_vbuz1 + inc.z digit + jmp b1 + // ultoa::@1 + b1: + // [45] if((byte) ultoa::digit#1<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z digit + cmp #max_digits-1 + bcc b2 + jmp b3 + // ultoa::@3 + b3: + // [46] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#16 -- vbuz1=_byte_vduz2 + lda.z value + sta.z _4 + // [47] *((byte*) ultoa::buffer#11) ← *((const byte[]) DIGITS#0 + (byte~) ultoa::$4) -- _deref_pbuz1=pbuc1_derefidx_vbuz2 + ldy.z _4 + lda DIGITS,y + ldy #0 + sta (buffer_11),y + // [48] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz2 + lda.z buffer_11 + clc + adc #1 + sta.z buffer + lda.z buffer_11+1 + adc #0 + sta.z buffer+1 + // [49] *((byte*) ultoa::buffer#3) ← (byte) 0 -- _deref_pbuz1=vbuc1 + lda #0 + ldy #0 + sta (buffer),y + jmp breturn + // ultoa::@return + breturn: + // [50] return + rts + // ultoa::@2 + b2: + // [51] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 << (byte) 2 -- vbuz1=vbuz2_rol_2 + lda.z digit + asl + asl + sta.z _11 + // [52] (dword) ultoa::digit_value#0 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0 + (byte~) ultoa::$11) -- vduz1=pduc1_derefidx_vbuz2 + ldy.z _11 + lda RADIX_DECIMAL_VALUES_LONG,y + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1,y + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2,y + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3,y + sta.z digit_value+3 + // [53] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 -- vbuc1_neq_vbuz1_then_la1 + lda #0 + cmp.z started + bne b5_from_b2 + // [41] phi from ultoa::@2 to ultoa::@7 [phi:ultoa::@2->ultoa::@7] + b7_from_b2: + // [41] phi (dword) ultoa::digit_value#3 = (dword) ultoa::digit_value#0 [phi:ultoa::@2->ultoa::@7#0] -- register_copy + // [41] phi (byte*) ultoa::buffer#28 = (byte*) ultoa::buffer#11 [phi:ultoa::@2->ultoa::@7#1] -- register_copy + // [41] phi (byte) ultoa::started#8 = (byte) ultoa::started#2 [phi:ultoa::@2->ultoa::@7#2] -- register_copy + // [41] phi (dword) ultoa::value#21 = (dword) ultoa::value#16 [phi:ultoa::@2->ultoa::@7#3] -- register_copy + // [41] phi (byte) ultoa::digit#15 = (byte) ultoa::digit#1 [phi:ultoa::@2->ultoa::@7#4] -- register_copy + jmp b7 + // [54] phi from ultoa::@2 ultoa::@7 to ultoa::@5 [phi:ultoa::@2/ultoa::@7->ultoa::@5] + b5_from_b2: + b5_from_b7: + // [54] phi (dword) ultoa::digit_value#2 = (dword) ultoa::digit_value#0 [phi:ultoa::@2/ultoa::@7->ultoa::@5#0] -- register_copy + // [54] phi (byte*) ultoa::buffer#29 = (byte*) ultoa::buffer#11 [phi:ultoa::@2/ultoa::@7->ultoa::@5#1] -- register_copy + // [54] phi (dword) ultoa::value#22 = (dword) ultoa::value#16 [phi:ultoa::@2/ultoa::@7->ultoa::@5#2] -- register_copy + // [54] phi (byte) ultoa::digit#14 = (byte) ultoa::digit#1 [phi:ultoa::@2/ultoa::@7->ultoa::@5#3] -- register_copy + jmp b5 + // ultoa::@5 + b5: + // [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 -- pbuz1=pbuz2 + lda.z buffer_29 + sta.z ultoa_append.buffer + lda.z buffer_29+1 + sta.z ultoa_append.buffer+1 + // [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 -- vduz1=vduz2 + lda.z value + sta.z ultoa_append.value + lda.z value+1 + sta.z ultoa_append.value+1 + lda.z value+2 + sta.z ultoa_append.value+2 + lda.z value+3 + sta.z ultoa_append.value+3 + // [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 -- vduz1=vduz2 + lda.z digit_value + sta.z ultoa_append.sub + lda.z digit_value+1 + sta.z ultoa_append.sub+1 + lda.z digit_value+2 + sta.z ultoa_append.sub+2 + lda.z digit_value+3 + sta.z ultoa_append.sub+3 + // [58] call ultoa_append + // [62] phi from ultoa::@5 to ultoa_append [phi:ultoa::@5->ultoa_append] + ultoa_append_from_b5: + jsr ultoa_append + // [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 -- vduz1=vduz2 + lda.z ultoa_append.value + sta.z ultoa_append.return + lda.z ultoa_append.value+1 + sta.z ultoa_append.return+1 + lda.z ultoa_append.value+2 + sta.z ultoa_append.return+2 + lda.z ultoa_append.value+3 + sta.z ultoa_append.return+3 + jmp b6 + // ultoa::@6 + b6: + // [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 -- vduz1=vduz2 + lda.z ultoa_append.return + sta.z value + lda.z ultoa_append.return+1 + sta.z value+1 + lda.z ultoa_append.return+2 + sta.z value+2 + lda.z ultoa_append.return+3 + sta.z value+3 + // [61] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#29 -- pbuz1=_inc_pbuz1 + inc.z buffer_4 + bne !+ + inc.z buffer_4+1 + !: + // [43] phi from ultoa::@6 to ultoa::@4 [phi:ultoa::@6->ultoa::@4] + b4_from_b6: + // [43] phi (byte) ultoa::digit#13 = (byte) ultoa::digit#14 [phi:ultoa::@6->ultoa::@4#0] -- register_copy + // [43] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#4 [phi:ultoa::@6->ultoa::@4#1] -- register_copy + // [43] phi (byte) ultoa::started#2 = (byte) 1 [phi:ultoa::@6->ultoa::@4#2] -- vbuz1=vbuc1 + lda #1 + sta.z started + // [43] phi (dword) ultoa::value#16 = (dword) ultoa::value#0 [phi:ultoa::@6->ultoa::@4#3] -- register_copy + jmp b4 +} + // ultoa_append +// Used to convert a single digit of an unsigned number value to a string representation +// Counts a single digit up from '0' as long as the value is larger than sub. +// Each time the digit is increased sub is subtracted from value. +// - buffer : pointer to the char that receives the digit +// - value : The value where the digit will be derived from +// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. +// (For decimal the subs used are 10000, 1000, 100, 10, 1) +// returns : the value reduced by sub * digit so that it is less than sub. +// ultoa_append(byte* zeropage($27) buffer, dword zeropage($1a) value, dword zeropage($29) sub) +ultoa_append: { + .label buffer = $27 + .label value = $1a + .label sub = $29 + .label return = $2d + .label digit = $1e + // [63] phi from ultoa_append to ultoa_append::@1 [phi:ultoa_append->ultoa_append::@1] + b1_from_ultoa_append: + // [63] phi (byte) ultoa_append::digit#2 = (byte) 0 [phi:ultoa_append->ultoa_append::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z digit + // [63] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#0 [phi:ultoa_append->ultoa_append::@1#1] -- register_copy + jmp b1 + // ultoa_append::@1 + b1: + // [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -- vduz1_ge_vduz2_then_la1 + lda.z value+3 + cmp.z sub+3 + bcc !+ + bne b2 + lda.z value+2 + cmp.z sub+2 + bcc !+ + bne b2 + lda.z value+1 + cmp.z sub+1 + bcc !+ + bne b2 + lda.z value + cmp.z sub + bcs b2 + !: + jmp b3 + // ultoa_append::@3 + b3: + // [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) -- _deref_pbuz1=pbuc1_derefidx_vbuz2 + ldy.z digit + lda DIGITS,y + ldy #0 + sta (buffer),y + jmp breturn + // ultoa_append::@return + breturn: + // [66] return + rts + // ultoa_append::@2 + b2: + // [67] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 -- vbuz1=_inc_vbuz1 + inc.z digit + // [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 -- vduz1=vduz1_minus_vduz2 + lda.z value + sec + sbc.z sub + sta.z value + lda.z value+1 + sbc.z sub+1 + sta.z value+1 + lda.z value+2 + sbc.z sub+2 + sta.z value+2 + lda.z value+3 + sbc.z sub+3 + sta.z value+3 + // [63] phi from ultoa_append::@2 to ultoa_append::@1 [phi:ultoa_append::@2->ultoa_append::@1] + b1_from_b2: + // [63] phi (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#1 [phi:ultoa_append::@2->ultoa_append::@1#0] -- register_copy + // [63] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#1 [phi:ultoa_append::@2->ultoa_append::@1#1] -- register_copy + jmp b1 +} + // File Data + // The digits used for numbers + DIGITS: .text "0123456789abcdef" + // Values of decimal digits + RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a + // Digits used for storing the decimal word + decimal_digits_long: .fill $b, 0 + jesper_initials: .text "jg" + .byte 0 + henry_initials: .text "hg" + .byte 0 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 [ print_char_cursor#49 print_line_cursor#1 ] ( main:2 [ print_char_cursor#49 print_line_cursor#1 ] ) always clobbers reg byte a +Statement [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ( main:2::print_person:5 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] main:2::print_person:7 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ) always clobbers reg byte a +Statement [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ( main:2::print_person:5 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] main:2::print_person:7 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ) always clobbers reg byte a +Statement [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a +Statement [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a +Statement [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y +Statement [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y +Statement [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 [ print_char_cursor#18 ] ( main:2::print_person:5::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] main:2::print_person:7::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] ) always clobbers reg byte a reg byte y +Statement [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 [ print_char_cursor#39 ultoa::value#1 ] ( main:2::print_person:5::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] main:2::print_person:7::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] ) always clobbers reg byte a +Statement [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) [ ultoa::value#1 ultoa::digit_value#4 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ultoa::digit_value#4 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ultoa::digit_value#4 ] ) always clobbers reg byte a +Statement [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 [ ultoa::digit#15 ultoa::value#21 ultoa::started#8 ultoa::buffer#28 ultoa::digit_value#3 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#15 ultoa::value#21 ultoa::started#8 ultoa::buffer#28 ultoa::digit_value#3 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#15 ultoa::value#21 ultoa::started#8 ultoa::buffer#28 ultoa::digit_value#3 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:14 [ ultoa::started#8 ultoa::started#2 ] +Statement [46] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#16 [ ultoa::buffer#11 ultoa::$4 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] ) always clobbers reg byte a +Statement [47] *((byte*) ultoa::buffer#11) ← *((const byte[]) DIGITS#0 + (byte~) ultoa::$4) [ ultoa::buffer#11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] ) always clobbers reg byte a reg byte y +Statement [48] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 [ ultoa::buffer#3 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] ) always clobbers reg byte a +Statement [49] *((byte*) ultoa::buffer#3) ← (byte) 0 [ ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] ) always clobbers reg byte a reg byte y +Statement [51] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 << (byte) 2 [ ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ) always clobbers reg byte a +Statement [52] (dword) ultoa::digit_value#0 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0 + (byte~) ultoa::$11) [ ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ) always clobbers reg byte a +Statement [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 [ ultoa::digit#14 ultoa::value#22 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::value#22 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::value#22 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ] ) always clobbers reg byte a +Statement [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 [ ultoa::digit#14 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ultoa_append::value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ultoa_append::value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ultoa_append::value#0 ] ) always clobbers reg byte a +Statement [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 [ ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ) always clobbers reg byte a +Statement [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 [ ultoa::digit#14 ultoa::buffer#29 ultoa_append::return#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::return#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::return#0 ] ) always clobbers reg byte a +Statement [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 [ ultoa::value#0 ultoa::digit#14 ultoa::buffer#29 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#0 ultoa::digit#14 ultoa::buffer#29 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#0 ultoa::digit#14 ultoa::buffer#29 ] ) always clobbers reg byte a +Statement [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:30 [ ultoa_append::digit#2 ultoa_append::digit#1 ] +Statement [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) [ ultoa_append::value#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::value#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::value#2 ] ) always clobbers reg byte a reg byte y +Removing always clobbered register reg byte y as potential for zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +Statement [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ) always clobbers reg byte a +Statement [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 [ print_char_cursor#49 print_line_cursor#1 ] ( main:2 [ print_char_cursor#49 print_line_cursor#1 ] ) always clobbers reg byte a +Statement [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ( main:2::print_person:5 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] main:2::print_person:7 [ print_char_cursor#39 print_person::person_initials#2 print_line_cursor#20 print_dword_decimal::w#0 ] ) always clobbers reg byte a +Statement [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ( main:2::print_person:5 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] main:2::print_person:7 [ print_line_cursor#20 print_str::str#2 print_char_cursor#25 ] ) always clobbers reg byte a +Statement [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a +Statement [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 [ print_line_cursor#1 print_char_cursor#18 ] ( main:2::print_person:5::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] main:2::print_person:7::print_ln:17 [ print_line_cursor#1 print_char_cursor#18 ] ) always clobbers reg byte a +Statement [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y +Statement [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) [ print_char_cursor#18 print_str::str#3 ] ( main:2::print_person:5::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_str:15 [ print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:5::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] main:2::print_person:7::print_dword_decimal:11::print_str:37 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 print_str::str#3 ] ) always clobbers reg byte a reg byte y +Statement [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 [ print_char_cursor#18 ] ( main:2::print_person:5::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] main:2::print_person:7::print_char:13 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#18 ] ) always clobbers reg byte a reg byte y +Statement [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 [ print_char_cursor#39 ultoa::value#1 ] ( main:2::print_person:5::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] main:2::print_person:7::print_dword_decimal:11 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ] ) always clobbers reg byte a +Statement [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) [ ultoa::value#1 ultoa::digit_value#4 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ultoa::digit_value#4 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#1 ultoa::digit_value#4 ] ) always clobbers reg byte a +Statement [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 [ ultoa::digit#15 ultoa::value#21 ultoa::started#8 ultoa::buffer#28 ultoa::digit_value#3 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#15 ultoa::value#21 ultoa::started#8 ultoa::buffer#28 ultoa::digit_value#3 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#15 ultoa::value#21 ultoa::started#8 ultoa::buffer#28 ultoa::digit_value#3 ] ) always clobbers reg byte a +Statement [46] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#16 [ ultoa::buffer#11 ultoa::$4 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ultoa::$4 ] ) always clobbers reg byte a +Statement [47] *((byte*) ultoa::buffer#11) ← *((const byte[]) DIGITS#0 + (byte~) ultoa::$4) [ ultoa::buffer#11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#11 ] ) always clobbers reg byte a reg byte y +Statement [48] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 [ ultoa::buffer#3 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::buffer#3 ] ) always clobbers reg byte a +Statement [49] *((byte*) ultoa::buffer#3) ← (byte) 0 [ ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ] ) always clobbers reg byte a reg byte y +Statement [51] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 << (byte) 2 [ ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::$11 ] ) always clobbers reg byte a +Statement [52] (dword) ultoa::digit_value#0 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0 + (byte~) ultoa::$11) [ ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#1 ultoa::value#16 ultoa::started#2 ultoa::buffer#11 ultoa::digit_value#0 ] ) always clobbers reg byte a +Statement [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 [ ultoa::digit#14 ultoa::value#22 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::value#22 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::value#22 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ] ) always clobbers reg byte a +Statement [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 [ ultoa::digit#14 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ultoa_append::value#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ultoa_append::value#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa::digit_value#2 ultoa_append::buffer#0 ultoa_append::value#0 ] ) always clobbers reg byte a +Statement [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 [ ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::value#0 ultoa_append::sub#0 ] ) always clobbers reg byte a +Statement [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 [ ultoa::digit#14 ultoa::buffer#29 ultoa_append::return#0 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::return#0 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::return#0 ] ) always clobbers reg byte a +Statement [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 [ ultoa::value#0 ultoa::digit#14 ultoa::buffer#29 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#0 ultoa::digit#14 ultoa::buffer#29 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::value#0 ultoa::digit#14 ultoa::buffer#29 ] ) always clobbers reg byte a +Statement [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#2 ultoa_append::digit#2 ] ) always clobbers reg byte a +Statement [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) [ ultoa_append::value#2 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::value#2 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::value#2 ] ) always clobbers reg byte a reg byte y +Statement [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 [ ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ( main:2::print_person:5::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] main:2::print_person:7::print_dword_decimal:11::ultoa:35::ultoa_append:58 [ print_person::person_initials#2 print_line_cursor#20 print_char_cursor#39 ultoa::digit#14 ultoa::buffer#29 ultoa_append::buffer#0 ultoa_append::sub#0 ultoa_append::value#1 ultoa_append::digit#1 ] ) always clobbers reg byte a +Potential registers zp ZP_DWORD:2 [ print_person::person_id#2 ] : zp ZP_DWORD:2 , +Potential registers zp ZP_WORD:6 [ print_person::person_initials#2 ] : zp ZP_WORD:6 , +Potential registers zp ZP_WORD:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] : zp ZP_WORD:8 , +Potential registers zp ZP_WORD:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] : zp ZP_WORD:10 , +Potential registers zp ZP_WORD:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] : zp ZP_WORD:12 , +Potential registers zp ZP_BYTE:14 [ ultoa::started#8 ultoa::started#2 ] : zp ZP_BYTE:14 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] : zp ZP_BYTE:15 , reg byte x , +Potential registers zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] : zp ZP_DWORD:16 , +Potential registers zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] : zp ZP_WORD:20 , +Potential registers zp ZP_DWORD:22 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] : zp ZP_DWORD:22 , +Potential registers zp ZP_DWORD:26 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] : zp ZP_DWORD:26 , +Potential registers zp ZP_BYTE:30 [ ultoa_append::digit#2 ultoa_append::digit#1 ] : zp ZP_BYTE:30 , reg byte x , reg byte y , +Potential registers zp ZP_DWORD:31 [ print_dword_decimal::w#0 ] : zp ZP_DWORD:31 , +Potential registers zp ZP_BYTE:35 [ ultoa::$4 ] : zp ZP_BYTE:35 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_WORD:36 [ ultoa::buffer#3 ] : zp ZP_WORD:36 , +Potential registers zp ZP_BYTE:38 [ ultoa::$11 ] : zp ZP_BYTE:38 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_WORD:39 [ ultoa_append::buffer#0 ] : zp ZP_WORD:39 , +Potential registers zp ZP_DWORD:41 [ ultoa_append::sub#0 ] : zp ZP_DWORD:41 , +Potential registers zp ZP_DWORD:45 [ ultoa_append::return#0 ] : zp ZP_DWORD:45 , + +REGISTER UPLIFT SCOPES +Uplift Scope [ultoa_append] 259: zp ZP_DWORD:26 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] 203: zp ZP_BYTE:30 [ ultoa_append::digit#2 ultoa_append::digit#1 ] 35.5: zp ZP_DWORD:41 [ ultoa_append::sub#0 ] 22: zp ZP_DWORD:45 [ ultoa_append::return#0 ] 1.62: zp ZP_WORD:39 [ ultoa_append::buffer#0 ] +Uplift Scope [ultoa] 64.62: zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] 59.17: zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] 50.79: zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] 49: zp ZP_DWORD:22 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] 22: zp ZP_BYTE:38 [ ultoa::$11 ] 16.5: zp ZP_BYTE:14 [ ultoa::started#8 ultoa::started#2 ] 4: zp ZP_BYTE:35 [ ultoa::$4 ] 4: zp ZP_WORD:36 [ ultoa::buffer#3 ] +Uplift Scope [] 29.73: zp ZP_WORD:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] 26.13: zp ZP_WORD:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +Uplift Scope [print_str] 41.5: zp ZP_WORD:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +Uplift Scope [print_dword_decimal] 4: zp ZP_DWORD:31 [ print_dword_decimal::w#0 ] +Uplift Scope [print_person] 2: zp ZP_DWORD:2 [ print_person::person_id#2 ] 0.4: zp ZP_WORD:6 [ print_person::person_initials#2 ] +Uplift Scope [RADIX] +Uplift Scope [print_ln] +Uplift Scope [print_char] +Uplift Scope [Person] +Uplift Scope [main] + +Uplifting [ultoa_append] best 13485 combination zp ZP_DWORD:26 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ] zp ZP_DWORD:41 [ ultoa_append::sub#0 ] zp ZP_DWORD:45 [ ultoa_append::return#0 ] zp ZP_WORD:39 [ ultoa_append::buffer#0 ] +Uplifting [ultoa] best 13351 combination zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] zp ZP_DWORD:22 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] reg byte a [ ultoa::$11 ] reg byte x [ ultoa::started#8 ultoa::started#2 ] reg byte a [ ultoa::$4 ] zp ZP_WORD:36 [ ultoa::buffer#3 ] +Uplifting [] best 13351 combination zp ZP_WORD:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] zp ZP_WORD:12 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +Uplifting [print_str] best 13351 combination zp ZP_WORD:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +Uplifting [print_dword_decimal] best 13351 combination zp ZP_DWORD:31 [ print_dword_decimal::w#0 ] +Uplifting [print_person] best 13351 combination zp ZP_DWORD:2 [ print_person::person_id#2 ] zp ZP_WORD:6 [ print_person::person_initials#2 ] +Uplifting [RADIX] best 13351 combination +Uplifting [print_ln] best 13351 combination +Uplifting [print_char] best 13351 combination +Uplifting [Person] best 13351 combination +Uplifting [main] best 13351 combination +Attempting to uplift remaining variables inzp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +Uplifting [ultoa] best 13351 combination zp ZP_BYTE:15 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +Coalescing zero page register [ zp ZP_DWORD:2 [ print_person::person_id#2 ] ] with [ zp ZP_DWORD:31 [ print_dword_decimal::w#0 ] ] - score: 1 +Coalescing zero page register [ zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ] ] with [ zp ZP_DWORD:26 [ ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] ] - score: 1 +Coalescing zero page register [ zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ] ] with [ zp ZP_DWORD:45 [ ultoa_append::return#0 ] ] - score: 1 +Coalescing zero page register [ zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ] ] with [ zp ZP_WORD:36 [ ultoa::buffer#3 ] ] - score: 1 +Coalescing zero page register [ zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ultoa::buffer#3 ] ] with [ zp ZP_WORD:39 [ ultoa_append::buffer#0 ] ] - score: 1 +Coalescing zero page register [ zp ZP_DWORD:22 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ] ] with [ zp ZP_DWORD:41 [ ultoa_append::sub#0 ] ] - score: 1 +Coalescing zero page register [ zp ZP_DWORD:2 [ print_person::person_id#2 print_dword_decimal::w#0 ] ] with [ zp ZP_DWORD:16 [ ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ] ] - score: 1 +Coalescing zero page register [ zp ZP_WORD:20 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 ] ] with [ zp ZP_WORD:10 [ print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] ] +Allocated (was zp ZP_WORD:12) zp ZP_WORD:10 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +Allocated (was zp ZP_BYTE:15) zp ZP_BYTE:12 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +Allocated (was zp ZP_WORD:20) zp ZP_WORD:13 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +Allocated (was zp ZP_DWORD:22) zp ZP_DWORD:15 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ultoa_append::sub#0 ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Example of a struct containing an array + // Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" + // Global Constants & labels + .const jesper_id = $1b244 + .const henry_id = $4466d + .label print_char_cursor = $a + .label print_line_cursor = 8 + // @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: { + // [5] call print_person + // [9] phi from main to print_person [phi:main->print_person] + print_person_from_main: + // [9] phi (byte*) print_line_cursor#20 = (byte*) 1024 [phi:main->print_person#0] -- pbuz1=pbuc1 + lda #<$400 + sta.z print_line_cursor + lda #>$400 + sta.z print_line_cursor+1 + // [9] phi (byte[2]) print_person::person_initials#2 = (const byte[2]) jesper_initials#0 [phi:main->print_person#1] -- pbuz1=pbuc1 + lda #jesper_initials + sta.z print_person.person_initials+1 + // [9] phi (byte*) print_char_cursor#39 = (byte*) 1024 [phi:main->print_person#2] -- pbuz1=pbuc1 + lda #<$400 + sta.z print_char_cursor + lda #>$400 + sta.z print_char_cursor+1 + // [9] phi (dword) print_person::person_id#2 = (const dword) jesper_id#0 [phi:main->print_person#3] -- vduz1=vduc1 + lda #jesper_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>jesper_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + jmp b1 + // main::@1 + b1: + // [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 + lda.z print_line_cursor + sta.z print_char_cursor + lda.z print_line_cursor+1 + sta.z print_char_cursor+1 + // [7] call print_person + // [9] phi from main::@1 to print_person [phi:main::@1->print_person] + print_person_from_b1: + // [9] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#1 [phi:main::@1->print_person#0] -- register_copy + // [9] phi (byte[2]) print_person::person_initials#2 = (const byte[2]) henry_initials#0 [phi:main::@1->print_person#1] -- pbuz1=pbuc1 + lda #henry_initials + sta.z print_person.person_initials+1 + // [9] phi (byte*) print_char_cursor#39 = (byte*~) print_char_cursor#49 [phi:main::@1->print_person#2] -- register_copy + // [9] phi (dword) print_person::person_id#2 = (const dword) henry_id#0 [phi:main::@1->print_person#3] -- vduz1=vduc1 + lda #henry_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>henry_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + jmp breturn + // main::@return + breturn: + // [8] return + rts +} + // print_person +// print_person(dword zeropage(2) person_id, byte[2] zeropage(6) person_initials) +print_person: { + .label person_id = 2 + .label person_initials = 6 + // [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 + // [11] call print_dword_decimal + jsr print_dword_decimal + // [12] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] + b1_from_print_person: + jmp b1 + // print_person::@1 + b1: + // [13] call print_char + jsr print_char + jmp b2 + // print_person::@2 + b2: + // [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 -- pbuz1=pbuz2 + lda.z person_initials + sta.z print_str.str + lda.z person_initials+1 + sta.z print_str.str+1 + // [15] call print_str + // [24] phi from print_person::@2 to print_str [phi:print_person::@2->print_str] + print_str_from_b2: + // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#25 [phi:print_person::@2->print_str#0] -- register_copy + // [24] phi (byte*) print_str::str#5 = (byte*) print_str::str#2 [phi:print_person::@2->print_str#1] -- register_copy + jsr print_str + // [16] phi from print_person::@2 to print_person::@3 [phi:print_person::@2->print_person::@3] + b3_from_b2: + jmp b3 + // print_person::@3 + b3: + // [17] call print_ln + // [19] phi from print_person::@3 to print_ln [phi:print_person::@3->print_ln] + print_ln_from_b3: + jsr print_ln + jmp breturn + // print_person::@return + breturn: + // [18] return + rts +} + // print_ln +// Print a newline +print_ln: { + // [20] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] + b1_from_print_ln: + b1_from_b1: + // [20] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#20 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy + jmp b1 + // print_ln::@1 + b1: + // [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z print_line_cursor + sta.z print_line_cursor + bcc !+ + inc.z print_line_cursor+1 + !: + // [22] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#18) goto print_ln::@1 -- pbuz1_lt_pbuz2_then_la1 + lda.z print_line_cursor+1 + cmp.z print_char_cursor+1 + bcc b1_from_b1 + bne !+ + lda.z print_line_cursor + cmp.z print_char_cursor + bcc b1_from_b1 + !: + jmp breturn + // print_ln::@return + breturn: + // [23] return + rts +} + // print_str +// Print a zero-terminated string +// print_str(byte* zeropage($d) str) +print_str: { + .label str = $d + // [25] phi from print_str print_str::@2 to print_str::@1 [phi:print_str/print_str::@2->print_str::@1] + b1_from_print_str: + b1_from_b2: + // [25] phi (byte*) print_char_cursor#18 = (byte*) print_char_cursor#41 [phi:print_str/print_str::@2->print_str::@1#0] -- register_copy + // [25] phi (byte*) print_str::str#3 = (byte*) print_str::str#5 [phi:print_str/print_str::@2->print_str::@1#1] -- register_copy + jmp b1 + // print_str::@1 + b1: + // [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 + ldy #0 + lda (str),y + cmp #0 + bne b2 + jmp breturn + // print_str::@return + breturn: + // [27] return + rts + // print_str::@2 + b2: + // [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (str),y + ldy #0 + sta (print_char_cursor),y + // [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + // [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 -- pbuz1=_inc_pbuz1 + inc.z str + bne !+ + inc.z str+1 + !: + jmp b1_from_b2 +} + // print_char +// Print a single char +print_char: { + .const ch = ' ' + // [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 -- _deref_pbuz1=vbuc1 + lda #ch + ldy #0 + sta (print_char_cursor),y + // [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + jmp breturn + // print_char::@return + breturn: + // [33] return + rts +} + // print_dword_decimal +// Print a dword as DECIMAL +// print_dword_decimal(dword zeropage(2) w) +print_dword_decimal: { + .label w = 2 + // [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 + // [35] call ultoa + // [39] phi from print_dword_decimal to ultoa [phi:print_dword_decimal->ultoa] + ultoa_from_print_dword_decimal: + jsr ultoa + // [36] phi from print_dword_decimal to print_dword_decimal::@1 [phi:print_dword_decimal->print_dword_decimal::@1] + b1_from_print_dword_decimal: + jmp b1 + // print_dword_decimal::@1 + b1: + // [37] call print_str + // [24] phi from print_dword_decimal::@1 to print_str [phi:print_dword_decimal::@1->print_str] + print_str_from_b1: + // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#39 [phi:print_dword_decimal::@1->print_str#0] -- register_copy + // [24] phi (byte*) print_str::str#5 = (const byte[$b]) decimal_digits_long#0 [phi:print_dword_decimal::@1->print_str#1] -- pbuz1=pbuc1 + lda #decimal_digits_long + sta.z print_str.str+1 + jsr print_str + jmp breturn + // print_dword_decimal::@return + breturn: + // [38] return + rts +} + // ultoa +// Converts unsigned number value to a string representing it in RADIX format. +// If the leading digits are zero they are not included in the string. +// - value : The number to be converted to RADIX +// - buffer : receives the string representing the number and zero-termination. +// - radix : The radix to convert the number to (from the enum RADIX) +// ultoa(dword zeropage(2) value, byte* zeropage($d) buffer) +ultoa: { + .const max_digits = $a + .label digit_value = $f + .label buffer = $d + .label digit = $c + .label value = 2 + jmp b19_1 + // ultoa::@19_1 + b19_1: + // [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) -- vduz1=_deref_pduc1 + lda RADIX_DECIMAL_VALUES_LONG + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1 + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2 + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3 + sta.z digit_value+3 + // [41] phi from ultoa::@19_1 to ultoa::@7 [phi:ultoa::@19_1->ultoa::@7] + b7_from_b19_1: + // [41] phi (dword) ultoa::digit_value#3 = (dword) ultoa::digit_value#4 [phi:ultoa::@19_1->ultoa::@7#0] -- register_copy + // [41] phi (byte*) ultoa::buffer#28 = (const byte[$b]) decimal_digits_long#0 [phi:ultoa::@19_1->ultoa::@7#1] -- pbuz1=pbuc1 + lda #decimal_digits_long + sta.z buffer+1 + // [41] phi (byte) ultoa::started#8 = (byte) 0 [phi:ultoa::@19_1->ultoa::@7#2] -- vbuxx=vbuc1 + ldx #0 + // [41] phi (dword) ultoa::value#21 = (dword) ultoa::value#1 [phi:ultoa::@19_1->ultoa::@7#3] -- register_copy + // [41] phi (byte) ultoa::digit#15 = (byte) 0 [phi:ultoa::@19_1->ultoa::@7#4] -- vbuz1=vbuc1 + lda #0 + sta.z digit + jmp b7 + // ultoa::@7 + b7: + // [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 -- vduz1_ge_vduz2_then_la1 + lda.z value+3 + cmp.z digit_value+3 + bcc !+ + bne b5_from_b7 + lda.z value+2 + cmp.z digit_value+2 + bcc !+ + bne b5_from_b7 + lda.z value+1 + cmp.z digit_value+1 + bcc !+ + bne b5_from_b7 + lda.z value + cmp.z digit_value + bcs b5_from_b7 + !: + // [43] phi from ultoa::@7 to ultoa::@4 [phi:ultoa::@7->ultoa::@4] + b4_from_b7: + // [43] phi (byte) ultoa::digit#13 = (byte) ultoa::digit#15 [phi:ultoa::@7->ultoa::@4#0] -- register_copy + // [43] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#28 [phi:ultoa::@7->ultoa::@4#1] -- register_copy + // [43] phi (byte) ultoa::started#2 = (byte) ultoa::started#8 [phi:ultoa::@7->ultoa::@4#2] -- register_copy + // [43] phi (dword) ultoa::value#16 = (dword) ultoa::value#21 [phi:ultoa::@7->ultoa::@4#3] -- register_copy + jmp b4 + // ultoa::@4 + b4: + // [44] (byte) ultoa::digit#1 ← ++ (byte) ultoa::digit#13 -- vbuz1=_inc_vbuz1 + inc.z digit + jmp b1 + // ultoa::@1 + b1: + // [45] if((byte) ultoa::digit#1<(const byte) ultoa::max_digits#1-(byte) 1) goto ultoa::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z digit + cmp #max_digits-1 + bcc b2 + jmp b3 + // ultoa::@3 + b3: + // [46] (byte~) ultoa::$4 ← (byte)(dword) ultoa::value#16 -- vbuaa=_byte_vduz1 + lda.z value + // [47] *((byte*) ultoa::buffer#11) ← *((const byte[]) DIGITS#0 + (byte~) ultoa::$4) -- _deref_pbuz1=pbuc1_derefidx_vbuaa + tay + lda DIGITS,y + ldy #0 + sta (buffer),y + // [48] (byte*) ultoa::buffer#3 ← ++ (byte*) ultoa::buffer#11 -- pbuz1=_inc_pbuz1 + inc.z buffer + bne !+ + inc.z buffer+1 + !: + // [49] *((byte*) ultoa::buffer#3) ← (byte) 0 -- _deref_pbuz1=vbuc1 + lda #0 + ldy #0 + sta (buffer),y + jmp breturn + // ultoa::@return + breturn: + // [50] return + rts + // ultoa::@2 + b2: + // [51] (byte~) ultoa::$11 ← (byte) ultoa::digit#1 << (byte) 2 -- vbuaa=vbuz1_rol_2 + lda.z digit + asl + asl + // [52] (dword) ultoa::digit_value#0 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0 + (byte~) ultoa::$11) -- vduz1=pduc1_derefidx_vbuaa + tay + lda RADIX_DECIMAL_VALUES_LONG,y + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1,y + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2,y + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3,y + sta.z digit_value+3 + // [53] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 -- vbuc1_neq_vbuxx_then_la1 + cpx #0 + bne b5_from_b2 + // [41] phi from ultoa::@2 to ultoa::@7 [phi:ultoa::@2->ultoa::@7] + b7_from_b2: + // [41] phi (dword) ultoa::digit_value#3 = (dword) ultoa::digit_value#0 [phi:ultoa::@2->ultoa::@7#0] -- register_copy + // [41] phi (byte*) ultoa::buffer#28 = (byte*) ultoa::buffer#11 [phi:ultoa::@2->ultoa::@7#1] -- register_copy + // [41] phi (byte) ultoa::started#8 = (byte) ultoa::started#2 [phi:ultoa::@2->ultoa::@7#2] -- register_copy + // [41] phi (dword) ultoa::value#21 = (dword) ultoa::value#16 [phi:ultoa::@2->ultoa::@7#3] -- register_copy + // [41] phi (byte) ultoa::digit#15 = (byte) ultoa::digit#1 [phi:ultoa::@2->ultoa::@7#4] -- register_copy + jmp b7 + // [54] phi from ultoa::@2 ultoa::@7 to ultoa::@5 [phi:ultoa::@2/ultoa::@7->ultoa::@5] + b5_from_b2: + b5_from_b7: + // [54] phi (dword) ultoa::digit_value#2 = (dword) ultoa::digit_value#0 [phi:ultoa::@2/ultoa::@7->ultoa::@5#0] -- register_copy + // [54] phi (byte*) ultoa::buffer#29 = (byte*) ultoa::buffer#11 [phi:ultoa::@2/ultoa::@7->ultoa::@5#1] -- register_copy + // [54] phi (dword) ultoa::value#22 = (dword) ultoa::value#16 [phi:ultoa::@2/ultoa::@7->ultoa::@5#2] -- register_copy + // [54] phi (byte) ultoa::digit#14 = (byte) ultoa::digit#1 [phi:ultoa::@2/ultoa::@7->ultoa::@5#3] -- register_copy + jmp b5 + // ultoa::@5 + b5: + // [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 + // [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 + // [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 + // [58] call ultoa_append + // [62] phi from ultoa::@5 to ultoa_append [phi:ultoa::@5->ultoa_append] + ultoa_append_from_b5: + jsr ultoa_append + // [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 + jmp b6 + // ultoa::@6 + b6: + // [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 + // [61] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#29 -- pbuz1=_inc_pbuz1 + inc.z buffer + bne !+ + inc.z buffer+1 + !: + // [43] phi from ultoa::@6 to ultoa::@4 [phi:ultoa::@6->ultoa::@4] + b4_from_b6: + // [43] phi (byte) ultoa::digit#13 = (byte) ultoa::digit#14 [phi:ultoa::@6->ultoa::@4#0] -- register_copy + // [43] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#4 [phi:ultoa::@6->ultoa::@4#1] -- register_copy + // [43] phi (byte) ultoa::started#2 = (byte) 1 [phi:ultoa::@6->ultoa::@4#2] -- vbuxx=vbuc1 + ldx #1 + // [43] phi (dword) ultoa::value#16 = (dword) ultoa::value#0 [phi:ultoa::@6->ultoa::@4#3] -- register_copy + jmp b4 +} + // ultoa_append +// Used to convert a single digit of an unsigned number value to a string representation +// Counts a single digit up from '0' as long as the value is larger than sub. +// Each time the digit is increased sub is subtracted from value. +// - buffer : pointer to the char that receives the digit +// - value : The value where the digit will be derived from +// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. +// (For decimal the subs used are 10000, 1000, 100, 10, 1) +// returns : the value reduced by sub * digit so that it is less than sub. +// ultoa_append(byte* zeropage($d) buffer, dword zeropage(2) value, dword zeropage($f) sub) +ultoa_append: { + .label buffer = $d + .label value = 2 + .label sub = $f + .label return = 2 + // [63] phi from ultoa_append to ultoa_append::@1 [phi:ultoa_append->ultoa_append::@1] + b1_from_ultoa_append: + // [63] phi (byte) ultoa_append::digit#2 = (byte) 0 [phi:ultoa_append->ultoa_append::@1#0] -- vbuxx=vbuc1 + ldx #0 + // [63] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#0 [phi:ultoa_append->ultoa_append::@1#1] -- register_copy + jmp b1 + // ultoa_append::@1 + b1: + // [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -- vduz1_ge_vduz2_then_la1 + lda.z value+3 + cmp.z sub+3 + bcc !+ + bne b2 + lda.z value+2 + cmp.z sub+2 + bcc !+ + bne b2 + lda.z value+1 + cmp.z sub+1 + bcc !+ + bne b2 + lda.z value + cmp.z sub + bcs b2 + !: + jmp b3 + // ultoa_append::@3 + b3: + // [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) -- _deref_pbuz1=pbuc1_derefidx_vbuxx + lda DIGITS,x + ldy #0 + sta (buffer),y + jmp breturn + // ultoa_append::@return + breturn: + // [66] return + rts + // ultoa_append::@2 + b2: + // [67] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 -- vbuxx=_inc_vbuxx + inx + // [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 -- vduz1=vduz1_minus_vduz2 + lda.z value + sec + sbc.z sub + sta.z value + lda.z value+1 + sbc.z sub+1 + sta.z value+1 + lda.z value+2 + sbc.z sub+2 + sta.z value+2 + lda.z value+3 + sbc.z sub+3 + sta.z value+3 + // [63] phi from ultoa_append::@2 to ultoa_append::@1 [phi:ultoa_append::@2->ultoa_append::@1] + b1_from_b2: + // [63] phi (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#1 [phi:ultoa_append::@2->ultoa_append::@1#0] -- register_copy + // [63] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#1 [phi:ultoa_append::@2->ultoa_append::@1#1] -- register_copy + jmp b1 +} + // File Data + // The digits used for numbers + DIGITS: .text "0123456789abcdef" + // Values of decimal digits + RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a + // Digits used for storing the decimal word + decimal_digits_long: .fill $b, 0 + jesper_initials: .text "jg" + .byte 0 + henry_initials: .text "hg" + .byte 0 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp b19_1 +Removing instruction jmp b7 +Removing instruction jmp b4 +Removing instruction jmp b1 +Removing instruction jmp b3 +Removing instruction jmp breturn +Removing instruction jmp b5 +Removing instruction jmp b6 +Removing instruction jmp b1 +Removing instruction jmp b3 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction ldy #0 +Replacing instruction lda #0 with TXA +Replacing instruction ldy #0 with TAY +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b2 with b1 +Replacing label b5_from_b7 with b5 +Replacing label b5_from_b7 with b5 +Replacing label b5_from_b7 with b5 +Replacing label b5_from_b7 with b5 +Replacing label b5_from_b2 with b5 +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_print_person: +Removing instruction b3_from_b2: +Removing instruction print_ln_from_b3: +Removing instruction b1_from_print_ln: +Removing instruction b1_from_b1: +Removing instruction b1_from_print_str: +Removing instruction b1_from_b2: +Removing instruction b1_from_print_dword_decimal: +Removing instruction print_str_from_b1: +Removing instruction b4_from_b7: +Removing instruction b5_from_b2: +Removing instruction b5_from_b7: +Removing instruction ultoa_append_from_b5: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction print_person_from_main: +Removing instruction b1: +Removing instruction print_person_from_b1: +Removing instruction breturn: +Removing instruction b1: +Removing instruction b2: +Removing instruction print_str_from_b2: +Removing instruction b3: +Removing instruction breturn: +Removing instruction breturn: +Removing instruction breturn: +Removing instruction breturn: +Removing instruction ultoa_from_print_dword_decimal: +Removing instruction b1: +Removing instruction breturn: +Removing instruction b19_1: +Removing instruction b7_from_b19_1: +Removing instruction b1: +Removing instruction b3: +Removing instruction breturn: +Removing instruction b7_from_b2: +Removing instruction b6: +Removing instruction b4_from_b6: +Removing instruction b1_from_ultoa_append: +Removing instruction b3: +Removing instruction breturn: +Removing instruction b1_from_b2: +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 +(byte[]) DIGITS +(const byte[]) DIGITS#0 DIGITS = (string) "0123456789abcdef"z +(dword) Person::id +(byte[2]) Person::initials +(const byte) RADIX::BINARY BINARY = (number) 2 +(const byte) RADIX::DECIMAL DECIMAL = (number) $a +(const byte) RADIX::HEXADECIMAL HEXADECIMAL = (number) $10 +(const byte) RADIX::OCTAL OCTAL = (number) 8 +(dword[]) RADIX_BINARY_VALUES_LONG +(dword[]) RADIX_DECIMAL_VALUES_LONG +(const dword[]) RADIX_DECIMAL_VALUES_LONG#0 RADIX_DECIMAL_VALUES_LONG = { (dword) $3b9aca00, (dword) $5f5e100, (dword) $989680, (dword) $f4240, (dword) $186a0, (dword) $2710, (dword) $3e8, (dword) $64, (dword) $a } +(dword[]) RADIX_HEXADECIMAL_VALUES_LONG +(dword[]) RADIX_OCTAL_VALUES_LONG +(byte[$b]) decimal_digits_long +(const byte[$b]) decimal_digits_long#0 decimal_digits_long = { fill( $b, 0) } +(dword) henry_id +(const dword) henry_id#0 henry_id = (dword) $4466d +(byte[2]) henry_initials +(const byte[2]) henry_initials#0 henry_initials = (string) "hg" +(dword) jesper_id +(const dword) jesper_id#0 jesper_id = (dword) $1b244 +(byte[2]) jesper_initials +(const byte[2]) jesper_initials#0 jesper_initials = (string) "jg" +(void()) main() +(label) main::@1 +(label) main::@return +(void()) print_char((byte) print_char::ch) +(label) print_char::@return +(byte) print_char::ch +(const byte) print_char::ch#0 ch = (byte) ' ' +(byte*) print_char_cursor +(byte*) print_char_cursor#1 print_char_cursor zp ZP_WORD:10 11.0 +(byte*) print_char_cursor#18 print_char_cursor zp ZP_WORD:10 3.333333333333333 +(byte*) print_char_cursor#25 print_char_cursor zp ZP_WORD:10 1.0 +(byte*) print_char_cursor#39 print_char_cursor zp ZP_WORD:10 0.8 +(byte*) print_char_cursor#41 print_char_cursor zp ZP_WORD:10 6.0 +(byte*~) print_char_cursor#49 print_char_cursor zp ZP_WORD:10 4.0 +(void()) print_dword_decimal((dword) print_dword_decimal::w) +(label) print_dword_decimal::@1 +(label) print_dword_decimal::@return +(dword) print_dword_decimal::w +(dword) print_dword_decimal::w#0 w zp ZP_DWORD:2 4.0 +(byte*) print_line_cursor +(byte*) print_line_cursor#1 print_line_cursor zp ZP_WORD:8 5.285714285714286 +(byte*) print_line_cursor#20 print_line_cursor zp ZP_WORD:8 0.4444444444444444 +(byte*) print_line_cursor#9 print_line_cursor zp ZP_WORD:8 24.0 +(void()) print_ln() +(label) print_ln::@1 +(label) print_ln::@return +(void()) print_person((dword) print_person::person_id , (byte[2]) print_person::person_initials) +(label) print_person::@1 +(label) print_person::@2 +(label) print_person::@3 +(label) print_person::@return +(struct Person) print_person::person +(dword) print_person::person_id +(dword) print_person::person_id#2 person_id zp ZP_DWORD:2 2.0 +(byte[2]) print_person::person_initials +(byte[2]) print_person::person_initials#2 person_initials zp ZP_WORD:6 0.4 +(byte*) print_screen +(void()) print_str((byte*) print_str::str) +(label) print_str::@1 +(label) print_str::@2 +(label) print_str::@return +(byte*) print_str::str +(byte*) print_str::str#0 str zp ZP_WORD:13 22.0 +(byte*) print_str::str#2 str zp ZP_WORD:13 4.0 +(byte*) print_str::str#3 str zp ZP_WORD:13 11.5 +(byte*) print_str::str#5 str zp ZP_WORD:13 4.0 +(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) +(byte~) ultoa::$11 reg byte a 22.0 +(byte~) ultoa::$4 reg byte a 4.0 +(label) ultoa::@1 +(label) ultoa::@19_1 +(label) ultoa::@2 +(label) ultoa::@3 +(label) ultoa::@4 +(label) ultoa::@5 +(label) ultoa::@6 +(label) ultoa::@7 +(label) ultoa::@return +(byte*) ultoa::buffer +(byte*) ultoa::buffer#11 buffer zp ZP_WORD:13 6.0 +(byte*) ultoa::buffer#28 buffer zp ZP_WORD:13 16.5 +(byte*) ultoa::buffer#29 buffer zp ZP_WORD:13 6.285714285714286 +(byte*) ultoa::buffer#3 buffer zp ZP_WORD:13 4.0 +(byte*) ultoa::buffer#4 buffer zp ZP_WORD:13 22.0 +(byte) ultoa::digit +(byte) ultoa::digit#1 digit zp ZP_BYTE:12 11.0 +(byte) ultoa::digit#13 digit zp ZP_BYTE:12 33.0 +(byte) ultoa::digit#14 digit zp ZP_BYTE:12 4.125 +(byte) ultoa::digit#15 digit zp ZP_BYTE:12 16.5 +(dword) ultoa::digit_value +(dword) ultoa::digit_value#0 digit_value zp ZP_DWORD:15 16.5 +(dword) ultoa::digit_value#2 digit_value zp ZP_DWORD:15 11.0 +(dword) ultoa::digit_value#3 digit_value zp ZP_DWORD:15 17.5 +(dword) ultoa::digit_value#4 digit_value zp ZP_DWORD:15 4.0 +(dword*) ultoa::digit_values +(byte) ultoa::max_digits +(const byte) ultoa::max_digits#1 max_digits = (byte) $a +(byte) ultoa::radix +(byte) ultoa::started +(byte) ultoa::started#2 reg byte x 5.5 +(byte) ultoa::started#8 reg byte x 11.0 +(dword) ultoa::value +(dword) ultoa::value#0 value zp ZP_DWORD:2 11.0 +(dword) ultoa::value#1 value zp ZP_DWORD:2 1.3333333333333333 +(dword) ultoa::value#16 value zp ZP_DWORD:2 7.333333333333333 +(dword) ultoa::value#21 value zp ZP_DWORD:2 23.0 +(dword) ultoa::value#22 value zp ZP_DWORD:2 16.5 +(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) +(label) ultoa_append::@1 +(label) ultoa_append::@2 +(label) ultoa_append::@3 +(label) ultoa_append::@return +(byte*) ultoa_append::buffer +(byte*) ultoa_append::buffer#0 buffer zp ZP_WORD:13 1.625 +(byte) ultoa_append::digit +(byte) ultoa_append::digit#1 reg byte x 101.0 +(byte) ultoa_append::digit#2 reg byte x 102.0 +(dword) ultoa_append::return +(dword) ultoa_append::return#0 return zp ZP_DWORD:2 22.0 +(dword) ultoa_append::sub +(dword) ultoa_append::sub#0 sub zp ZP_DWORD:15 35.5 +(dword) ultoa_append::value +(dword) ultoa_append::value#0 value zp ZP_DWORD:2 4.333333333333333 +(dword) ultoa_append::value#1 value zp ZP_DWORD:2 202.0 +(dword) ultoa_append::value#2 value zp ZP_DWORD:2 52.66666666666666 + +zp ZP_DWORD:2 [ print_person::person_id#2 print_dword_decimal::w#0 ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ] +zp ZP_WORD:6 [ print_person::person_initials#2 ] +zp ZP_WORD:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] +zp ZP_WORD:10 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +reg byte x [ ultoa::started#8 ultoa::started#2 ] +zp ZP_BYTE:12 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +zp ZP_WORD:13 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +zp ZP_DWORD:15 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ultoa_append::sub#0 ] +reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ] +reg byte a [ ultoa::$4 ] +reg byte a [ ultoa::$11 ] + + +FINAL ASSEMBLER +Score: 11222 + + // File Comments +// Example of a struct containing an array + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .const jesper_id = $1b244 + .const henry_id = $4466d + .label print_char_cursor = $a + .label print_line_cursor = 8 + // @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: { + // print_person(jesper) + // [5] call print_person + // [9] phi from main to print_person [phi:main->print_person] + // [9] phi (byte*) print_line_cursor#20 = (byte*) 1024 [phi:main->print_person#0] -- pbuz1=pbuc1 + lda #<$400 + sta.z print_line_cursor + lda #>$400 + sta.z print_line_cursor+1 + // [9] phi (byte[2]) print_person::person_initials#2 = (const byte[2]) jesper_initials#0 [phi:main->print_person#1] -- pbuz1=pbuc1 + lda #jesper_initials + sta.z print_person.person_initials+1 + // [9] phi (byte*) print_char_cursor#39 = (byte*) 1024 [phi:main->print_person#2] -- pbuz1=pbuc1 + lda #<$400 + sta.z print_char_cursor + lda #>$400 + sta.z print_char_cursor+1 + // [9] phi (dword) print_person::person_id#2 = (const dword) jesper_id#0 [phi:main->print_person#3] -- vduz1=vduc1 + lda #jesper_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>jesper_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + // main::@1 + // [6] (byte*~) print_char_cursor#49 ← (byte*) print_line_cursor#1 -- pbuz1=pbuz2 + lda.z print_line_cursor + sta.z print_char_cursor + lda.z print_line_cursor+1 + sta.z print_char_cursor+1 + // print_person(henry) + // [7] call print_person + // [9] phi from main::@1 to print_person [phi:main::@1->print_person] + // [9] phi (byte*) print_line_cursor#20 = (byte*) print_line_cursor#1 [phi:main::@1->print_person#0] -- register_copy + // [9] phi (byte[2]) print_person::person_initials#2 = (const byte[2]) henry_initials#0 [phi:main::@1->print_person#1] -- pbuz1=pbuc1 + lda #henry_initials + sta.z print_person.person_initials+1 + // [9] phi (byte*) print_char_cursor#39 = (byte*~) print_char_cursor#49 [phi:main::@1->print_person#2] -- register_copy + // [9] phi (dword) print_person::person_id#2 = (const dword) henry_id#0 [phi:main::@1->print_person#3] -- vduz1=vduc1 + lda #henry_id + sta.z print_person.person_id+1 + lda #>$10 + sta.z print_person.person_id+2 + lda #>henry_id>>$10 + sta.z print_person.person_id+3 + jsr print_person + // main::@return + // } + // [8] return + rts +} + // print_person +// print_person(dword zeropage(2) person_id, byte[2] zeropage(6) person_initials) +print_person: { + .label person_id = 2 + .label person_initials = 6 + // print_dword_decimal(person.id) + // [10] (dword) print_dword_decimal::w#0 ← (dword) print_person::person_id#2 + // [11] call print_dword_decimal + jsr print_dword_decimal + // [12] phi from print_person to print_person::@1 [phi:print_person->print_person::@1] + // print_person::@1 + // print_char(' ') + // [13] call print_char + jsr print_char + // print_person::@2 + // print_str(person.initials) + // [14] (byte*) print_str::str#2 ← (byte[2]) print_person::person_initials#2 -- pbuz1=pbuz2 + lda.z person_initials + sta.z print_str.str + lda.z person_initials+1 + sta.z print_str.str+1 + // [15] call print_str + // [24] phi from print_person::@2 to print_str [phi:print_person::@2->print_str] + // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#25 [phi:print_person::@2->print_str#0] -- register_copy + // [24] phi (byte*) print_str::str#5 = (byte*) print_str::str#2 [phi:print_person::@2->print_str#1] -- register_copy + jsr print_str + // [16] phi from print_person::@2 to print_person::@3 [phi:print_person::@2->print_person::@3] + // print_person::@3 + // print_ln() + // [17] call print_ln + // [19] phi from print_person::@3 to print_ln [phi:print_person::@3->print_ln] + jsr print_ln + // print_person::@return + // } + // [18] return + rts +} + // print_ln +// Print a newline +print_ln: { + // [20] phi from print_ln print_ln::@1 to print_ln::@1 [phi:print_ln/print_ln::@1->print_ln::@1] + // [20] phi (byte*) print_line_cursor#9 = (byte*) print_line_cursor#20 [phi:print_ln/print_ln::@1->print_ln::@1#0] -- register_copy + // print_ln::@1 + b1: + // print_line_cursor + $28 + // [21] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#9 + (byte) $28 -- pbuz1=pbuz1_plus_vbuc1 + lda #$28 + clc + adc.z print_line_cursor + sta.z print_line_cursor + bcc !+ + inc.z print_line_cursor+1 + !: + // while (print_line_cursorprint_str::@1] + // [25] phi (byte*) print_char_cursor#18 = (byte*) print_char_cursor#41 [phi:print_str/print_str::@2->print_str::@1#0] -- register_copy + // [25] phi (byte*) print_str::str#3 = (byte*) print_str::str#5 [phi:print_str/print_str::@2->print_str::@1#1] -- register_copy + // print_str::@1 + b1: + // while(*str) + // [26] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1 + ldy #0 + lda (str),y + cmp #0 + bne b2 + // print_str::@return + // } + // [27] return + rts + // print_str::@2 + b2: + // *(print_char_cursor++) = *(str++) + // [28] *((byte*) print_char_cursor#18) ← *((byte*) print_str::str#3) -- _deref_pbuz1=_deref_pbuz2 + ldy #0 + lda (str),y + sta (print_char_cursor),y + // *(print_char_cursor++) = *(str++); + // [29] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + // [30] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3 -- pbuz1=_inc_pbuz1 + inc.z str + bne !+ + inc.z str+1 + !: + jmp b1 +} + // print_char +// Print a single char +print_char: { + .const ch = ' ' + // *(print_char_cursor++) = ch + // [31] *((byte*) print_char_cursor#18) ← (const byte) print_char::ch#0 -- _deref_pbuz1=vbuc1 + lda #ch + ldy #0 + sta (print_char_cursor),y + // *(print_char_cursor++) = ch; + // [32] (byte*) print_char_cursor#25 ← ++ (byte*) print_char_cursor#18 -- pbuz1=_inc_pbuz1 + inc.z print_char_cursor + bne !+ + inc.z print_char_cursor+1 + !: + // print_char::@return + // } + // [33] return + rts +} + // print_dword_decimal +// Print a dword as DECIMAL +// print_dword_decimal(dword zeropage(2) w) +print_dword_decimal: { + .label w = 2 + // ultoa(w, decimal_digits_long, DECIMAL) + // [34] (dword) ultoa::value#1 ← (dword) print_dword_decimal::w#0 + // [35] call ultoa + // [39] phi from print_dword_decimal to ultoa [phi:print_dword_decimal->ultoa] + jsr ultoa + // [36] phi from print_dword_decimal to print_dword_decimal::@1 [phi:print_dword_decimal->print_dword_decimal::@1] + // print_dword_decimal::@1 + // print_str(decimal_digits_long) + // [37] call print_str + // [24] phi from print_dword_decimal::@1 to print_str [phi:print_dword_decimal::@1->print_str] + // [24] phi (byte*) print_char_cursor#41 = (byte*) print_char_cursor#39 [phi:print_dword_decimal::@1->print_str#0] -- register_copy + // [24] phi (byte*) print_str::str#5 = (const byte[$b]) decimal_digits_long#0 [phi:print_dword_decimal::@1->print_str#1] -- pbuz1=pbuc1 + lda #decimal_digits_long + sta.z print_str.str+1 + jsr print_str + // print_dword_decimal::@return + // } + // [38] return + rts +} + // ultoa +// Converts unsigned number value to a string representing it in RADIX format. +// If the leading digits are zero they are not included in the string. +// - value : The number to be converted to RADIX +// - buffer : receives the string representing the number and zero-termination. +// - radix : The radix to convert the number to (from the enum RADIX) +// ultoa(dword zeropage(2) value, byte* zeropage($d) buffer) +ultoa: { + .const max_digits = $a + .label digit_value = $f + .label buffer = $d + .label digit = $c + .label value = 2 + // ultoa::@19_1 + // digit_value = digit_values[digit] + // [40] (dword) ultoa::digit_value#4 ← *((const dword[]) RADIX_DECIMAL_VALUES_LONG#0) -- vduz1=_deref_pduc1 + lda RADIX_DECIMAL_VALUES_LONG + sta.z digit_value + lda RADIX_DECIMAL_VALUES_LONG+1 + sta.z digit_value+1 + lda RADIX_DECIMAL_VALUES_LONG+2 + sta.z digit_value+2 + lda RADIX_DECIMAL_VALUES_LONG+3 + sta.z digit_value+3 + // [41] phi from ultoa::@19_1 to ultoa::@7 [phi:ultoa::@19_1->ultoa::@7] + // [41] phi (dword) ultoa::digit_value#3 = (dword) ultoa::digit_value#4 [phi:ultoa::@19_1->ultoa::@7#0] -- register_copy + // [41] phi (byte*) ultoa::buffer#28 = (const byte[$b]) decimal_digits_long#0 [phi:ultoa::@19_1->ultoa::@7#1] -- pbuz1=pbuc1 + lda #decimal_digits_long + sta.z buffer+1 + // [41] phi (byte) ultoa::started#8 = (byte) 0 [phi:ultoa::@19_1->ultoa::@7#2] -- vbuxx=vbuc1 + ldx #0 + // [41] phi (dword) ultoa::value#21 = (dword) ultoa::value#1 [phi:ultoa::@19_1->ultoa::@7#3] -- register_copy + // [41] phi (byte) ultoa::digit#15 = (byte) 0 [phi:ultoa::@19_1->ultoa::@7#4] -- vbuz1=vbuc1 + txa + sta.z digit + // ultoa::@7 + b7: + // if (started || value >= digit_value) + // [42] if((dword) ultoa::value#21>=(dword) ultoa::digit_value#3) goto ultoa::@5 -- vduz1_ge_vduz2_then_la1 + lda.z value+3 + cmp.z digit_value+3 + bcc !+ + bne b5 + lda.z value+2 + cmp.z digit_value+2 + bcc !+ + bne b5 + lda.z value+1 + cmp.z digit_value+1 + bcc !+ + bne b5 + lda.z value + cmp.z digit_value + bcs b5 + !: + // [43] phi from ultoa::@7 to ultoa::@4 [phi:ultoa::@7->ultoa::@4] + // [43] phi (byte) ultoa::digit#13 = (byte) ultoa::digit#15 [phi:ultoa::@7->ultoa::@4#0] -- register_copy + // [43] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#28 [phi:ultoa::@7->ultoa::@4#1] -- register_copy + // [43] phi (byte) ultoa::started#2 = (byte) ultoa::started#8 [phi:ultoa::@7->ultoa::@4#2] -- register_copy + // [43] phi (dword) ultoa::value#16 = (dword) ultoa::value#21 [phi:ultoa::@7->ultoa::@4#3] -- register_copy + // ultoa::@4 + b4: + // for( char digit=0; digit= digit_value) + // [53] if((byte) 0!=(byte) ultoa::started#2) goto ultoa::@5 -- vbuc1_neq_vbuxx_then_la1 + cpx #0 + bne b5 + // [41] phi from ultoa::@2 to ultoa::@7 [phi:ultoa::@2->ultoa::@7] + // [41] phi (dword) ultoa::digit_value#3 = (dword) ultoa::digit_value#0 [phi:ultoa::@2->ultoa::@7#0] -- register_copy + // [41] phi (byte*) ultoa::buffer#28 = (byte*) ultoa::buffer#11 [phi:ultoa::@2->ultoa::@7#1] -- register_copy + // [41] phi (byte) ultoa::started#8 = (byte) ultoa::started#2 [phi:ultoa::@2->ultoa::@7#2] -- register_copy + // [41] phi (dword) ultoa::value#21 = (dword) ultoa::value#16 [phi:ultoa::@2->ultoa::@7#3] -- register_copy + // [41] phi (byte) ultoa::digit#15 = (byte) ultoa::digit#1 [phi:ultoa::@2->ultoa::@7#4] -- register_copy + jmp b7 + // [54] phi from ultoa::@2 ultoa::@7 to ultoa::@5 [phi:ultoa::@2/ultoa::@7->ultoa::@5] + // [54] phi (dword) ultoa::digit_value#2 = (dword) ultoa::digit_value#0 [phi:ultoa::@2/ultoa::@7->ultoa::@5#0] -- register_copy + // [54] phi (byte*) ultoa::buffer#29 = (byte*) ultoa::buffer#11 [phi:ultoa::@2/ultoa::@7->ultoa::@5#1] -- register_copy + // [54] phi (dword) ultoa::value#22 = (dword) ultoa::value#16 [phi:ultoa::@2/ultoa::@7->ultoa::@5#2] -- register_copy + // [54] phi (byte) ultoa::digit#14 = (byte) ultoa::digit#1 [phi:ultoa::@2/ultoa::@7->ultoa::@5#3] -- register_copy + // ultoa::@5 + b5: + // ultoa_append(buffer++, value, digit_value) + // [55] (byte*) ultoa_append::buffer#0 ← (byte*) ultoa::buffer#29 + // [56] (dword) ultoa_append::value#0 ← (dword) ultoa::value#22 + // [57] (dword) ultoa_append::sub#0 ← (dword) ultoa::digit_value#2 + // [58] call ultoa_append + // [62] phi from ultoa::@5 to ultoa_append [phi:ultoa::@5->ultoa_append] + jsr ultoa_append + // ultoa_append(buffer++, value, digit_value) + // [59] (dword) ultoa_append::return#0 ← (dword) ultoa_append::value#2 + // ultoa::@6 + // value = ultoa_append(buffer++, value, digit_value) + // [60] (dword) ultoa::value#0 ← (dword) ultoa_append::return#0 + // value = ultoa_append(buffer++, value, digit_value); + // [61] (byte*) ultoa::buffer#4 ← ++ (byte*) ultoa::buffer#29 -- pbuz1=_inc_pbuz1 + inc.z buffer + bne !+ + inc.z buffer+1 + !: + // [43] phi from ultoa::@6 to ultoa::@4 [phi:ultoa::@6->ultoa::@4] + // [43] phi (byte) ultoa::digit#13 = (byte) ultoa::digit#14 [phi:ultoa::@6->ultoa::@4#0] -- register_copy + // [43] phi (byte*) ultoa::buffer#11 = (byte*) ultoa::buffer#4 [phi:ultoa::@6->ultoa::@4#1] -- register_copy + // [43] phi (byte) ultoa::started#2 = (byte) 1 [phi:ultoa::@6->ultoa::@4#2] -- vbuxx=vbuc1 + ldx #1 + // [43] phi (dword) ultoa::value#16 = (dword) ultoa::value#0 [phi:ultoa::@6->ultoa::@4#3] -- register_copy + jmp b4 +} + // ultoa_append +// Used to convert a single digit of an unsigned number value to a string representation +// Counts a single digit up from '0' as long as the value is larger than sub. +// Each time the digit is increased sub is subtracted from value. +// - buffer : pointer to the char that receives the digit +// - value : The value where the digit will be derived from +// - sub : the value of a '1' in the digit. Subtracted continually while the digit is increased. +// (For decimal the subs used are 10000, 1000, 100, 10, 1) +// returns : the value reduced by sub * digit so that it is less than sub. +// ultoa_append(byte* zeropage($d) buffer, dword zeropage(2) value, dword zeropage($f) sub) +ultoa_append: { + .label buffer = $d + .label value = 2 + .label sub = $f + .label return = 2 + // [63] phi from ultoa_append to ultoa_append::@1 [phi:ultoa_append->ultoa_append::@1] + // [63] phi (byte) ultoa_append::digit#2 = (byte) 0 [phi:ultoa_append->ultoa_append::@1#0] -- vbuxx=vbuc1 + ldx #0 + // [63] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#0 [phi:ultoa_append->ultoa_append::@1#1] -- register_copy + // ultoa_append::@1 + b1: + // while (value >= sub) + // [64] if((dword) ultoa_append::value#2>=(dword) ultoa_append::sub#0) goto ultoa_append::@2 -- vduz1_ge_vduz2_then_la1 + lda.z value+3 + cmp.z sub+3 + bcc !+ + bne b2 + lda.z value+2 + cmp.z sub+2 + bcc !+ + bne b2 + lda.z value+1 + cmp.z sub+1 + bcc !+ + bne b2 + lda.z value + cmp.z sub + bcs b2 + !: + // ultoa_append::@3 + // *buffer = DIGITS[digit] + // [65] *((byte*) ultoa_append::buffer#0) ← *((const byte[]) DIGITS#0 + (byte) ultoa_append::digit#2) -- _deref_pbuz1=pbuc1_derefidx_vbuxx + lda DIGITS,x + ldy #0 + sta (buffer),y + // ultoa_append::@return + // } + // [66] return + rts + // ultoa_append::@2 + b2: + // digit++; + // [67] (byte) ultoa_append::digit#1 ← ++ (byte) ultoa_append::digit#2 -- vbuxx=_inc_vbuxx + inx + // value -= sub + // [68] (dword) ultoa_append::value#1 ← (dword) ultoa_append::value#2 - (dword) ultoa_append::sub#0 -- vduz1=vduz1_minus_vduz2 + lda.z value + sec + sbc.z sub + sta.z value + lda.z value+1 + sbc.z sub+1 + sta.z value+1 + lda.z value+2 + sbc.z sub+2 + sta.z value+2 + lda.z value+3 + sbc.z sub+3 + sta.z value+3 + // [63] phi from ultoa_append::@2 to ultoa_append::@1 [phi:ultoa_append::@2->ultoa_append::@1] + // [63] phi (byte) ultoa_append::digit#2 = (byte) ultoa_append::digit#1 [phi:ultoa_append::@2->ultoa_append::@1#0] -- register_copy + // [63] phi (dword) ultoa_append::value#2 = (dword) ultoa_append::value#1 [phi:ultoa_append::@2->ultoa_append::@1#1] -- register_copy + jmp b1 +} + // File Data + // The digits used for numbers + DIGITS: .text "0123456789abcdef" + // Values of decimal digits + RADIX_DECIMAL_VALUES_LONG: .dword $3b9aca00, $5f5e100, $989680, $f4240, $186a0, $2710, $3e8, $64, $a + // Digits used for storing the decimal word + decimal_digits_long: .fill $b, 0 + jesper_initials: .text "jg" + .byte 0 + henry_initials: .text "hg" + .byte 0 + diff --git a/src/test/ref/struct-11.sym b/src/test/ref/struct-11.sym new file mode 100644 index 000000000..d5bee7e97 --- /dev/null +++ b/src/test/ref/struct-11.sym @@ -0,0 +1,143 @@ +(label) @1 +(label) @begin +(label) @end +(byte[]) DIGITS +(const byte[]) DIGITS#0 DIGITS = (string) "0123456789abcdef"z +(dword) Person::id +(byte[2]) Person::initials +(const byte) RADIX::BINARY BINARY = (number) 2 +(const byte) RADIX::DECIMAL DECIMAL = (number) $a +(const byte) RADIX::HEXADECIMAL HEXADECIMAL = (number) $10 +(const byte) RADIX::OCTAL OCTAL = (number) 8 +(dword[]) RADIX_BINARY_VALUES_LONG +(dword[]) RADIX_DECIMAL_VALUES_LONG +(const dword[]) RADIX_DECIMAL_VALUES_LONG#0 RADIX_DECIMAL_VALUES_LONG = { (dword) $3b9aca00, (dword) $5f5e100, (dword) $989680, (dword) $f4240, (dword) $186a0, (dword) $2710, (dword) $3e8, (dword) $64, (dword) $a } +(dword[]) RADIX_HEXADECIMAL_VALUES_LONG +(dword[]) RADIX_OCTAL_VALUES_LONG +(byte[$b]) decimal_digits_long +(const byte[$b]) decimal_digits_long#0 decimal_digits_long = { fill( $b, 0) } +(dword) henry_id +(const dword) henry_id#0 henry_id = (dword) $4466d +(byte[2]) henry_initials +(const byte[2]) henry_initials#0 henry_initials = (string) "hg" +(dword) jesper_id +(const dword) jesper_id#0 jesper_id = (dword) $1b244 +(byte[2]) jesper_initials +(const byte[2]) jesper_initials#0 jesper_initials = (string) "jg" +(void()) main() +(label) main::@1 +(label) main::@return +(void()) print_char((byte) print_char::ch) +(label) print_char::@return +(byte) print_char::ch +(const byte) print_char::ch#0 ch = (byte) ' ' +(byte*) print_char_cursor +(byte*) print_char_cursor#1 print_char_cursor zp ZP_WORD:10 11.0 +(byte*) print_char_cursor#18 print_char_cursor zp ZP_WORD:10 3.333333333333333 +(byte*) print_char_cursor#25 print_char_cursor zp ZP_WORD:10 1.0 +(byte*) print_char_cursor#39 print_char_cursor zp ZP_WORD:10 0.8 +(byte*) print_char_cursor#41 print_char_cursor zp ZP_WORD:10 6.0 +(byte*~) print_char_cursor#49 print_char_cursor zp ZP_WORD:10 4.0 +(void()) print_dword_decimal((dword) print_dword_decimal::w) +(label) print_dword_decimal::@1 +(label) print_dword_decimal::@return +(dword) print_dword_decimal::w +(dword) print_dword_decimal::w#0 w zp ZP_DWORD:2 4.0 +(byte*) print_line_cursor +(byte*) print_line_cursor#1 print_line_cursor zp ZP_WORD:8 5.285714285714286 +(byte*) print_line_cursor#20 print_line_cursor zp ZP_WORD:8 0.4444444444444444 +(byte*) print_line_cursor#9 print_line_cursor zp ZP_WORD:8 24.0 +(void()) print_ln() +(label) print_ln::@1 +(label) print_ln::@return +(void()) print_person((dword) print_person::person_id , (byte[2]) print_person::person_initials) +(label) print_person::@1 +(label) print_person::@2 +(label) print_person::@3 +(label) print_person::@return +(struct Person) print_person::person +(dword) print_person::person_id +(dword) print_person::person_id#2 person_id zp ZP_DWORD:2 2.0 +(byte[2]) print_person::person_initials +(byte[2]) print_person::person_initials#2 person_initials zp ZP_WORD:6 0.4 +(byte*) print_screen +(void()) print_str((byte*) print_str::str) +(label) print_str::@1 +(label) print_str::@2 +(label) print_str::@return +(byte*) print_str::str +(byte*) print_str::str#0 str zp ZP_WORD:13 22.0 +(byte*) print_str::str#2 str zp ZP_WORD:13 4.0 +(byte*) print_str::str#3 str zp ZP_WORD:13 11.5 +(byte*) print_str::str#5 str zp ZP_WORD:13 4.0 +(void()) ultoa((dword) ultoa::value , (byte*) ultoa::buffer , (byte) ultoa::radix) +(byte~) ultoa::$11 reg byte a 22.0 +(byte~) ultoa::$4 reg byte a 4.0 +(label) ultoa::@1 +(label) ultoa::@19_1 +(label) ultoa::@2 +(label) ultoa::@3 +(label) ultoa::@4 +(label) ultoa::@5 +(label) ultoa::@6 +(label) ultoa::@7 +(label) ultoa::@return +(byte*) ultoa::buffer +(byte*) ultoa::buffer#11 buffer zp ZP_WORD:13 6.0 +(byte*) ultoa::buffer#28 buffer zp ZP_WORD:13 16.5 +(byte*) ultoa::buffer#29 buffer zp ZP_WORD:13 6.285714285714286 +(byte*) ultoa::buffer#3 buffer zp ZP_WORD:13 4.0 +(byte*) ultoa::buffer#4 buffer zp ZP_WORD:13 22.0 +(byte) ultoa::digit +(byte) ultoa::digit#1 digit zp ZP_BYTE:12 11.0 +(byte) ultoa::digit#13 digit zp ZP_BYTE:12 33.0 +(byte) ultoa::digit#14 digit zp ZP_BYTE:12 4.125 +(byte) ultoa::digit#15 digit zp ZP_BYTE:12 16.5 +(dword) ultoa::digit_value +(dword) ultoa::digit_value#0 digit_value zp ZP_DWORD:15 16.5 +(dword) ultoa::digit_value#2 digit_value zp ZP_DWORD:15 11.0 +(dword) ultoa::digit_value#3 digit_value zp ZP_DWORD:15 17.5 +(dword) ultoa::digit_value#4 digit_value zp ZP_DWORD:15 4.0 +(dword*) ultoa::digit_values +(byte) ultoa::max_digits +(const byte) ultoa::max_digits#1 max_digits = (byte) $a +(byte) ultoa::radix +(byte) ultoa::started +(byte) ultoa::started#2 reg byte x 5.5 +(byte) ultoa::started#8 reg byte x 11.0 +(dword) ultoa::value +(dword) ultoa::value#0 value zp ZP_DWORD:2 11.0 +(dword) ultoa::value#1 value zp ZP_DWORD:2 1.3333333333333333 +(dword) ultoa::value#16 value zp ZP_DWORD:2 7.333333333333333 +(dword) ultoa::value#21 value zp ZP_DWORD:2 23.0 +(dword) ultoa::value#22 value zp ZP_DWORD:2 16.5 +(dword()) ultoa_append((byte*) ultoa_append::buffer , (dword) ultoa_append::value , (dword) ultoa_append::sub) +(label) ultoa_append::@1 +(label) ultoa_append::@2 +(label) ultoa_append::@3 +(label) ultoa_append::@return +(byte*) ultoa_append::buffer +(byte*) ultoa_append::buffer#0 buffer zp ZP_WORD:13 1.625 +(byte) ultoa_append::digit +(byte) ultoa_append::digit#1 reg byte x 101.0 +(byte) ultoa_append::digit#2 reg byte x 102.0 +(dword) ultoa_append::return +(dword) ultoa_append::return#0 return zp ZP_DWORD:2 22.0 +(dword) ultoa_append::sub +(dword) ultoa_append::sub#0 sub zp ZP_DWORD:15 35.5 +(dword) ultoa_append::value +(dword) ultoa_append::value#0 value zp ZP_DWORD:2 4.333333333333333 +(dword) ultoa_append::value#1 value zp ZP_DWORD:2 202.0 +(dword) ultoa_append::value#2 value zp ZP_DWORD:2 52.66666666666666 + +zp ZP_DWORD:2 [ print_person::person_id#2 print_dword_decimal::w#0 ultoa::value#22 ultoa::value#21 ultoa::value#16 ultoa::value#1 ultoa::value#0 ultoa_append::value#2 ultoa_append::value#0 ultoa_append::value#1 ultoa_append::return#0 ] +zp ZP_WORD:6 [ print_person::person_initials#2 ] +zp ZP_WORD:8 [ print_line_cursor#9 print_line_cursor#20 print_line_cursor#1 ] +zp ZP_WORD:10 [ print_char_cursor#18 print_char_cursor#41 print_char_cursor#39 print_char_cursor#49 print_char_cursor#25 print_char_cursor#1 ] +reg byte x [ ultoa::started#8 ultoa::started#2 ] +zp ZP_BYTE:12 [ ultoa::digit#13 ultoa::digit#14 ultoa::digit#15 ultoa::digit#1 ] +zp ZP_WORD:13 [ ultoa::buffer#29 ultoa::buffer#28 ultoa::buffer#11 ultoa::buffer#4 ultoa::buffer#3 ultoa_append::buffer#0 print_str::str#3 print_str::str#5 print_str::str#2 print_str::str#0 ] +zp ZP_DWORD:15 [ ultoa::digit_value#2 ultoa::digit_value#3 ultoa::digit_value#0 ultoa::digit_value#4 ultoa_append::sub#0 ] +reg byte x [ ultoa_append::digit#2 ultoa_append::digit#1 ] +reg byte a [ ultoa::$4 ] +reg byte a [ ultoa::$11 ]