diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java b/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java index 5664593e6..ccfb9306b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java @@ -1,13 +1,20 @@ package dk.camelot64.kickc.passes; +import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.symbols.Scope; +import dk.camelot64.kickc.model.symbols.VariableIntermediate; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.values.*; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.ConstantLiteral; +import dk.camelot64.kickc.model.values.ConstantValue; +import dk.camelot64.kickc.model.values.RValue; import java.util.ListIterator; @@ -22,20 +29,20 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { public boolean step() { boolean optimized = false; for(ControlFlowBlock block : getGraph().getAllBlocks()) { - ListIterator statementsIt = block.getStatements().listIterator(); - while(statementsIt.hasNext()) { - Statement statement = statementsIt.next(); + ListIterator stmtIt = block.getStatements().listIterator(); + while(stmtIt.hasNext()) { + Statement statement = stmtIt.next(); if(statement instanceof StatementAssignment) { StatementAssignment assignment = (StatementAssignment) statement; if(Operators.MULTIPLY.equals(assignment.getOperator()) || Operators.DIVIDE.equals(assignment.getOperator())) { if(assignment.getrValue1() instanceof ConstantValue) continue; ConstantLiteral constantLiteral = getConstantLiteral2(assignment); if(constantLiteral instanceof ConstantInteger) { - Long constantInt = ((ConstantInteger)constantLiteral).getInteger(); + Long constantInt = ((ConstantInteger) constantLiteral).getInteger(); double power2 = Math.log(constantInt) / Math.log(2); - if(power2==0.0) { + if(power2 == 0.0) { // Found multiplication/division with 1 (ONE) - getLog().append("Rewriting multiplication to remove identity multiply/divide "+statement.toString(getProgram(), false)); + getLog().append("Rewriting multiplication to remove identity multiply/divide " + statement.toString(getProgram(), false)); assignment.setOperator(null); assignment.setrValue2(assignment.getrValue1()); assignment.setrValue1(null); @@ -53,6 +60,49 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { assignment.setrValue2(new ConstantInteger((long)power2, SymbolType.BYTE)); optimized = true; } + } else if(Operators.MULTIPLY.equals(assignment.getOperator())) { + // Multiplication by constant + getLog().append("Rewriting multiplication to use shift and addition"+statement.toString(getProgram(), false)); + stmtIt.previous(); + Scope scope = getScope().getScope(block.getScope()); + SymbolType resultType = SymbolTypeInference.inferType(getScope(), assignment.getrValue1()); + long pow2 = (long) power2; + long remains = constantInt - (1L<=0) { + long powVal = 1L <=powVal) { + // First add shifts + VariableIntermediate varShift = scope.addVariableIntermediate(); + varShift.setType(resultType); + stmtIt.add(new StatementAssignment(varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), assignment.getSource(), Comment.NO_COMMENTS)); + shiftCount = 0; + // Then add rvalue1 + VariableIntermediate varAdd = scope.addVariableIntermediate(); + varAdd.setType(resultType); + stmtIt.add(new StatementAssignment(varAdd.getRef(), varShift.getRef(), Operators.PLUS, assignment.getrValue1(), assignment.getSource(), Comment.NO_COMMENTS)); + building = varAdd.getRef(); + remains -= powVal; + } + // Add a shift + if(pow2>0) { + shiftCount++; + } + pow2--; + } + // add remaining shifts + if(shiftCount>0) { + VariableIntermediate varShift = scope.addVariableIntermediate(); + varShift.setType(resultType); + stmtIt.add(new StatementAssignment(varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), assignment.getSource(), Comment.NO_COMMENTS)); + building = varShift.getRef(); + } + stmtIt.next(); + // Replace old multiplication + assignment.setOperator(null); + assignment.setrValue1(null); + assignment.setrValue2(building); } } } @@ -64,6 +114,7 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { /** * Get the constant literal value for RValue2 - or null if not possible + * * @param assignment The Assignment * @return The constant literal value for RValue2 (or null) */ diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index a80673cf9..093c7727a 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -35,6 +35,11 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testStructPtr11() throws IOException, URISyntaxException { + compileAndCompare("struct-ptr-11"); + } + @Test public void testStructPtr10() throws IOException, URISyntaxException { compileAndCompare("struct-ptr-10"); @@ -639,6 +644,11 @@ public class TestPrograms { compileAndCompare("multiply-2s"); } + @Test + public void testMultiplyNs() throws IOException, URISyntaxException { + compileAndCompare("multiply-ns"); + } + @Test public void testPointerCast2() throws IOException, URISyntaxException { compileAndCompare("pointer-cast-2"); diff --git a/src/test/kc/multiply-ns.kc b/src/test/kc/multiply-ns.kc new file mode 100644 index 000000000..7da716e11 --- /dev/null +++ b/src/test/kc/multiply-ns.kc @@ -0,0 +1,25 @@ +// Check that multiplication by constants is converted to shift/add + +void main() { + const byte* SCREEN = 0x0400; + + for(byte i: 0..17) { + (SCREEN+0*40)[i] = i*1; + (SCREEN+1*40)[i] = i*2; + (SCREEN+2*40)[i] = i*3; + (SCREEN+3*40)[i] = i*4; + (SCREEN+4*40)[i] = i*5; + (SCREEN+5*40)[i] = i*6; + (SCREEN+6*40)[i] = i*7; + (SCREEN+7*40)[i] = i*8; + (SCREEN+8*40)[i] = i*9; + (SCREEN+9*40)[i] = i*10; + (SCREEN+10*40)[i] = i*11; + (SCREEN+11*40)[i] = i*12; + (SCREEN+12*40)[i] = i*13; + (SCREEN+13*40)[i] = i*14; + (SCREEN+14*40)[i] = i*15; + } + +} + diff --git a/src/test/kc/struct-ptr-11.kc b/src/test/kc/struct-ptr-11.kc new file mode 100644 index 000000000..e41c95586 --- /dev/null +++ b/src/test/kc/struct-ptr-11.kc @@ -0,0 +1,20 @@ +// Minimal struct - array of 3-byte structs (required *3) + +struct Point { + signed byte x; + signed byte y; + signed byte z; +}; + +struct Point[4] points; + +void main() { + for( byte i: 0..3) { + points[i] = { (signed byte)i, -(signed byte)i, (signed byte)i }; + } + const struct Point* SCREEN = 0x0400; + for( byte i: 0..3) { + SCREEN[i] = points[i]; + } + +} \ No newline at end of file diff --git a/src/test/ref/multiply-ns.asm b/src/test/ref/multiply-ns.asm new file mode 100644 index 000000000..61e47f133 --- /dev/null +++ b/src/test/ref/multiply-ns.asm @@ -0,0 +1,107 @@ +// Check that multiplication by constants is converted to shift/add +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + .label _61 = 2 + .label _63 = 3 + ldx #0 + b1: + txa + sta SCREEN,x + txa + asl + sta _61 + sta SCREEN+1*$28,x + txa + clc + adc _61 + sta SCREEN+2*$28,x + txa + asl + asl + sta _63 + sta SCREEN+3*$28,x + txa + clc + adc _63 + sta SCREEN+4*$28,x + txa + clc + adc _61 + asl + sta SCREEN+5*$28,x + txa + clc + adc _61 + asl + stx $ff + clc + adc $ff + sta SCREEN+6*$28,x + txa + asl + asl + asl + sta SCREEN+7*$28,x + stx $ff + clc + adc $ff + sta SCREEN+8*$28,x + txa + clc + adc _63 + asl + sta SCREEN+9*$28,x + txa + clc + adc _63 + asl + stx $ff + clc + adc $ff + sta SCREEN+$a*$28,x + txa + clc + adc _61 + asl + asl + sta SCREEN+$b*$28,x + txa + clc + adc _61 + asl + asl + stx $ff + clc + adc $ff + sta SCREEN+$c*$28,x + txa + clc + adc _61 + asl + stx $ff + clc + adc $ff + asl + sta SCREEN+$d*$28,x + txa + clc + adc _61 + asl + stx $ff + clc + adc $ff + asl + stx $ff + clc + adc $ff + sta SCREEN+$e*$28,x + inx + cpx #$12 + beq !b1+ + jmp b1 + !b1: + rts +} diff --git a/src/test/ref/multiply-ns.cfg b/src/test/ref/multiply-ns.cfg new file mode 100644 index 000000000..2c3312453 --- /dev/null +++ b/src/test/ref/multiply-ns.cfg @@ -0,0 +1,65 @@ +@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() + to:main::@1 +main::@1: scope:[main] from main main::@1 + [5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 ) + [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 + [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 + [8] *((const byte*) main::SCREEN#0+(byte)(number) 1*(number) $28 + (byte) main::i#2) ← (byte) main::$61 + [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 + [10] *((const byte*) main::SCREEN#0+(byte)(number) 2*(number) $28 + (byte) main::i#2) ← (byte~) main::$8 + [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 + [12] *((const byte*) main::SCREEN#0+(byte)(number) 3*(number) $28 + (byte) main::i#2) ← (byte) main::$63 + [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 + [14] *((const byte*) main::SCREEN#0+(byte)(number) 4*(number) $28 + (byte) main::i#2) ← (byte~) main::$14 + [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 + [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 + [17] *((const byte*) main::SCREEN#0+(byte)(number) 5*(number) $28 + (byte) main::i#2) ← (byte~) main::$17 + [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 + [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 + [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 + [21] *((const byte*) main::SCREEN#0+(byte)(number) 6*(number) $28 + (byte) main::i#2) ← (byte~) main::$20 + [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 + [23] *((const byte*) main::SCREEN#0+(word)(number) 7*(number) $28 + (byte) main::i#2) ← (byte) main::$72 + [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 + [25] *((const byte*) main::SCREEN#0+(word)(number) 8*(number) $28 + (byte) main::i#2) ← (byte~) main::$26 + [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 + [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 + [28] *((const byte*) main::SCREEN#0+(word)(number) 9*(number) $28 + (byte) main::i#2) ← (byte~) main::$29 + [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 + [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 + [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 + [32] *((const byte*) main::SCREEN#0+(word)(number) $a*(number) $28 + (byte) main::i#2) ← (byte~) main::$32 + [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 + [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 + [35] *((const byte*) main::SCREEN#0+(word)(number) $b*(number) $28 + (byte) main::i#2) ← (byte~) main::$35 + [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 + [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 + [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 + [39] *((const byte*) main::SCREEN#0+(word)(number) $c*(number) $28 + (byte) main::i#2) ← (byte~) main::$38 + [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 + [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 + [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 + [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 + [44] *((const byte*) main::SCREEN#0+(word)(number) $d*(number) $28 + (byte) main::i#2) ← (byte~) main::$41 + [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 + [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 + [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 + [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 + [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 + [50] *((const byte*) main::SCREEN#0+(word)(number) $e*(number) $28 + (byte) main::i#2) ← (byte~) main::$44 + [51] (byte) main::i#1 ← ++ (byte) main::i#2 + [52] if((byte) main::i#1!=(byte) $12) goto main::@1 + to:main::@return +main::@return: scope:[main] from main::@1 + [53] return + to:@return diff --git a/src/test/ref/multiply-ns.log b/src/test/ref/multiply-ns.log new file mode 100644 index 000000000..4bcc4b2a2 --- /dev/null +++ b/src/test/ref/multiply-ns.log @@ -0,0 +1,1641 @@ +Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400 +Culled Empty Block (label) main::@2 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@1 + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) + (number~) main::$0 ← (number) 0 * (number) $28 + (byte*~) main::$1 ← (byte*) main::SCREEN#0 + (number~) main::$0 + (number~) main::$2 ← (byte) main::i#2 * (number) 1 + *((byte*~) main::$1 + (byte) main::i#2) ← (number~) main::$2 + (number~) main::$3 ← (number) 1 * (number) $28 + (byte*~) main::$4 ← (byte*) main::SCREEN#0 + (number~) main::$3 + (number~) main::$5 ← (byte) main::i#2 * (number) 2 + *((byte*~) main::$4 + (byte) main::i#2) ← (number~) main::$5 + (number~) main::$6 ← (number) 2 * (number) $28 + (byte*~) main::$7 ← (byte*) main::SCREEN#0 + (number~) main::$6 + (number~) main::$8 ← (byte) main::i#2 * (number) 3 + *((byte*~) main::$7 + (byte) main::i#2) ← (number~) main::$8 + (number~) main::$9 ← (number) 3 * (number) $28 + (byte*~) main::$10 ← (byte*) main::SCREEN#0 + (number~) main::$9 + (number~) main::$11 ← (byte) main::i#2 * (number) 4 + *((byte*~) main::$10 + (byte) main::i#2) ← (number~) main::$11 + (number~) main::$12 ← (number) 4 * (number) $28 + (byte*~) main::$13 ← (byte*) main::SCREEN#0 + (number~) main::$12 + (number~) main::$14 ← (byte) main::i#2 * (number) 5 + *((byte*~) main::$13 + (byte) main::i#2) ← (number~) main::$14 + (number~) main::$15 ← (number) 5 * (number) $28 + (byte*~) main::$16 ← (byte*) main::SCREEN#0 + (number~) main::$15 + (number~) main::$17 ← (byte) main::i#2 * (number) 6 + *((byte*~) main::$16 + (byte) main::i#2) ← (number~) main::$17 + (number~) main::$18 ← (number) 6 * (number) $28 + (byte*~) main::$19 ← (byte*) main::SCREEN#0 + (number~) main::$18 + (number~) main::$20 ← (byte) main::i#2 * (number) 7 + *((byte*~) main::$19 + (byte) main::i#2) ← (number~) main::$20 + (number~) main::$21 ← (number) 7 * (number) $28 + (byte*~) main::$22 ← (byte*) main::SCREEN#0 + (number~) main::$21 + (number~) main::$23 ← (byte) main::i#2 * (number) 8 + *((byte*~) main::$22 + (byte) main::i#2) ← (number~) main::$23 + (number~) main::$24 ← (number) 8 * (number) $28 + (byte*~) main::$25 ← (byte*) main::SCREEN#0 + (number~) main::$24 + (number~) main::$26 ← (byte) main::i#2 * (number) 9 + *((byte*~) main::$25 + (byte) main::i#2) ← (number~) main::$26 + (number~) main::$27 ← (number) 9 * (number) $28 + (byte*~) main::$28 ← (byte*) main::SCREEN#0 + (number~) main::$27 + (number~) main::$29 ← (byte) main::i#2 * (number) $a + *((byte*~) main::$28 + (byte) main::i#2) ← (number~) main::$29 + (number~) main::$30 ← (number) $a * (number) $28 + (byte*~) main::$31 ← (byte*) main::SCREEN#0 + (number~) main::$30 + (number~) main::$32 ← (byte) main::i#2 * (number) $b + *((byte*~) main::$31 + (byte) main::i#2) ← (number~) main::$32 + (number~) main::$33 ← (number) $b * (number) $28 + (byte*~) main::$34 ← (byte*) main::SCREEN#0 + (number~) main::$33 + (number~) main::$35 ← (byte) main::i#2 * (number) $c + *((byte*~) main::$34 + (byte) main::i#2) ← (number~) main::$35 + (number~) main::$36 ← (number) $c * (number) $28 + (byte*~) main::$37 ← (byte*) main::SCREEN#0 + (number~) main::$36 + (number~) main::$38 ← (byte) main::i#2 * (number) $d + *((byte*~) main::$37 + (byte) main::i#2) ← (number~) main::$38 + (number~) main::$39 ← (number) $d * (number) $28 + (byte*~) main::$40 ← (byte*) main::SCREEN#0 + (number~) main::$39 + (number~) main::$41 ← (byte) main::i#2 * (number) $e + *((byte*~) main::$40 + (byte) main::i#2) ← (number~) main::$41 + (number~) main::$42 ← (number) $e * (number) $28 + (byte*~) main::$43 ← (byte*) main::SCREEN#0 + (number~) main::$42 + (number~) main::$44 ← (byte) main::i#2 * (number) $f + *((byte*~) main::$43 + (byte) main::i#2) ← (number~) main::$44 + (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$11) + (bool~) main::$45 ← (byte) main::i#1 != rangelast(0,$11) + if((bool~) main::$45) goto main::@1 + to:main::@return +main::@return: scope:[main] from main::@1 + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(void()) main() +(number~) main::$0 +(byte*~) main::$1 +(byte*~) main::$10 +(number~) main::$11 +(number~) main::$12 +(byte*~) main::$13 +(number~) main::$14 +(number~) main::$15 +(byte*~) main::$16 +(number~) main::$17 +(number~) main::$18 +(byte*~) main::$19 +(number~) main::$2 +(number~) main::$20 +(number~) main::$21 +(byte*~) main::$22 +(number~) main::$23 +(number~) main::$24 +(byte*~) main::$25 +(number~) main::$26 +(number~) main::$27 +(byte*~) main::$28 +(number~) main::$29 +(number~) main::$3 +(number~) main::$30 +(byte*~) main::$31 +(number~) main::$32 +(number~) main::$33 +(byte*~) main::$34 +(number~) main::$35 +(number~) main::$36 +(byte*~) main::$37 +(number~) main::$38 +(number~) main::$39 +(byte*~) main::$4 +(byte*~) main::$40 +(number~) main::$41 +(number~) main::$42 +(byte*~) main::$43 +(number~) main::$44 +(bool~) main::$45 +(number~) main::$5 +(number~) main::$6 +(byte*~) main::$7 +(number~) main::$8 +(number~) main::$9 +(label) main::@1 +(label) main::@return +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::i +(byte) main::i#0 +(byte) main::i#1 +(byte) main::i#2 + +Adding number conversion cast (unumber) main::$0 in (byte*~) main::$1 ← (byte*) main::SCREEN#0 + (number~) main::$0 +Adding number conversion cast (unumber) 1 in (number~) main::$2 ← (byte) main::i#2 * (number) 1 +Adding number conversion cast (unumber) main::$2 in (number~) main::$2 ← (byte) main::i#2 * (unumber)(number) 1 +Adding number conversion cast (unumber) main::$3 in (byte*~) main::$4 ← (byte*) main::SCREEN#0 + (number~) main::$3 +Adding number conversion cast (unumber) 2 in (number~) main::$5 ← (byte) main::i#2 * (number) 2 +Adding number conversion cast (unumber) main::$5 in (number~) main::$5 ← (byte) main::i#2 * (unumber)(number) 2 +Adding number conversion cast (unumber) main::$6 in (byte*~) main::$7 ← (byte*) main::SCREEN#0 + (number~) main::$6 +Adding number conversion cast (unumber) 3 in (number~) main::$8 ← (byte) main::i#2 * (number) 3 +Adding number conversion cast (unumber) main::$8 in (number~) main::$8 ← (byte) main::i#2 * (unumber)(number) 3 +Adding number conversion cast (unumber) main::$9 in (byte*~) main::$10 ← (byte*) main::SCREEN#0 + (number~) main::$9 +Adding number conversion cast (unumber) 4 in (number~) main::$11 ← (byte) main::i#2 * (number) 4 +Adding number conversion cast (unumber) main::$11 in (number~) main::$11 ← (byte) main::i#2 * (unumber)(number) 4 +Adding number conversion cast (unumber) main::$12 in (byte*~) main::$13 ← (byte*) main::SCREEN#0 + (number~) main::$12 +Adding number conversion cast (unumber) 5 in (number~) main::$14 ← (byte) main::i#2 * (number) 5 +Adding number conversion cast (unumber) main::$14 in (number~) main::$14 ← (byte) main::i#2 * (unumber)(number) 5 +Adding number conversion cast (unumber) main::$15 in (byte*~) main::$16 ← (byte*) main::SCREEN#0 + (number~) main::$15 +Adding number conversion cast (unumber) 6 in (number~) main::$17 ← (byte) main::i#2 * (number) 6 +Adding number conversion cast (unumber) main::$17 in (number~) main::$17 ← (byte) main::i#2 * (unumber)(number) 6 +Adding number conversion cast (unumber) main::$18 in (byte*~) main::$19 ← (byte*) main::SCREEN#0 + (number~) main::$18 +Adding number conversion cast (unumber) 7 in (number~) main::$20 ← (byte) main::i#2 * (number) 7 +Adding number conversion cast (unumber) main::$20 in (number~) main::$20 ← (byte) main::i#2 * (unumber)(number) 7 +Adding number conversion cast (unumber) main::$21 in (byte*~) main::$22 ← (byte*) main::SCREEN#0 + (number~) main::$21 +Adding number conversion cast (unumber) 8 in (number~) main::$23 ← (byte) main::i#2 * (number) 8 +Adding number conversion cast (unumber) main::$23 in (number~) main::$23 ← (byte) main::i#2 * (unumber)(number) 8 +Adding number conversion cast (unumber) main::$24 in (byte*~) main::$25 ← (byte*) main::SCREEN#0 + (number~) main::$24 +Adding number conversion cast (unumber) 9 in (number~) main::$26 ← (byte) main::i#2 * (number) 9 +Adding number conversion cast (unumber) main::$26 in (number~) main::$26 ← (byte) main::i#2 * (unumber)(number) 9 +Adding number conversion cast (unumber) main::$27 in (byte*~) main::$28 ← (byte*) main::SCREEN#0 + (number~) main::$27 +Adding number conversion cast (unumber) $a in (number~) main::$29 ← (byte) main::i#2 * (number) $a +Adding number conversion cast (unumber) main::$29 in (number~) main::$29 ← (byte) main::i#2 * (unumber)(number) $a +Adding number conversion cast (unumber) main::$30 in (byte*~) main::$31 ← (byte*) main::SCREEN#0 + (number~) main::$30 +Adding number conversion cast (unumber) $b in (number~) main::$32 ← (byte) main::i#2 * (number) $b +Adding number conversion cast (unumber) main::$32 in (number~) main::$32 ← (byte) main::i#2 * (unumber)(number) $b +Adding number conversion cast (unumber) main::$33 in (byte*~) main::$34 ← (byte*) main::SCREEN#0 + (number~) main::$33 +Adding number conversion cast (unumber) $c in (number~) main::$35 ← (byte) main::i#2 * (number) $c +Adding number conversion cast (unumber) main::$35 in (number~) main::$35 ← (byte) main::i#2 * (unumber)(number) $c +Adding number conversion cast (unumber) main::$36 in (byte*~) main::$37 ← (byte*) main::SCREEN#0 + (number~) main::$36 +Adding number conversion cast (unumber) $d in (number~) main::$38 ← (byte) main::i#2 * (number) $d +Adding number conversion cast (unumber) main::$38 in (number~) main::$38 ← (byte) main::i#2 * (unumber)(number) $d +Adding number conversion cast (unumber) main::$39 in (byte*~) main::$40 ← (byte*) main::SCREEN#0 + (number~) main::$39 +Adding number conversion cast (unumber) $e in (number~) main::$41 ← (byte) main::i#2 * (number) $e +Adding number conversion cast (unumber) main::$41 in (number~) main::$41 ← (byte) main::i#2 * (unumber)(number) $e +Adding number conversion cast (unumber) main::$42 in (byte*~) main::$43 ← (byte*) main::SCREEN#0 + (number~) main::$42 +Adding number conversion cast (unumber) $f in (number~) main::$44 ← (byte) main::i#2 * (number) $f +Adding number conversion cast (unumber) main::$44 in (number~) main::$44 ← (byte) main::i#2 * (unumber)(number) $f +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Inlining cast (unumber~) main::$46 ← (unumber)(number~) main::$0 +Inlining cast (unumber~) main::$47 ← (unumber)(number~) main::$3 +Inlining cast (unumber~) main::$48 ← (unumber)(number~) main::$6 +Inlining cast (unumber~) main::$49 ← (unumber)(number~) main::$9 +Inlining cast (unumber~) main::$50 ← (unumber)(number~) main::$12 +Inlining cast (unumber~) main::$51 ← (unumber)(number~) main::$15 +Inlining cast (unumber~) main::$52 ← (unumber)(number~) main::$18 +Inlining cast (unumber~) main::$53 ← (unumber)(number~) main::$21 +Inlining cast (unumber~) main::$54 ← (unumber)(number~) main::$24 +Inlining cast (unumber~) main::$55 ← (unumber)(number~) main::$27 +Inlining cast (unumber~) main::$56 ← (unumber)(number~) main::$30 +Inlining cast (unumber~) main::$57 ← (unumber)(number~) main::$33 +Inlining cast (unumber~) main::$58 ← (unumber)(number~) main::$36 +Inlining cast (unumber~) main::$59 ← (unumber)(number~) main::$39 +Inlining cast (unumber~) main::$60 ← (unumber)(number~) main::$42 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 1 +Simplifying constant integer cast 2 +Simplifying constant integer cast 3 +Simplifying constant integer cast 4 +Simplifying constant integer cast 5 +Simplifying constant integer cast 6 +Simplifying constant integer cast 7 +Simplifying constant integer cast 8 +Simplifying constant integer cast 9 +Simplifying constant integer cast $a +Simplifying constant integer cast $b +Simplifying constant integer cast $c +Simplifying constant integer cast $d +Simplifying constant integer cast $e +Simplifying constant integer cast $f +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 2 +Finalized unsigned number type (byte) 3 +Finalized unsigned number type (byte) 4 +Finalized unsigned number type (byte) 5 +Finalized unsigned number type (byte) 6 +Finalized unsigned number type (byte) 7 +Finalized unsigned number type (byte) 8 +Finalized unsigned number type (byte) 9 +Finalized unsigned number type (byte) $a +Finalized unsigned number type (byte) $b +Finalized unsigned number type (byte) $c +Finalized unsigned number type (byte) $d +Finalized unsigned number type (byte) $e +Finalized unsigned number type (byte) $f +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to byte in (unumber~) main::$2 ← (byte) main::i#2 * (byte) 1 +Inferred type updated to byte in (unumber~) main::$5 ← (byte) main::i#2 * (byte) 2 +Inferred type updated to byte in (unumber~) main::$8 ← (byte) main::i#2 * (byte) 3 +Inferred type updated to byte in (unumber~) main::$11 ← (byte) main::i#2 * (byte) 4 +Inferred type updated to byte in (unumber~) main::$14 ← (byte) main::i#2 * (byte) 5 +Inferred type updated to byte in (unumber~) main::$17 ← (byte) main::i#2 * (byte) 6 +Inferred type updated to byte in (unumber~) main::$20 ← (byte) main::i#2 * (byte) 7 +Inferred type updated to byte in (unumber~) main::$23 ← (byte) main::i#2 * (byte) 8 +Inferred type updated to byte in (unumber~) main::$26 ← (byte) main::i#2 * (byte) 9 +Inferred type updated to byte in (unumber~) main::$29 ← (byte) main::i#2 * (byte) $a +Inferred type updated to byte in (unumber~) main::$32 ← (byte) main::i#2 * (byte) $b +Inferred type updated to byte in (unumber~) main::$35 ← (byte) main::i#2 * (byte) $c +Inferred type updated to byte in (unumber~) main::$38 ← (byte) main::i#2 * (byte) $d +Inferred type updated to byte in (unumber~) main::$41 ← (byte) main::i#2 * (byte) $e +Inferred type updated to byte in (unumber~) main::$44 ← (byte) main::i#2 * (byte) $f +Simple Condition (bool~) main::$45 [80] if((byte) main::i#1!=rangelast(0,$11)) goto main::@1 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [3] (number~) main::$0 ← (number) 0 * (number) $28 +Constant right-side identified [8] (number~) main::$3 ← (number) 1 * (number) $28 +Constant right-side identified [13] (number~) main::$6 ← (number) 2 * (number) $28 +Constant right-side identified [18] (number~) main::$9 ← (number) 3 * (number) $28 +Constant right-side identified [23] (number~) main::$12 ← (number) 4 * (number) $28 +Constant right-side identified [28] (number~) main::$15 ← (number) 5 * (number) $28 +Constant right-side identified [33] (number~) main::$18 ← (number) 6 * (number) $28 +Constant right-side identified [38] (number~) main::$21 ← (number) 7 * (number) $28 +Constant right-side identified [43] (number~) main::$24 ← (number) 8 * (number) $28 +Constant right-side identified [48] (number~) main::$27 ← (number) 9 * (number) $28 +Constant right-side identified [53] (number~) main::$30 ← (number) $a * (number) $28 +Constant right-side identified [58] (number~) main::$33 ← (number) $b * (number) $28 +Constant right-side identified [63] (number~) main::$36 ← (number) $c * (number) $28 +Constant right-side identified [68] (number~) main::$39 ← (number) $d * (number) $28 +Constant right-side identified [73] (number~) main::$42 ← (number) $e * (number) $28 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Constant (const byte) main::i#0 = 0 +Constant (const number) main::$0 = 0*$28 +Constant (const number) main::$3 = 1*$28 +Constant (const number) main::$6 = 2*$28 +Constant (const number) main::$9 = 3*$28 +Constant (const number) main::$12 = 4*$28 +Constant (const number) main::$15 = 5*$28 +Constant (const number) main::$18 = 6*$28 +Constant (const number) main::$21 = 7*$28 +Constant (const number) main::$24 = 8*$28 +Constant (const number) main::$27 = 9*$28 +Constant (const number) main::$30 = $a*$28 +Constant (const number) main::$33 = $b*$28 +Constant (const number) main::$36 = $c*$28 +Constant (const number) main::$39 = $d*$28 +Constant (const number) main::$42 = $e*$28 +Successful SSA optimization Pass2ConstantIdentification +Constant value identified (unumber)main::$0 in [4] (unumber~) main::$46 ← (unumber)(const number) main::$0 +Constant value identified (unumber)main::$3 in [9] (unumber~) main::$47 ← (unumber)(const number) main::$3 +Constant value identified (unumber)main::$6 in [14] (unumber~) main::$48 ← (unumber)(const number) main::$6 +Constant value identified (unumber)main::$9 in [19] (unumber~) main::$49 ← (unumber)(const number) main::$9 +Constant value identified (unumber)main::$12 in [24] (unumber~) main::$50 ← (unumber)(const number) main::$12 +Constant value identified (unumber)main::$15 in [29] (unumber~) main::$51 ← (unumber)(const number) main::$15 +Constant value identified (unumber)main::$18 in [34] (unumber~) main::$52 ← (unumber)(const number) main::$18 +Constant value identified (unumber)main::$21 in [39] (unumber~) main::$53 ← (unumber)(const number) main::$21 +Constant value identified (unumber)main::$24 in [44] (unumber~) main::$54 ← (unumber)(const number) main::$24 +Constant value identified (unumber)main::$27 in [49] (unumber~) main::$55 ← (unumber)(const number) main::$27 +Constant value identified (unumber)main::$30 in [54] (unumber~) main::$56 ← (unumber)(const number) main::$30 +Constant value identified (unumber)main::$33 in [59] (unumber~) main::$57 ← (unumber)(const number) main::$33 +Constant value identified (unumber)main::$36 in [64] (unumber~) main::$58 ← (unumber)(const number) main::$36 +Constant value identified (unumber)main::$39 in [69] (unumber~) main::$59 ← (unumber)(const number) main::$39 +Constant value identified (unumber)main::$42 in [74] (unumber~) main::$60 ← (unumber)(const number) main::$42 +Successful SSA optimization Pass2ConstantValues +Resolved ranged next value [78] main::i#1 ← ++ main::i#2 to ++ +Resolved ranged comparison value [80] if(main::i#1!=rangelast(0,$11)) goto main::@1 to (number) $12 +Simplifying constant evaluating to zero (number) 0*(number) $28 in +Simplifying constant evaluating to zero (unumber)(const number) main::$0 in [4] (unumber~) main::$46 ← (unumber)(const number) main::$0 +Successful SSA optimization PassNSimplifyConstantZero +Eliminating unused constant (const number) main::$0 +Successful SSA optimization PassNEliminateUnusedVars +Adding number conversion cast (unumber) $12 in if((byte) main::i#1!=(number) $12) goto main::@1 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant integer cast $12 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) $12 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Inferred type updated to byte in (unumber~) main::$46 ← (byte) 0 +Constant (const byte) main::$46 = 0 +Constant (const unumber) main::$47 = (unumber)main::$3 +Constant (const unumber) main::$48 = (unumber)main::$6 +Constant (const unumber) main::$49 = (unumber)main::$9 +Constant (const unumber) main::$50 = (unumber)main::$12 +Constant (const unumber) main::$51 = (unumber)main::$15 +Constant (const unumber) main::$52 = (unumber)main::$18 +Constant (const unumber) main::$53 = (unumber)main::$21 +Constant (const unumber) main::$54 = (unumber)main::$24 +Constant (const unumber) main::$55 = (unumber)main::$27 +Constant (const unumber) main::$56 = (unumber)main::$30 +Constant (const unumber) main::$57 = (unumber)main::$33 +Constant (const unumber) main::$58 = (unumber)main::$36 +Constant (const unumber) main::$59 = (unumber)main::$39 +Constant (const unumber) main::$60 = (unumber)main::$42 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero main::SCREEN#0 in [2] (byte*~) main::$1 ← (const byte*) main::SCREEN#0 + (const byte) main::$46 +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant (const byte) main::$46 +Successful SSA optimization PassNEliminateUnusedVars +Simplifying constant integer cast (const unumber) main::$3 +Simplifying constant integer cast (const unumber) main::$6 +Simplifying constant integer cast (const unumber) main::$9 +Simplifying constant integer cast (const unumber) main::$12 +Simplifying constant integer cast (const unumber) main::$15 +Simplifying constant integer cast (const unumber) main::$18 +Simplifying constant integer cast (const unumber) main::$21 +Simplifying constant integer cast (const unumber) main::$24 +Simplifying constant integer cast (const unumber) main::$27 +Simplifying constant integer cast (const unumber) main::$30 +Simplifying constant integer cast (const unumber) main::$33 +Simplifying constant integer cast (const unumber) main::$36 +Simplifying constant integer cast (const unumber) main::$39 +Simplifying constant integer cast (const unumber) main::$42 +Successful SSA optimization PassNCastSimplification +Constant right-side identified [4] (byte*~) main::$4 ← (const byte*) main::SCREEN#0 + (const unumber) main::$47 +Constant right-side identified [7] (byte*~) main::$7 ← (const byte*) main::SCREEN#0 + (const unumber) main::$48 +Constant right-side identified [10] (byte*~) main::$10 ← (const byte*) main::SCREEN#0 + (const unumber) main::$49 +Constant right-side identified [13] (byte*~) main::$13 ← (const byte*) main::SCREEN#0 + (const unumber) main::$50 +Constant right-side identified [16] (byte*~) main::$16 ← (const byte*) main::SCREEN#0 + (const unumber) main::$51 +Constant right-side identified [19] (byte*~) main::$19 ← (const byte*) main::SCREEN#0 + (const unumber) main::$52 +Constant right-side identified [22] (byte*~) main::$22 ← (const byte*) main::SCREEN#0 + (const unumber) main::$53 +Constant right-side identified [25] (byte*~) main::$25 ← (const byte*) main::SCREEN#0 + (const unumber) main::$54 +Constant right-side identified [28] (byte*~) main::$28 ← (const byte*) main::SCREEN#0 + (const unumber) main::$55 +Constant right-side identified [31] (byte*~) main::$31 ← (const byte*) main::SCREEN#0 + (const unumber) main::$56 +Constant right-side identified [34] (byte*~) main::$34 ← (const byte*) main::SCREEN#0 + (const unumber) main::$57 +Constant right-side identified [37] (byte*~) main::$37 ← (const byte*) main::SCREEN#0 + (const unumber) main::$58 +Constant right-side identified [40] (byte*~) main::$40 ← (const byte*) main::SCREEN#0 + (const unumber) main::$59 +Constant right-side identified [43] (byte*~) main::$43 ← (const byte*) main::SCREEN#0 + (const unumber) main::$60 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte*) main::$1 = main::SCREEN#0 +Constant (const byte*) main::$4 = main::SCREEN#0+main::$47 +Constant (const byte*) main::$7 = main::SCREEN#0+main::$48 +Constant (const byte*) main::$10 = main::SCREEN#0+main::$49 +Constant (const byte*) main::$13 = main::SCREEN#0+main::$50 +Constant (const byte*) main::$16 = main::SCREEN#0+main::$51 +Constant (const byte*) main::$19 = main::SCREEN#0+main::$52 +Constant (const byte*) main::$22 = main::SCREEN#0+main::$53 +Constant (const byte*) main::$25 = main::SCREEN#0+main::$54 +Constant (const byte*) main::$28 = main::SCREEN#0+main::$55 +Constant (const byte*) main::$31 = main::SCREEN#0+main::$56 +Constant (const byte*) main::$34 = main::SCREEN#0+main::$57 +Constant (const byte*) main::$37 = main::SCREEN#0+main::$58 +Constant (const byte*) main::$40 = main::SCREEN#0+main::$59 +Constant (const byte*) main::$43 = main::SCREEN#0+main::$60 +Successful SSA optimization Pass2ConstantIdentification +Rewriting multiplication to remove identity multiply/divide [1] (byte~) main::$2 ← (byte) main::i#2 * (byte) 1 +Rewriting multiplication to use shift [3] (byte~) main::$5 ← (byte) main::i#2 * (byte) 2 +Rewriting multiplication to use shift and addition[5] (byte~) main::$8 ← (byte) main::i#2 * (byte) 3 +Rewriting multiplication to use shift [7] (byte~) main::$11 ← (byte) main::i#2 * (byte) 4 +Rewriting multiplication to use shift and addition[9] (byte~) main::$14 ← (byte) main::i#2 * (byte) 5 +Rewriting multiplication to use shift and addition[11] (byte~) main::$17 ← (byte) main::i#2 * (byte) 6 +Rewriting multiplication to use shift and addition[13] (byte~) main::$20 ← (byte) main::i#2 * (byte) 7 +Rewriting multiplication to use shift [15] (byte~) main::$23 ← (byte) main::i#2 * (byte) 8 +Rewriting multiplication to use shift and addition[17] (byte~) main::$26 ← (byte) main::i#2 * (byte) 9 +Rewriting multiplication to use shift and addition[19] (byte~) main::$29 ← (byte) main::i#2 * (byte) $a +Rewriting multiplication to use shift and addition[21] (byte~) main::$32 ← (byte) main::i#2 * (byte) $b +Rewriting multiplication to use shift and addition[23] (byte~) main::$35 ← (byte) main::i#2 * (byte) $c +Rewriting multiplication to use shift and addition[25] (byte~) main::$38 ← (byte) main::i#2 * (byte) $d +Rewriting multiplication to use shift and addition[27] (byte~) main::$41 ← (byte) main::i#2 * (byte) $e +Rewriting multiplication to use shift and addition[29] (byte~) main::$44 ← (byte) main::i#2 * (byte) $f +Successful SSA optimization Pass2MultiplyToShiftRewriting +Inlining constant with var siblings (const byte) main::i#0 +Constant inlined main::$50 = (number) 4*(number) $28 +Constant inlined main::$51 = (number) 5*(number) $28 +Constant inlined main::$12 = (number) 4*(number) $28 +Constant inlined main::$56 = (number) $a*(number) $28 +Constant inlined main::$34 = (const byte*) main::SCREEN#0+(number) $b*(number) $28 +Constant inlined main::$57 = (number) $b*(number) $28 +Constant inlined main::$13 = (const byte*) main::SCREEN#0+(number) 4*(number) $28 +Constant inlined main::$36 = (number) $c*(number) $28 +Constant inlined main::$58 = (number) $c*(number) $28 +Constant inlined main::$15 = (number) 5*(number) $28 +Constant inlined main::$59 = (number) $d*(number) $28 +Constant inlined main::$37 = (const byte*) main::SCREEN#0+(number) $c*(number) $28 +Constant inlined main::$30 = (number) $a*(number) $28 +Constant inlined main::$52 = (number) 6*(number) $28 +Constant inlined main::$53 = (number) 7*(number) $28 +Constant inlined main::$31 = (const byte*) main::SCREEN#0+(number) $a*(number) $28 +Constant inlined main::$54 = (number) 8*(number) $28 +Constant inlined main::$10 = (const byte*) main::SCREEN#0+(number) 3*(number) $28 +Constant inlined main::$33 = (number) $b*(number) $28 +Constant inlined main::$55 = (number) 9*(number) $28 +Constant inlined main::$16 = (const byte*) main::SCREEN#0+(number) 5*(number) $28 +Constant inlined main::$39 = (number) $d*(number) $28 +Constant inlined main::$18 = (number) 6*(number) $28 +Constant inlined main::$19 = (const byte*) main::SCREEN#0+(number) 6*(number) $28 +Constant inlined main::i#0 = (byte) 0 +Constant inlined main::$60 = (number) $e*(number) $28 +Constant inlined main::$40 = (const byte*) main::SCREEN#0+(number) $d*(number) $28 +Constant inlined main::$24 = (number) 8*(number) $28 +Constant inlined main::$47 = (number) 1*(number) $28 +Constant inlined main::$25 = (const byte*) main::SCREEN#0+(number) 8*(number) $28 +Constant inlined main::$48 = (number) 2*(number) $28 +Constant inlined main::$42 = (number) $e*(number) $28 +Constant inlined main::$21 = (number) 7*(number) $28 +Constant inlined main::$43 = (const byte*) main::SCREEN#0+(number) $e*(number) $28 +Constant inlined main::$22 = (const byte*) main::SCREEN#0+(number) 7*(number) $28 +Constant inlined main::$27 = (number) 9*(number) $28 +Constant inlined main::$1 = (const byte*) main::SCREEN#0 +Constant inlined main::$49 = (number) 3*(number) $28 +Constant inlined main::$28 = (const byte*) main::SCREEN#0+(number) 9*(number) $28 +Constant inlined main::$6 = (number) 2*(number) $28 +Constant inlined main::$3 = (number) 1*(number) $28 +Constant inlined main::$4 = (const byte*) main::SCREEN#0+(number) 1*(number) $28 +Constant inlined main::$9 = (number) 3*(number) $28 +Constant inlined main::$7 = (const byte*) main::SCREEN#0+(number) 2*(number) $28 +Successful SSA optimization Pass2ConstantInlining +Adding number conversion cast (unumber) 1*$28 in [4] *((const byte*) main::SCREEN#0+(number) 1*(number) $28 + (byte) main::i#2) ← (byte~) main::$5 +Adding number conversion cast (unumber) 2*$28 in [6] *((const byte*) main::SCREEN#0+(number) 2*(number) $28 + (byte) main::i#2) ← (byte~) main::$8 +Adding number conversion cast (unumber) 3*$28 in [8] *((const byte*) main::SCREEN#0+(number) 3*(number) $28 + (byte) main::i#2) ← (byte~) main::$11 +Adding number conversion cast (unumber) 4*$28 in [10] *((const byte*) main::SCREEN#0+(number) 4*(number) $28 + (byte) main::i#2) ← (byte~) main::$14 +Adding number conversion cast (unumber) 5*$28 in [12] *((const byte*) main::SCREEN#0+(number) 5*(number) $28 + (byte) main::i#2) ← (byte~) main::$17 +Adding number conversion cast (unumber) 6*$28 in [14] *((const byte*) main::SCREEN#0+(number) 6*(number) $28 + (byte) main::i#2) ← (byte~) main::$20 +Adding number conversion cast (unumber) 7*$28 in [16] *((const byte*) main::SCREEN#0+(number) 7*(number) $28 + (byte) main::i#2) ← (byte~) main::$23 +Adding number conversion cast (unumber) 8*$28 in [18] *((const byte*) main::SCREEN#0+(number) 8*(number) $28 + (byte) main::i#2) ← (byte~) main::$26 +Adding number conversion cast (unumber) 9*$28 in [20] *((const byte*) main::SCREEN#0+(number) 9*(number) $28 + (byte) main::i#2) ← (byte~) main::$29 +Adding number conversion cast (unumber) $a*$28 in [22] *((const byte*) main::SCREEN#0+(number) $a*(number) $28 + (byte) main::i#2) ← (byte~) main::$32 +Adding number conversion cast (unumber) $b*$28 in [24] *((const byte*) main::SCREEN#0+(number) $b*(number) $28 + (byte) main::i#2) ← (byte~) main::$35 +Adding number conversion cast (unumber) $c*$28 in [26] *((const byte*) main::SCREEN#0+(number) $c*(number) $28 + (byte) main::i#2) ← (byte~) main::$38 +Adding number conversion cast (unumber) $d*$28 in [28] *((const byte*) main::SCREEN#0+(number) $d*(number) $28 + (byte) main::i#2) ← (byte~) main::$41 +Adding number conversion cast (unumber) $e*$28 in [30] *((const byte*) main::SCREEN#0+(number) $e*(number) $28 + (byte) main::i#2) ← (byte~) main::$44 +Successful SSA optimization PassNAddNumberTypeConversions +Alias (byte) main::i#2 = (byte~) main::$2 +Alias (byte~) main::$8 = (byte) main::$62 +Alias (byte~) main::$14 = (byte) main::$64 +Alias (byte~) main::$17 = (byte) main::$67 +Alias (byte~) main::$20 = (byte) main::$71 +Alias (byte~) main::$26 = (byte) main::$73 +Alias (byte~) main::$29 = (byte) main::$76 +Alias (byte~) main::$32 = (byte) main::$80 +Alias (byte~) main::$35 = (byte) main::$83 +Alias (byte~) main::$38 = (byte) main::$87 +Alias (byte~) main::$41 = (byte) main::$92 +Alias (byte~) main::$44 = (byte) main::$98 +Successful SSA optimization Pass2AliasElimination +Identified duplicate assignment right side [5] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 +Identified duplicate assignment right side [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 +Identified duplicate assignment right side [15] (byte) main::$65 ← (byte) main::i#2 << (byte) 1 +Identified duplicate assignment right side [20] (byte) main::$68 ← (byte) main::i#2 << (byte) 1 +Identified duplicate assignment right side [28] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 +Identified duplicate assignment right side [32] (byte) main::$74 ← (byte) main::i#2 << (byte) 2 +Identified duplicate assignment right side [37] (byte) main::$77 ← (byte) main::i#2 << (byte) 2 +Identified duplicate assignment right side [43] (byte) main::$81 ← (byte) main::i#2 << (byte) 1 +Identified duplicate assignment right side [48] (byte) main::$84 ← (byte) main::i#2 << (byte) 1 +Identified duplicate assignment right side [54] (byte) main::$88 ← (byte) main::i#2 << (byte) 1 +Identified duplicate assignment right side [61] (byte) main::$93 ← (byte) main::i#2 << (byte) 1 +Successful SSA optimization Pass2DuplicateRValueIdentification +Alias (byte) main::$61 = (byte~) main::$5 (byte) main::$65 (byte) main::$68 (byte) main::$81 (byte) main::$84 (byte) main::$88 (byte) main::$93 +Alias (byte) main::$63 = (byte~) main::$11 (byte) main::$74 (byte) main::$77 +Alias (byte) main::$72 = (byte~) main::$23 +Successful SSA optimization Pass2AliasElimination +Added new block during phi lifting main::@3(between main::@1 and main::@1) +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +CALL GRAPH +Calls in [] to main:2 + +Created 1 initial phi equivalence classes +Coalesced [55] main::i#3 ← main::i#1 +Coalesced down to 1 phi equivalence classes +Culled Empty Block (label) @2 +Culled Empty Block (label) main::@3 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + to:main::@1 +main::@1: scope:[main] from main main::@1 + [5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 ) + [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 + [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 + [8] *((const byte*) main::SCREEN#0+(byte)(number) 1*(number) $28 + (byte) main::i#2) ← (byte) main::$61 + [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 + [10] *((const byte*) main::SCREEN#0+(byte)(number) 2*(number) $28 + (byte) main::i#2) ← (byte~) main::$8 + [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 + [12] *((const byte*) main::SCREEN#0+(byte)(number) 3*(number) $28 + (byte) main::i#2) ← (byte) main::$63 + [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 + [14] *((const byte*) main::SCREEN#0+(byte)(number) 4*(number) $28 + (byte) main::i#2) ← (byte~) main::$14 + [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 + [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 + [17] *((const byte*) main::SCREEN#0+(byte)(number) 5*(number) $28 + (byte) main::i#2) ← (byte~) main::$17 + [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 + [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 + [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 + [21] *((const byte*) main::SCREEN#0+(byte)(number) 6*(number) $28 + (byte) main::i#2) ← (byte~) main::$20 + [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 + [23] *((const byte*) main::SCREEN#0+(word)(number) 7*(number) $28 + (byte) main::i#2) ← (byte) main::$72 + [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 + [25] *((const byte*) main::SCREEN#0+(word)(number) 8*(number) $28 + (byte) main::i#2) ← (byte~) main::$26 + [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 + [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 + [28] *((const byte*) main::SCREEN#0+(word)(number) 9*(number) $28 + (byte) main::i#2) ← (byte~) main::$29 + [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 + [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 + [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 + [32] *((const byte*) main::SCREEN#0+(word)(number) $a*(number) $28 + (byte) main::i#2) ← (byte~) main::$32 + [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 + [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 + [35] *((const byte*) main::SCREEN#0+(word)(number) $b*(number) $28 + (byte) main::i#2) ← (byte~) main::$35 + [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 + [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 + [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 + [39] *((const byte*) main::SCREEN#0+(word)(number) $c*(number) $28 + (byte) main::i#2) ← (byte~) main::$38 + [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 + [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 + [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 + [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 + [44] *((const byte*) main::SCREEN#0+(word)(number) $d*(number) $28 + (byte) main::i#2) ← (byte~) main::$41 + [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 + [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 + [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 + [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 + [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 + [50] *((const byte*) main::SCREEN#0+(word)(number) $e*(number) $28 + (byte) main::i#2) ← (byte~) main::$44 + [51] (byte) main::i#1 ← ++ (byte) main::i#2 + [52] if((byte) main::i#1!=(byte) $12) goto main::@1 + to:main::@return +main::@return: scope:[main] from main::@1 + [53] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte~) main::$14 22.0 +(byte~) main::$17 22.0 +(byte~) main::$20 22.0 +(byte~) main::$26 22.0 +(byte~) main::$29 22.0 +(byte~) main::$32 22.0 +(byte~) main::$35 22.0 +(byte~) main::$38 22.0 +(byte~) main::$41 22.0 +(byte~) main::$44 22.0 +(byte) main::$61 2.605263157894737 +(byte) main::$63 3.055555555555556 +(byte) main::$66 22.0 +(byte) main::$69 22.0 +(byte) main::$70 22.0 +(byte) main::$72 16.5 +(byte) main::$75 22.0 +(byte) main::$78 22.0 +(byte) main::$79 22.0 +(byte~) main::$8 22.0 +(byte) main::$82 22.0 +(byte) main::$85 22.0 +(byte) main::$86 22.0 +(byte) main::$89 22.0 +(byte) main::$90 22.0 +(byte) main::$91 22.0 +(byte) main::$94 22.0 +(byte) main::$95 22.0 +(byte) main::$96 22.0 +(byte) main::$97 22.0 +(byte*) main::SCREEN +(byte) main::i +(byte) main::i#1 16.5 +(byte) main::i#2 9.086956521739129 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +Added variable main::$61 to zero page equivalence class [ main::$61 ] +Added variable main::$8 to zero page equivalence class [ main::$8 ] +Added variable main::$63 to zero page equivalence class [ main::$63 ] +Added variable main::$14 to zero page equivalence class [ main::$14 ] +Added variable main::$66 to zero page equivalence class [ main::$66 ] +Added variable main::$17 to zero page equivalence class [ main::$17 ] +Added variable main::$69 to zero page equivalence class [ main::$69 ] +Added variable main::$70 to zero page equivalence class [ main::$70 ] +Added variable main::$20 to zero page equivalence class [ main::$20 ] +Added variable main::$72 to zero page equivalence class [ main::$72 ] +Added variable main::$26 to zero page equivalence class [ main::$26 ] +Added variable main::$75 to zero page equivalence class [ main::$75 ] +Added variable main::$29 to zero page equivalence class [ main::$29 ] +Added variable main::$78 to zero page equivalence class [ main::$78 ] +Added variable main::$79 to zero page equivalence class [ main::$79 ] +Added variable main::$32 to zero page equivalence class [ main::$32 ] +Added variable main::$82 to zero page equivalence class [ main::$82 ] +Added variable main::$35 to zero page equivalence class [ main::$35 ] +Added variable main::$85 to zero page equivalence class [ main::$85 ] +Added variable main::$86 to zero page equivalence class [ main::$86 ] +Added variable main::$38 to zero page equivalence class [ main::$38 ] +Added variable main::$89 to zero page equivalence class [ main::$89 ] +Added variable main::$90 to zero page equivalence class [ main::$90 ] +Added variable main::$91 to zero page equivalence class [ main::$91 ] +Added variable main::$41 to zero page equivalence class [ main::$41 ] +Added variable main::$94 to zero page equivalence class [ main::$94 ] +Added variable main::$95 to zero page equivalence class [ main::$95 ] +Added variable main::$96 to zero page equivalence class [ main::$96 ] +Added variable main::$97 to zero page equivalence class [ main::$97 ] +Added variable main::$44 to zero page equivalence class [ main::$44 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::$61 ] +[ main::$8 ] +[ main::$63 ] +[ main::$14 ] +[ main::$66 ] +[ main::$17 ] +[ main::$69 ] +[ main::$70 ] +[ main::$20 ] +[ main::$72 ] +[ main::$26 ] +[ main::$75 ] +[ main::$29 ] +[ main::$78 ] +[ main::$79 ] +[ main::$32 ] +[ main::$82 ] +[ main::$35 ] +[ main::$85 ] +[ main::$86 ] +[ main::$38 ] +[ main::$89 ] +[ main::$90 ] +[ main::$91 ] +[ main::$41 ] +[ main::$94 ] +[ main::$95 ] +[ main::$96 ] +[ main::$97 ] +[ main::$44 ] +Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Allocated zp ZP_BYTE:3 [ main::$61 ] +Allocated zp ZP_BYTE:4 [ main::$8 ] +Allocated zp ZP_BYTE:5 [ main::$63 ] +Allocated zp ZP_BYTE:6 [ main::$14 ] +Allocated zp ZP_BYTE:7 [ main::$66 ] +Allocated zp ZP_BYTE:8 [ main::$17 ] +Allocated zp ZP_BYTE:9 [ main::$69 ] +Allocated zp ZP_BYTE:10 [ main::$70 ] +Allocated zp ZP_BYTE:11 [ main::$20 ] +Allocated zp ZP_BYTE:12 [ main::$72 ] +Allocated zp ZP_BYTE:13 [ main::$26 ] +Allocated zp ZP_BYTE:14 [ main::$75 ] +Allocated zp ZP_BYTE:15 [ main::$29 ] +Allocated zp ZP_BYTE:16 [ main::$78 ] +Allocated zp ZP_BYTE:17 [ main::$79 ] +Allocated zp ZP_BYTE:18 [ main::$32 ] +Allocated zp ZP_BYTE:19 [ main::$82 ] +Allocated zp ZP_BYTE:20 [ main::$35 ] +Allocated zp ZP_BYTE:21 [ main::$85 ] +Allocated zp ZP_BYTE:22 [ main::$86 ] +Allocated zp ZP_BYTE:23 [ main::$38 ] +Allocated zp ZP_BYTE:24 [ main::$89 ] +Allocated zp ZP_BYTE:25 [ main::$90 ] +Allocated zp ZP_BYTE:26 [ main::$91 ] +Allocated zp ZP_BYTE:27 [ main::$41 ] +Allocated zp ZP_BYTE:28 [ main::$94 ] +Allocated zp ZP_BYTE:29 [ main::$95 ] +Allocated zp ZP_BYTE:30 [ main::$96 ] +Allocated zp ZP_BYTE:31 [ main::$97 ] +Allocated zp ZP_BYTE:32 [ main::$44 ] + +INITIAL ASM +//SEG0 File Comments +// Check that multiplication by constants is converted to shift/add +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label SCREEN = $400 + .label _8 = 4 + .label _14 = 6 + .label _17 = 8 + .label _20 = $b + .label _26 = $d + .label _29 = $f + .label _32 = $12 + .label _35 = $14 + .label _38 = $17 + .label _41 = $1b + .label _44 = $20 + .label i = 2 + .label _61 = 3 + .label _63 = 5 + .label _66 = 7 + .label _69 = 9 + .label _70 = $a + .label _72 = $c + .label _75 = $e + .label _78 = $10 + .label _79 = $11 + .label _82 = $13 + .label _85 = $15 + .label _86 = $16 + .label _89 = $18 + .label _90 = $19 + .label _91 = $1a + .label _94 = $1c + .label _95 = $1d + .label _96 = $1e + .label _97 = $1f + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta i + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz1 + ldy i + tya + sta SCREEN,y + //SEG17 [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda i + asl + sta _61 + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte)(number) 1*(number) $28 + (byte) main::i#2) ← (byte) main::$61 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _61 + ldy i + sta SCREEN+1*$28,y + //SEG19 [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _8 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte)(number) 2*(number) $28 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _8 + ldy i + sta SCREEN+2*$28,y + //SEG21 [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 -- vbuz1=vbuz2_rol_2 + lda i + asl + asl + sta _63 + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte)(number) 3*(number) $28 + (byte) main::i#2) ← (byte) main::$63 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _63 + ldy i + sta SCREEN+3*$28,y + //SEG23 [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _63 + clc + adc i + sta _14 + //SEG24 [14] *((const byte*) main::SCREEN#0+(byte)(number) 4*(number) $28 + (byte) main::i#2) ← (byte~) main::$14 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _14 + ldy i + sta SCREEN+4*$28,y + //SEG25 [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _66 + //SEG26 [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _66 + asl + sta _17 + //SEG27 [17] *((const byte*) main::SCREEN#0+(byte)(number) 5*(number) $28 + (byte) main::i#2) ← (byte~) main::$17 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _17 + ldy i + sta SCREEN+5*$28,y + //SEG28 [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _69 + //SEG29 [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _69 + asl + sta _70 + //SEG30 [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _70 + clc + adc i + sta _20 + //SEG31 [21] *((const byte*) main::SCREEN#0+(byte)(number) 6*(number) $28 + (byte) main::i#2) ← (byte~) main::$20 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _20 + ldy i + sta SCREEN+6*$28,y + //SEG32 [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 -- vbuz1=vbuz2_rol_3 + lda i + asl + asl + asl + sta _72 + //SEG33 [23] *((const byte*) main::SCREEN#0+(word)(number) 7*(number) $28 + (byte) main::i#2) ← (byte) main::$72 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _72 + ldy i + sta SCREEN+7*$28,y + //SEG34 [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _72 + clc + adc i + sta _26 + //SEG35 [25] *((const byte*) main::SCREEN#0+(word)(number) 8*(number) $28 + (byte) main::i#2) ← (byte~) main::$26 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _26 + ldy i + sta SCREEN+8*$28,y + //SEG36 [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _63 + clc + adc i + sta _75 + //SEG37 [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _75 + asl + sta _29 + //SEG38 [28] *((const byte*) main::SCREEN#0+(word)(number) 9*(number) $28 + (byte) main::i#2) ← (byte~) main::$29 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _29 + ldy i + sta SCREEN+9*$28,y + //SEG39 [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _63 + clc + adc i + sta _78 + //SEG40 [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _78 + asl + sta _79 + //SEG41 [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _79 + clc + adc i + sta _32 + //SEG42 [32] *((const byte*) main::SCREEN#0+(word)(number) $a*(number) $28 + (byte) main::i#2) ← (byte~) main::$32 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _32 + ldy i + sta SCREEN+$a*$28,y + //SEG43 [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _82 + //SEG44 [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 -- vbuz1=vbuz2_rol_2 + lda _82 + asl + asl + sta _35 + //SEG45 [35] *((const byte*) main::SCREEN#0+(word)(number) $b*(number) $28 + (byte) main::i#2) ← (byte~) main::$35 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _35 + ldy i + sta SCREEN+$b*$28,y + //SEG46 [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _85 + //SEG47 [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 -- vbuz1=vbuz2_rol_2 + lda _85 + asl + asl + sta _86 + //SEG48 [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _86 + clc + adc i + sta _38 + //SEG49 [39] *((const byte*) main::SCREEN#0+(word)(number) $c*(number) $28 + (byte) main::i#2) ← (byte~) main::$38 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _38 + ldy i + sta SCREEN+$c*$28,y + //SEG50 [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _89 + //SEG51 [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _89 + asl + sta _90 + //SEG52 [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _90 + clc + adc i + sta _91 + //SEG53 [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _91 + asl + sta _41 + //SEG54 [44] *((const byte*) main::SCREEN#0+(word)(number) $d*(number) $28 + (byte) main::i#2) ← (byte~) main::$41 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _41 + ldy i + sta SCREEN+$d*$28,y + //SEG55 [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _61 + clc + adc i + sta _94 + //SEG56 [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _94 + asl + sta _95 + //SEG57 [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _95 + clc + adc i + sta _96 + //SEG58 [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda _96 + asl + sta _97 + //SEG59 [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _97 + clc + adc i + sta _44 + //SEG60 [50] *((const byte*) main::SCREEN#0+(word)(number) $e*(number) $28 + (byte) main::i#2) ← (byte~) main::$44 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _44 + ldy i + sta SCREEN+$e*$28,y + //SEG61 [51] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 + inc i + //SEG62 [52] if((byte) main::i#1!=(byte) $12) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #$12 + cmp i + bne b1_from_b1 + jmp breturn + //SEG63 main::@return + breturn: + //SEG64 [53] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 [ main::i#2 main::$61 ] ( main:2 [ main::i#2 main::$61 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Statement [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$8 ] ( main:2 [ main::i#2 main::$61 main::$8 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::$61 ] +Statement [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 [ main::i#2 main::$61 main::$63 ] ( main:2 [ main::i#2 main::$61 main::$63 ] ) always clobbers reg byte a +Statement [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$14 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$14 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ main::$63 ] +Statement [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$66 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$66 ] ) always clobbers reg byte a +Statement [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 [ main::i#2 main::$61 main::$63 main::$17 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$17 ] ) always clobbers reg byte a +Statement [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$69 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$69 ] ) always clobbers reg byte a +Statement [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 [ main::i#2 main::$61 main::$63 main::$70 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$70 ] ) always clobbers reg byte a +Statement [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$20 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$20 ] ) always clobbers reg byte a +Statement [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 [ main::i#2 main::$61 main::$63 main::$72 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$72 ] ) always clobbers reg byte a +Statement [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$26 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$26 ] ) always clobbers reg byte a +Statement [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$75 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$75 ] ) always clobbers reg byte a +Statement [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 [ main::i#2 main::$61 main::$63 main::$29 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$29 ] ) always clobbers reg byte a +Statement [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 [ main::i#2 main::$61 main::$78 ] ( main:2 [ main::i#2 main::$61 main::$78 ] ) always clobbers reg byte a +Statement [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 [ main::i#2 main::$61 main::$79 ] ( main:2 [ main::i#2 main::$61 main::$79 ] ) always clobbers reg byte a +Statement [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 [ main::i#2 main::$61 main::$32 ] ( main:2 [ main::i#2 main::$61 main::$32 ] ) always clobbers reg byte a +Statement [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$82 ] ( main:2 [ main::i#2 main::$61 main::$82 ] ) always clobbers reg byte a +Statement [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 [ main::i#2 main::$61 main::$35 ] ( main:2 [ main::i#2 main::$61 main::$35 ] ) always clobbers reg byte a +Statement [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$85 ] ( main:2 [ main::i#2 main::$61 main::$85 ] ) always clobbers reg byte a +Statement [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 [ main::i#2 main::$61 main::$86 ] ( main:2 [ main::i#2 main::$61 main::$86 ] ) always clobbers reg byte a +Statement [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 [ main::i#2 main::$61 main::$38 ] ( main:2 [ main::i#2 main::$61 main::$38 ] ) always clobbers reg byte a +Statement [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$89 ] ( main:2 [ main::i#2 main::$61 main::$89 ] ) always clobbers reg byte a +Statement [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 [ main::i#2 main::$61 main::$90 ] ( main:2 [ main::i#2 main::$61 main::$90 ] ) always clobbers reg byte a +Statement [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 [ main::i#2 main::$61 main::$91 ] ( main:2 [ main::i#2 main::$61 main::$91 ] ) always clobbers reg byte a +Statement [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 [ main::i#2 main::$61 main::$41 ] ( main:2 [ main::i#2 main::$61 main::$41 ] ) always clobbers reg byte a +Statement [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$94 ] ( main:2 [ main::i#2 main::$94 ] ) always clobbers reg byte a +Statement [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 [ main::i#2 main::$95 ] ( main:2 [ main::i#2 main::$95 ] ) always clobbers reg byte a +Statement [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 [ main::i#2 main::$96 ] ( main:2 [ main::i#2 main::$96 ] ) always clobbers reg byte a +Statement [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 [ main::i#2 main::$97 ] ( main:2 [ main::i#2 main::$97 ] ) always clobbers reg byte a +Statement [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 [ main::i#2 main::$44 ] ( main:2 [ main::i#2 main::$44 ] ) always clobbers reg byte a +Statement [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a +Statement [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 [ main::i#2 main::$61 ] ( main:2 [ main::i#2 main::$61 ] ) always clobbers reg byte a +Statement [8] *((const byte*) main::SCREEN#0+(byte)(number) 1*(number) $28 + (byte) main::i#2) ← (byte) main::$61 [ main::i#2 main::$61 ] ( main:2 [ main::i#2 main::$61 ] ) always clobbers reg byte a +Statement [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$8 ] ( main:2 [ main::i#2 main::$61 main::$8 ] ) always clobbers reg byte a +Statement [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 [ main::i#2 main::$61 main::$63 ] ( main:2 [ main::i#2 main::$61 main::$63 ] ) always clobbers reg byte a +Statement [12] *((const byte*) main::SCREEN#0+(byte)(number) 3*(number) $28 + (byte) main::i#2) ← (byte) main::$63 [ main::i#2 main::$61 main::$63 ] ( main:2 [ main::i#2 main::$61 main::$63 ] ) always clobbers reg byte a +Statement [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$14 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$14 ] ) always clobbers reg byte a +Statement [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$66 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$66 ] ) always clobbers reg byte a +Statement [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 [ main::i#2 main::$61 main::$63 main::$17 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$17 ] ) always clobbers reg byte a +Statement [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$69 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$69 ] ) always clobbers reg byte a +Statement [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 [ main::i#2 main::$61 main::$63 main::$70 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$70 ] ) always clobbers reg byte a +Statement [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$20 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$20 ] ) always clobbers reg byte a +Statement [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 [ main::i#2 main::$61 main::$63 main::$72 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$72 ] ) always clobbers reg byte a +Statement [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$26 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$26 ] ) always clobbers reg byte a +Statement [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 [ main::i#2 main::$61 main::$63 main::$75 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$75 ] ) always clobbers reg byte a +Statement [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 [ main::i#2 main::$61 main::$63 main::$29 ] ( main:2 [ main::i#2 main::$61 main::$63 main::$29 ] ) always clobbers reg byte a +Statement [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 [ main::i#2 main::$61 main::$78 ] ( main:2 [ main::i#2 main::$61 main::$78 ] ) always clobbers reg byte a +Statement [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 [ main::i#2 main::$61 main::$79 ] ( main:2 [ main::i#2 main::$61 main::$79 ] ) always clobbers reg byte a +Statement [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 [ main::i#2 main::$61 main::$32 ] ( main:2 [ main::i#2 main::$61 main::$32 ] ) always clobbers reg byte a +Statement [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$82 ] ( main:2 [ main::i#2 main::$61 main::$82 ] ) always clobbers reg byte a +Statement [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 [ main::i#2 main::$61 main::$35 ] ( main:2 [ main::i#2 main::$61 main::$35 ] ) always clobbers reg byte a +Statement [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$85 ] ( main:2 [ main::i#2 main::$61 main::$85 ] ) always clobbers reg byte a +Statement [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 [ main::i#2 main::$61 main::$86 ] ( main:2 [ main::i#2 main::$61 main::$86 ] ) always clobbers reg byte a +Statement [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 [ main::i#2 main::$61 main::$38 ] ( main:2 [ main::i#2 main::$61 main::$38 ] ) always clobbers reg byte a +Statement [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$61 main::$89 ] ( main:2 [ main::i#2 main::$61 main::$89 ] ) always clobbers reg byte a +Statement [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 [ main::i#2 main::$61 main::$90 ] ( main:2 [ main::i#2 main::$61 main::$90 ] ) always clobbers reg byte a +Statement [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 [ main::i#2 main::$61 main::$91 ] ( main:2 [ main::i#2 main::$61 main::$91 ] ) always clobbers reg byte a +Statement [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 [ main::i#2 main::$61 main::$41 ] ( main:2 [ main::i#2 main::$61 main::$41 ] ) always clobbers reg byte a +Statement [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 [ main::i#2 main::$94 ] ( main:2 [ main::i#2 main::$94 ] ) always clobbers reg byte a +Statement [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 [ main::i#2 main::$95 ] ( main:2 [ main::i#2 main::$95 ] ) always clobbers reg byte a +Statement [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 [ main::i#2 main::$96 ] ( main:2 [ main::i#2 main::$96 ] ) always clobbers reg byte a +Statement [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 [ main::i#2 main::$97 ] ( main:2 [ main::i#2 main::$97 ] ) always clobbers reg byte a +Statement [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 [ main::i#2 main::$44 ] ( main:2 [ main::i#2 main::$44 ] ) always clobbers reg byte a +Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::$61 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ main::$8 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ main::$63 ] : zp ZP_BYTE:5 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:6 [ main::$14 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:7 [ main::$66 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:8 [ main::$17 ] : zp ZP_BYTE:8 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:9 [ main::$69 ] : zp ZP_BYTE:9 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:10 [ main::$70 ] : zp ZP_BYTE:10 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:11 [ main::$20 ] : zp ZP_BYTE:11 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:12 [ main::$72 ] : zp ZP_BYTE:12 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:13 [ main::$26 ] : zp ZP_BYTE:13 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:14 [ main::$75 ] : zp ZP_BYTE:14 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:15 [ main::$29 ] : zp ZP_BYTE:15 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:16 [ main::$78 ] : zp ZP_BYTE:16 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:17 [ main::$79 ] : zp ZP_BYTE:17 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:18 [ main::$32 ] : zp ZP_BYTE:18 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:19 [ main::$82 ] : zp ZP_BYTE:19 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:20 [ main::$35 ] : zp ZP_BYTE:20 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:21 [ main::$85 ] : zp ZP_BYTE:21 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:22 [ main::$86 ] : zp ZP_BYTE:22 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:23 [ main::$38 ] : zp ZP_BYTE:23 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:24 [ main::$89 ] : zp ZP_BYTE:24 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:25 [ main::$90 ] : zp ZP_BYTE:25 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:26 [ main::$91 ] : zp ZP_BYTE:26 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:27 [ main::$41 ] : zp ZP_BYTE:27 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:28 [ main::$94 ] : zp ZP_BYTE:28 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:29 [ main::$95 ] : zp ZP_BYTE:29 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:30 [ main::$96 ] : zp ZP_BYTE:30 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:31 [ main::$97 ] : zp ZP_BYTE:31 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:32 [ main::$44 ] : zp ZP_BYTE:32 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 25.59: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:4 [ main::$8 ] 22: zp ZP_BYTE:6 [ main::$14 ] 22: zp ZP_BYTE:7 [ main::$66 ] 22: zp ZP_BYTE:8 [ main::$17 ] 22: zp ZP_BYTE:9 [ main::$69 ] 22: zp ZP_BYTE:10 [ main::$70 ] 22: zp ZP_BYTE:11 [ main::$20 ] 22: zp ZP_BYTE:13 [ main::$26 ] 22: zp ZP_BYTE:14 [ main::$75 ] 22: zp ZP_BYTE:15 [ main::$29 ] 22: zp ZP_BYTE:16 [ main::$78 ] 22: zp ZP_BYTE:17 [ main::$79 ] 22: zp ZP_BYTE:18 [ main::$32 ] 22: zp ZP_BYTE:19 [ main::$82 ] 22: zp ZP_BYTE:20 [ main::$35 ] 22: zp ZP_BYTE:21 [ main::$85 ] 22: zp ZP_BYTE:22 [ main::$86 ] 22: zp ZP_BYTE:23 [ main::$38 ] 22: zp ZP_BYTE:24 [ main::$89 ] 22: zp ZP_BYTE:25 [ main::$90 ] 22: zp ZP_BYTE:26 [ main::$91 ] 22: zp ZP_BYTE:27 [ main::$41 ] 22: zp ZP_BYTE:28 [ main::$94 ] 22: zp ZP_BYTE:29 [ main::$95 ] 22: zp ZP_BYTE:30 [ main::$96 ] 22: zp ZP_BYTE:31 [ main::$97 ] 22: zp ZP_BYTE:32 [ main::$44 ] 16.5: zp ZP_BYTE:12 [ main::$72 ] 3.06: zp ZP_BYTE:5 [ main::$63 ] 2.61: zp ZP_BYTE:3 [ main::$61 ] +Uplift Scope [] + +Uplifting [] best 4933 combination +Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Uplifting [main] best 4193 combination reg byte x [ main::i#2 main::i#1 ] +Attempting to uplift remaining variables inzp ZP_BYTE:4 [ main::$8 ] +Uplifting [main] best 4133 combination reg byte a [ main::$8 ] +Attempting to uplift remaining variables inzp ZP_BYTE:6 [ main::$14 ] +Uplifting [main] best 4073 combination reg byte a [ main::$14 ] +Attempting to uplift remaining variables inzp ZP_BYTE:7 [ main::$66 ] +Uplifting [main] best 4013 combination reg byte a [ main::$66 ] +Attempting to uplift remaining variables inzp ZP_BYTE:8 [ main::$17 ] +Uplifting [main] best 3953 combination reg byte a [ main::$17 ] +Attempting to uplift remaining variables inzp ZP_BYTE:9 [ main::$69 ] +Uplifting [main] best 3893 combination reg byte a [ main::$69 ] +Attempting to uplift remaining variables inzp ZP_BYTE:10 [ main::$70 ] +Uplifting [main] best 3873 combination reg byte a [ main::$70 ] +Attempting to uplift remaining variables inzp ZP_BYTE:11 [ main::$20 ] +Uplifting [main] best 3813 combination reg byte a [ main::$20 ] +Attempting to uplift remaining variables inzp ZP_BYTE:13 [ main::$26 ] +Uplifting [main] best 3753 combination reg byte a [ main::$26 ] +Attempting to uplift remaining variables inzp ZP_BYTE:14 [ main::$75 ] +Uplifting [main] best 3693 combination reg byte a [ main::$75 ] +Attempting to uplift remaining variables inzp ZP_BYTE:15 [ main::$29 ] +Uplifting [main] best 3633 combination reg byte a [ main::$29 ] +Attempting to uplift remaining variables inzp ZP_BYTE:16 [ main::$78 ] +Uplifting [main] best 3573 combination reg byte a [ main::$78 ] +Attempting to uplift remaining variables inzp ZP_BYTE:17 [ main::$79 ] +Uplifting [main] best 3553 combination reg byte a [ main::$79 ] +Attempting to uplift remaining variables inzp ZP_BYTE:18 [ main::$32 ] +Uplifting [main] best 3493 combination reg byte a [ main::$32 ] +Attempting to uplift remaining variables inzp ZP_BYTE:19 [ main::$82 ] +Uplifting [main] best 3433 combination reg byte a [ main::$82 ] +Attempting to uplift remaining variables inzp ZP_BYTE:20 [ main::$35 ] +Uplifting [main] best 3373 combination reg byte a [ main::$35 ] +Attempting to uplift remaining variables inzp ZP_BYTE:21 [ main::$85 ] +Uplifting [main] best 3313 combination reg byte a [ main::$85 ] +Attempting to uplift remaining variables inzp ZP_BYTE:22 [ main::$86 ] +Uplifting [main] best 3293 combination reg byte a [ main::$86 ] +Attempting to uplift remaining variables inzp ZP_BYTE:23 [ main::$38 ] +Uplifting [main] best 3233 combination reg byte a [ main::$38 ] +Attempting to uplift remaining variables inzp ZP_BYTE:24 [ main::$89 ] +Uplifting [main] best 3173 combination reg byte a [ main::$89 ] +Attempting to uplift remaining variables inzp ZP_BYTE:25 [ main::$90 ] +Uplifting [main] best 3153 combination reg byte a [ main::$90 ] +Attempting to uplift remaining variables inzp ZP_BYTE:26 [ main::$91 ] +Uplifting [main] best 3093 combination reg byte a [ main::$91 ] +Attempting to uplift remaining variables inzp ZP_BYTE:27 [ main::$41 ] +Uplifting [main] best 3033 combination reg byte a [ main::$41 ] +Attempting to uplift remaining variables inzp ZP_BYTE:28 [ main::$94 ] +Uplifting [main] best 2973 combination reg byte a [ main::$94 ] +Attempting to uplift remaining variables inzp ZP_BYTE:29 [ main::$95 ] +Uplifting [main] best 2953 combination reg byte a [ main::$95 ] +Attempting to uplift remaining variables inzp ZP_BYTE:30 [ main::$96 ] +Uplifting [main] best 2893 combination reg byte a [ main::$96 ] +Attempting to uplift remaining variables inzp ZP_BYTE:31 [ main::$97 ] +Uplifting [main] best 2873 combination reg byte a [ main::$97 ] +Attempting to uplift remaining variables inzp ZP_BYTE:32 [ main::$44 ] +Uplifting [main] best 2813 combination reg byte a [ main::$44 ] +Attempting to uplift remaining variables inzp ZP_BYTE:12 [ main::$72 ] +Uplifting [main] best 2763 combination reg byte a [ main::$72 ] +Attempting to uplift remaining variables inzp ZP_BYTE:5 [ main::$63 ] +Uplifting [main] best 2763 combination zp ZP_BYTE:5 [ main::$63 ] +Attempting to uplift remaining variables inzp ZP_BYTE:3 [ main::$61 ] +Uplifting [main] best 2763 combination zp ZP_BYTE:3 [ main::$61 ] +Allocated (was zp ZP_BYTE:3) zp ZP_BYTE:2 [ main::$61 ] +Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:3 [ main::$63 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Check that multiplication by constants is converted to shift/add +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label SCREEN = $400 + .label _61 = 2 + .label _63 = 3 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + ldx #0 + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx + txa + sta SCREEN,x + //SEG17 [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 -- vbuz1=vbuxx_rol_1 + txa + asl + sta _61 + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte)(number) 1*(number) $28 + (byte) main::i#2) ← (byte) main::$61 -- pbuc1_derefidx_vbuxx=vbuz1 + lda _61 + sta SCREEN+1*$28,x + //SEG19 [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte)(number) 2*(number) $28 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+2*$28,x + //SEG21 [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 -- vbuz1=vbuxx_rol_2 + txa + asl + asl + sta _63 + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte)(number) 3*(number) $28 + (byte) main::i#2) ← (byte) main::$63 -- pbuc1_derefidx_vbuxx=vbuz1 + lda _63 + sta SCREEN+3*$28,x + //SEG23 [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _63 + //SEG24 [14] *((const byte*) main::SCREEN#0+(byte)(number) 4*(number) $28 + (byte) main::i#2) ← (byte~) main::$14 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+4*$28,x + //SEG25 [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG26 [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG27 [17] *((const byte*) main::SCREEN#0+(byte)(number) 5*(number) $28 + (byte) main::i#2) ← (byte~) main::$17 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+5*$28,x + //SEG28 [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG29 [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG30 [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG31 [21] *((const byte*) main::SCREEN#0+(byte)(number) 6*(number) $28 + (byte) main::i#2) ← (byte~) main::$20 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+6*$28,x + //SEG32 [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 -- vbuaa=vbuxx_rol_3 + txa + asl + asl + asl + //SEG33 [23] *((const byte*) main::SCREEN#0+(word)(number) 7*(number) $28 + (byte) main::i#2) ← (byte) main::$72 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+7*$28,x + //SEG34 [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG35 [25] *((const byte*) main::SCREEN#0+(word)(number) 8*(number) $28 + (byte) main::i#2) ← (byte~) main::$26 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+8*$28,x + //SEG36 [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _63 + //SEG37 [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG38 [28] *((const byte*) main::SCREEN#0+(word)(number) 9*(number) $28 + (byte) main::i#2) ← (byte~) main::$29 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+9*$28,x + //SEG39 [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _63 + //SEG40 [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG41 [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG42 [32] *((const byte*) main::SCREEN#0+(word)(number) $a*(number) $28 + (byte) main::i#2) ← (byte~) main::$32 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$a*$28,x + //SEG43 [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG44 [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 -- vbuaa=vbuaa_rol_2 + asl + asl + //SEG45 [35] *((const byte*) main::SCREEN#0+(word)(number) $b*(number) $28 + (byte) main::i#2) ← (byte~) main::$35 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$b*$28,x + //SEG46 [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG47 [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 -- vbuaa=vbuaa_rol_2 + asl + asl + //SEG48 [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG49 [39] *((const byte*) main::SCREEN#0+(word)(number) $c*(number) $28 + (byte) main::i#2) ← (byte~) main::$38 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$c*$28,x + //SEG50 [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG51 [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG52 [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG53 [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG54 [44] *((const byte*) main::SCREEN#0+(word)(number) $d*(number) $28 + (byte) main::i#2) ← (byte~) main::$41 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$d*$28,x + //SEG55 [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG56 [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG57 [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG58 [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG59 [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG60 [50] *((const byte*) main::SCREEN#0+(word)(number) $e*(number) $28 + (byte) main::i#2) ← (byte~) main::$44 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$e*$28,x + //SEG61 [51] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + inx + //SEG62 [52] if((byte) main::i#1!=(byte) $12) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + cpx #$12 + bne b1_from_b1 + jmp breturn + //SEG63 main::@return + breturn: + //SEG64 [53] return + rts +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda _61 +Removing instruction lda _63 +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Replacing label b1_from_b1 with b1 +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction b1_from_main: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction jmp b1 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination +Fixing long branch [102] bne b1 to beq + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(void()) main() +(byte~) main::$14 reg byte a 22.0 +(byte~) main::$17 reg byte a 22.0 +(byte~) main::$20 reg byte a 22.0 +(byte~) main::$26 reg byte a 22.0 +(byte~) main::$29 reg byte a 22.0 +(byte~) main::$32 reg byte a 22.0 +(byte~) main::$35 reg byte a 22.0 +(byte~) main::$38 reg byte a 22.0 +(byte~) main::$41 reg byte a 22.0 +(byte~) main::$44 reg byte a 22.0 +(byte) main::$61 $61 zp ZP_BYTE:2 2.605263157894737 +(byte) main::$63 $63 zp ZP_BYTE:3 3.055555555555556 +(byte) main::$66 reg byte a 22.0 +(byte) main::$69 reg byte a 22.0 +(byte) main::$70 reg byte a 22.0 +(byte) main::$72 reg byte a 16.5 +(byte) main::$75 reg byte a 22.0 +(byte) main::$78 reg byte a 22.0 +(byte) main::$79 reg byte a 22.0 +(byte~) main::$8 reg byte a 22.0 +(byte) main::$82 reg byte a 22.0 +(byte) main::$85 reg byte a 22.0 +(byte) main::$86 reg byte a 22.0 +(byte) main::$89 reg byte a 22.0 +(byte) main::$90 reg byte a 22.0 +(byte) main::$91 reg byte a 22.0 +(byte) main::$94 reg byte a 22.0 +(byte) main::$95 reg byte a 22.0 +(byte) main::$96 reg byte a 22.0 +(byte) main::$97 reg byte a 22.0 +(label) main::@1 +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 9.086956521739129 + +reg byte x [ main::i#2 main::i#1 ] +zp ZP_BYTE:2 [ main::$61 ] +reg byte a [ main::$8 ] +zp ZP_BYTE:3 [ main::$63 ] +reg byte a [ main::$14 ] +reg byte a [ main::$66 ] +reg byte a [ main::$17 ] +reg byte a [ main::$69 ] +reg byte a [ main::$70 ] +reg byte a [ main::$20 ] +reg byte a [ main::$72 ] +reg byte a [ main::$26 ] +reg byte a [ main::$75 ] +reg byte a [ main::$29 ] +reg byte a [ main::$78 ] +reg byte a [ main::$79 ] +reg byte a [ main::$32 ] +reg byte a [ main::$82 ] +reg byte a [ main::$35 ] +reg byte a [ main::$85 ] +reg byte a [ main::$86 ] +reg byte a [ main::$38 ] +reg byte a [ main::$89 ] +reg byte a [ main::$90 ] +reg byte a [ main::$91 ] +reg byte a [ main::$41 ] +reg byte a [ main::$94 ] +reg byte a [ main::$95 ] +reg byte a [ main::$96 ] +reg byte a [ main::$97 ] +reg byte a [ main::$44 ] + + +FINAL ASSEMBLER +Score: 2631 + +//SEG0 File Comments +// Check that multiplication by constants is converted to shift/add +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .label SCREEN = $400 + .label _61 = 2 + .label _63 = 3 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + //SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + ldx #0 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy + //SEG15 main::@1 + b1: + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx + txa + sta SCREEN,x + //SEG17 [7] (byte) main::$61 ← (byte) main::i#2 << (byte) 1 -- vbuz1=vbuxx_rol_1 + txa + asl + sta _61 + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte)(number) 1*(number) $28 + (byte) main::i#2) ← (byte) main::$61 -- pbuc1_derefidx_vbuxx=vbuz1 + sta SCREEN+1*$28,x + //SEG19 [9] (byte~) main::$8 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte)(number) 2*(number) $28 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+2*$28,x + //SEG21 [11] (byte) main::$63 ← (byte) main::i#2 << (byte) 2 -- vbuz1=vbuxx_rol_2 + txa + asl + asl + sta _63 + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte)(number) 3*(number) $28 + (byte) main::i#2) ← (byte) main::$63 -- pbuc1_derefidx_vbuxx=vbuz1 + sta SCREEN+3*$28,x + //SEG23 [13] (byte~) main::$14 ← (byte) main::$63 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _63 + //SEG24 [14] *((const byte*) main::SCREEN#0+(byte)(number) 4*(number) $28 + (byte) main::i#2) ← (byte~) main::$14 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+4*$28,x + //SEG25 [15] (byte) main::$66 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG26 [16] (byte~) main::$17 ← (byte) main::$66 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG27 [17] *((const byte*) main::SCREEN#0+(byte)(number) 5*(number) $28 + (byte) main::i#2) ← (byte~) main::$17 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+5*$28,x + //SEG28 [18] (byte) main::$69 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG29 [19] (byte) main::$70 ← (byte) main::$69 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG30 [20] (byte~) main::$20 ← (byte) main::$70 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG31 [21] *((const byte*) main::SCREEN#0+(byte)(number) 6*(number) $28 + (byte) main::i#2) ← (byte~) main::$20 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+6*$28,x + //SEG32 [22] (byte) main::$72 ← (byte) main::i#2 << (byte) 3 -- vbuaa=vbuxx_rol_3 + txa + asl + asl + asl + //SEG33 [23] *((const byte*) main::SCREEN#0+(word)(number) 7*(number) $28 + (byte) main::i#2) ← (byte) main::$72 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+7*$28,x + //SEG34 [24] (byte~) main::$26 ← (byte) main::$72 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG35 [25] *((const byte*) main::SCREEN#0+(word)(number) 8*(number) $28 + (byte) main::i#2) ← (byte~) main::$26 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+8*$28,x + //SEG36 [26] (byte) main::$75 ← (byte) main::$63 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _63 + //SEG37 [27] (byte~) main::$29 ← (byte) main::$75 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG38 [28] *((const byte*) main::SCREEN#0+(word)(number) 9*(number) $28 + (byte) main::i#2) ← (byte~) main::$29 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+9*$28,x + //SEG39 [29] (byte) main::$78 ← (byte) main::$63 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _63 + //SEG40 [30] (byte) main::$79 ← (byte) main::$78 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG41 [31] (byte~) main::$32 ← (byte) main::$79 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG42 [32] *((const byte*) main::SCREEN#0+(word)(number) $a*(number) $28 + (byte) main::i#2) ← (byte~) main::$32 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$a*$28,x + //SEG43 [33] (byte) main::$82 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG44 [34] (byte~) main::$35 ← (byte) main::$82 << (byte) 2 -- vbuaa=vbuaa_rol_2 + asl + asl + //SEG45 [35] *((const byte*) main::SCREEN#0+(word)(number) $b*(number) $28 + (byte) main::i#2) ← (byte~) main::$35 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$b*$28,x + //SEG46 [36] (byte) main::$85 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG47 [37] (byte) main::$86 ← (byte) main::$85 << (byte) 2 -- vbuaa=vbuaa_rol_2 + asl + asl + //SEG48 [38] (byte~) main::$38 ← (byte) main::$86 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG49 [39] *((const byte*) main::SCREEN#0+(word)(number) $c*(number) $28 + (byte) main::i#2) ← (byte~) main::$38 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$c*$28,x + //SEG50 [40] (byte) main::$89 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG51 [41] (byte) main::$90 ← (byte) main::$89 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG52 [42] (byte) main::$91 ← (byte) main::$90 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG53 [43] (byte~) main::$41 ← (byte) main::$91 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG54 [44] *((const byte*) main::SCREEN#0+(word)(number) $d*(number) $28 + (byte) main::i#2) ← (byte~) main::$41 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$d*$28,x + //SEG55 [45] (byte) main::$94 ← (byte) main::$61 + (byte) main::i#2 -- vbuaa=vbuz1_plus_vbuxx + txa + clc + adc _61 + //SEG56 [46] (byte) main::$95 ← (byte) main::$94 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG57 [47] (byte) main::$96 ← (byte) main::$95 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG58 [48] (byte) main::$97 ← (byte) main::$96 << (byte) 1 -- vbuaa=vbuaa_rol_1 + asl + //SEG59 [49] (byte~) main::$44 ← (byte) main::$97 + (byte) main::i#2 -- vbuaa=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + //SEG60 [50] *((const byte*) main::SCREEN#0+(word)(number) $e*(number) $28 + (byte) main::i#2) ← (byte~) main::$44 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$e*$28,x + //SEG61 [51] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + inx + //SEG62 [52] if((byte) main::i#1!=(byte) $12) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + cpx #$12 + beq !b1+ + jmp b1 + !b1: + //SEG63 main::@return + //SEG64 [53] return + rts +} + diff --git a/src/test/ref/multiply-ns.sym b/src/test/ref/multiply-ns.sym new file mode 100644 index 000000000..ae251e3bf --- /dev/null +++ b/src/test/ref/multiply-ns.sym @@ -0,0 +1,73 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(byte~) main::$14 reg byte a 22.0 +(byte~) main::$17 reg byte a 22.0 +(byte~) main::$20 reg byte a 22.0 +(byte~) main::$26 reg byte a 22.0 +(byte~) main::$29 reg byte a 22.0 +(byte~) main::$32 reg byte a 22.0 +(byte~) main::$35 reg byte a 22.0 +(byte~) main::$38 reg byte a 22.0 +(byte~) main::$41 reg byte a 22.0 +(byte~) main::$44 reg byte a 22.0 +(byte) main::$61 $61 zp ZP_BYTE:2 2.605263157894737 +(byte) main::$63 $63 zp ZP_BYTE:3 3.055555555555556 +(byte) main::$66 reg byte a 22.0 +(byte) main::$69 reg byte a 22.0 +(byte) main::$70 reg byte a 22.0 +(byte) main::$72 reg byte a 16.5 +(byte) main::$75 reg byte a 22.0 +(byte) main::$78 reg byte a 22.0 +(byte) main::$79 reg byte a 22.0 +(byte~) main::$8 reg byte a 22.0 +(byte) main::$82 reg byte a 22.0 +(byte) main::$85 reg byte a 22.0 +(byte) main::$86 reg byte a 22.0 +(byte) main::$89 reg byte a 22.0 +(byte) main::$90 reg byte a 22.0 +(byte) main::$91 reg byte a 22.0 +(byte) main::$94 reg byte a 22.0 +(byte) main::$95 reg byte a 22.0 +(byte) main::$96 reg byte a 22.0 +(byte) main::$97 reg byte a 22.0 +(label) main::@1 +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 9.086956521739129 + +reg byte x [ main::i#2 main::i#1 ] +zp ZP_BYTE:2 [ main::$61 ] +reg byte a [ main::$8 ] +zp ZP_BYTE:3 [ main::$63 ] +reg byte a [ main::$14 ] +reg byte a [ main::$66 ] +reg byte a [ main::$17 ] +reg byte a [ main::$69 ] +reg byte a [ main::$70 ] +reg byte a [ main::$20 ] +reg byte a [ main::$72 ] +reg byte a [ main::$26 ] +reg byte a [ main::$75 ] +reg byte a [ main::$29 ] +reg byte a [ main::$78 ] +reg byte a [ main::$79 ] +reg byte a [ main::$32 ] +reg byte a [ main::$82 ] +reg byte a [ main::$35 ] +reg byte a [ main::$85 ] +reg byte a [ main::$86 ] +reg byte a [ main::$38 ] +reg byte a [ main::$89 ] +reg byte a [ main::$90 ] +reg byte a [ main::$91 ] +reg byte a [ main::$41 ] +reg byte a [ main::$94 ] +reg byte a [ main::$95 ] +reg byte a [ main::$96 ] +reg byte a [ main::$97 ] +reg byte a [ main::$44 ] diff --git a/src/test/ref/struct-ptr-11.asm b/src/test/ref/struct-ptr-11.asm new file mode 100644 index 000000000..c83a1d68a --- /dev/null +++ b/src/test/ref/struct-ptr-11.asm @@ -0,0 +1,51 @@ +// Minimal struct - array of 3-byte structs (required *3) +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_POINT_Z = 2 +main: { + .label SCREEN = $400 + .label _2 = 2 + ldx #0 + b1: + txa + eor #$ff + clc + adc #1 + sta _2 + txa + asl + stx $ff + clc + adc $ff + tay + txa + sta points,y + lda _2 + sta points+OFFSET_STRUCT_POINT_Y,y + txa + sta points+OFFSET_STRUCT_POINT_Z,y + inx + cpx #4 + bne b1 + ldx #0 + b2: + txa + asl + stx $ff + clc + adc $ff + tay + lda points,y + sta SCREEN,y + lda points+OFFSET_STRUCT_POINT_Y,y + sta SCREEN+OFFSET_STRUCT_POINT_Y,y + lda points+OFFSET_STRUCT_POINT_Z,y + sta SCREEN+OFFSET_STRUCT_POINT_Z,y + inx + cpx #4 + bne b2 + rts +} + points: .fill 3*4, 0 diff --git a/src/test/ref/struct-ptr-11.cfg b/src/test/ref/struct-ptr-11.cfg new file mode 100644 index 000000000..f82e44c47 --- /dev/null +++ b/src/test/ref/struct-ptr-11.cfg @@ -0,0 +1,36 @@ +@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() + to:main::@1 +main::@1: scope:[main] from main main::@1 + [5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 ) + [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 + [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 + [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 + [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 + [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 + [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 + [12] (byte) main::i#1 ← ++ (byte) main::i#2 + [13] if((byte) main::i#1!=(byte) 4) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + [14] (byte) main::i1#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::i1#1 ) + [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 + [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 + [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) + [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) + [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) + [20] (byte) main::i1#1 ← ++ (byte) main::i1#2 + [21] if((byte) main::i1#1!=(byte) 4) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@2 + [22] return + to:@return diff --git a/src/test/ref/struct-ptr-11.log b/src/test/ref/struct-ptr-11.log new file mode 100644 index 000000000..3f5eb76d2 --- /dev/null +++ b/src/test/ref/struct-ptr-11.log @@ -0,0 +1,760 @@ +Fixing pointer array-indexing *((struct Point[4]) points + (byte) main::i) +Fixing pointer array-indexing *((struct Point[4]) points + (byte) main::i1) +Fixing pointer array-indexing *((struct Point*) main::SCREEN + (byte) main::i1) +Adding struct value list initializer *((signed byte*) main::$8 + (byte~) main::$6) ← (signed byte~) main::$0 +Adding struct value list initializer *((signed byte*) main::$9 + (byte~) main::$6) ← (signed byte~) main::$2 +Adding struct value list initializer *((signed byte*) main::$10 + (byte~) main::$6) ← (signed byte~) main::$3 +Adding struct value member variable copy *((signed byte*) main::$11 + (byte~) main::$7) ← *((signed byte*) main::$12 + (byte~) main::$7) +Adding struct value member variable copy *((signed byte*) main::$13 + (byte~) main::$7) ← *((signed byte*) main::$14 + (byte~) main::$7) +Adding struct value member variable copy *((signed byte*) main::$15 + (byte~) main::$7) ← *((signed byte*) main::$16 + (byte~) main::$7) +Adding pointer type conversion cast (struct Point*) main::SCREEN in (struct Point*) main::SCREEN ← (number) $400 +Culled Empty Block (label) main::@4 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (struct Point[4]) points#0 ← { fill( 4, 0) } + to:@1 +main: scope:[main] from @1 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@1 + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) + (signed byte~) main::$0 ← ((signed byte)) (byte) main::i#2 + (signed byte~) main::$1 ← ((signed byte)) (byte) main::i#2 + (signed byte~) main::$2 ← - (signed byte~) main::$1 + (signed byte~) main::$3 ← ((signed byte)) (byte) main::i#2 + (byte~) main::$6 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_POINT + (signed byte*) main::$8 ← (signed byte*)(struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_X + *((signed byte*) main::$8 + (byte~) main::$6) ← (signed byte~) main::$0 + (signed byte*) main::$9 ← (signed byte*)(struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Y + *((signed byte*) main::$9 + (byte~) main::$6) ← (signed byte~) main::$2 + (signed byte*) main::$10 ← (signed byte*)(struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Z + *((signed byte*) main::$10 + (byte~) main::$6) ← (signed byte~) main::$3 + (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,3) + (bool~) main::$4 ← (byte) main::i#1 != rangelast(0,3) + if((bool~) main::$4) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@1 + (struct Point*) main::SCREEN#0 ← ((struct Point*)) (number) $400 + (byte) main::i1#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@2 main::@3 + (byte) main::i1#2 ← phi( main::@2/(byte) main::i1#0 main::@3/(byte) main::i1#1 ) + (byte~) main::$7 ← (byte) main::i1#2 * (const byte) SIZEOF_STRUCT_POINT + (signed byte*) main::$11 ← (signed byte*)(struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_X + (signed byte*) main::$12 ← (signed byte*)(struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_X + *((signed byte*) main::$11 + (byte~) main::$7) ← *((signed byte*) main::$12 + (byte~) main::$7) + (signed byte*) main::$13 ← (signed byte*)(struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_Y + (signed byte*) main::$14 ← (signed byte*)(struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Y + *((signed byte*) main::$13 + (byte~) main::$7) ← *((signed byte*) main::$14 + (byte~) main::$7) + (signed byte*) main::$15 ← (signed byte*)(struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_Z + (signed byte*) main::$16 ← (signed byte*)(struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Z + *((signed byte*) main::$15 + (byte~) main::$7) ← *((signed byte*) main::$16 + (byte~) main::$7) + (byte) main::i1#1 ← (byte) main::i1#2 + rangenext(0,3) + (bool~) main::$5 ← (byte) main::i1#1 != rangelast(0,3) + if((bool~) main::$5) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@3 + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_X = (byte) 0 +(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1 +(const byte) OFFSET_STRUCT_POINT_Z = (byte) 2 +(signed byte) Point::x +(signed byte) Point::y +(signed byte) Point::z +(const byte) SIZEOF_STRUCT_POINT = (byte) 3 +(void()) main() +(signed byte~) main::$0 +(signed byte~) main::$1 +(signed byte*) main::$10 +(signed byte*) main::$11 +(signed byte*) main::$12 +(signed byte*) main::$13 +(signed byte*) main::$14 +(signed byte*) main::$15 +(signed byte*) main::$16 +(signed byte~) main::$2 +(signed byte~) main::$3 +(bool~) main::$4 +(bool~) main::$5 +(byte~) main::$6 +(byte~) main::$7 +(signed byte*) main::$8 +(signed byte*) main::$9 +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@return +(struct Point*) main::SCREEN +(struct Point*) main::SCREEN#0 +(byte) main::i +(byte) main::i#0 +(byte) main::i#1 +(byte) main::i#2 +(byte) main::i1 +(byte) main::i1#0 +(byte) main::i1#1 +(byte) main::i1#2 +(struct Point[4]) points +(struct Point[4]) points#0 + +Inlining cast (signed byte~) main::$0 ← (signed byte)(byte) main::i#2 +Inlining cast (signed byte~) main::$1 ← (signed byte)(byte) main::i#2 +Inlining cast (signed byte~) main::$3 ← (signed byte)(byte) main::i#2 +Inlining cast (struct Point*) main::SCREEN#0 ← (struct Point*)(number) $400 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (struct Point*) 1024 +Successful SSA optimization PassNCastSimplification +Simple Condition (bool~) main::$4 [16] if((byte) main::i#1!=rangelast(0,3)) goto main::@1 +Simple Condition (bool~) main::$5 [32] if((byte) main::i1#1!=rangelast(0,3)) goto main::@3 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [0] (struct Point[4]) points#0 ← { fill( 4, 0) } +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const struct Point[4]) points#0 = { fill( 4, 0) } +Constant (const byte) main::i#0 = 0 +Constant (const struct Point*) main::SCREEN#0 = (struct Point*) 1024 +Constant (const byte) main::i1#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Constant value identified (signed byte*)points#0 in [8] (signed byte*) main::$8 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_X +Constant value identified (signed byte*)points#0 in [10] (signed byte*) main::$9 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Y +Constant value identified (signed byte*)points#0 in [12] (signed byte*) main::$10 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Z +Constant value identified (signed byte*)main::SCREEN#0 in [21] (signed byte*) main::$11 ← (signed byte*)(const struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_X +Constant value identified (signed byte*)points#0 in [22] (signed byte*) main::$12 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_X +Constant value identified (signed byte*)main::SCREEN#0 in [24] (signed byte*) main::$13 ← (signed byte*)(const struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_Y +Constant value identified (signed byte*)points#0 in [25] (signed byte*) main::$14 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Y +Constant value identified (signed byte*)main::SCREEN#0 in [27] (signed byte*) main::$15 ← (signed byte*)(const struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_Z +Constant value identified (signed byte*)points#0 in [28] (signed byte*) main::$16 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Z +Successful SSA optimization Pass2ConstantValues +Resolved ranged next value [14] main::i#1 ← ++ main::i#2 to ++ +Resolved ranged comparison value [16] if(main::i#1!=rangelast(0,3)) goto main::@1 to (number) 4 +Resolved ranged next value [30] main::i1#1 ← ++ main::i1#2 to ++ +Resolved ranged comparison value [32] if(main::i1#1!=rangelast(0,3)) goto main::@3 to (number) 4 +Simplifying expression containing zero (signed byte*)points#0 in [8] (signed byte*) main::$8 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_X +Simplifying expression containing zero (signed byte*)main::SCREEN#0 in [21] (signed byte*) main::$11 ← (signed byte*)(const struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_X +Simplifying expression containing zero (signed byte*)points#0 in [22] (signed byte*) main::$12 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_X +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X +Successful SSA optimization PassNEliminateUnusedVars +Adding number conversion cast (unumber) 4 in if((byte) main::i#1!=(number) 4) goto main::@1 +Adding number conversion cast (unumber) 4 in if((byte) main::i1#1!=(number) 4) goto main::@3 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant integer cast 4 +Simplifying constant integer cast 4 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 4 +Finalized unsigned number type (byte) 4 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant right-side identified [8] (signed byte*) main::$9 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Y +Constant right-side identified [10] (signed byte*) main::$10 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Z +Constant right-side identified [19] (signed byte*) main::$13 ← (signed byte*)(const struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_Y +Constant right-side identified [20] (signed byte*) main::$14 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Y +Constant right-side identified [22] (signed byte*) main::$15 ← (signed byte*)(const struct Point*) main::SCREEN#0 + (const byte) OFFSET_STRUCT_POINT_Z +Constant right-side identified [23] (signed byte*) main::$16 ← (signed byte*)(const struct Point[4]) points#0 + (const byte) OFFSET_STRUCT_POINT_Z +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const signed byte*) main::$8 = (signed byte*)points#0 +Constant (const signed byte*) main::$9 = (signed byte*)points#0+OFFSET_STRUCT_POINT_Y +Constant (const signed byte*) main::$10 = (signed byte*)points#0+OFFSET_STRUCT_POINT_Z +Constant (const signed byte*) main::$11 = (signed byte*)main::SCREEN#0 +Constant (const signed byte*) main::$12 = (signed byte*)points#0 +Constant (const signed byte*) main::$13 = (signed byte*)main::SCREEN#0+OFFSET_STRUCT_POINT_Y +Constant (const signed byte*) main::$14 = (signed byte*)points#0+OFFSET_STRUCT_POINT_Y +Constant (const signed byte*) main::$15 = (signed byte*)main::SCREEN#0+OFFSET_STRUCT_POINT_Z +Constant (const signed byte*) main::$16 = (signed byte*)points#0+OFFSET_STRUCT_POINT_Z +Successful SSA optimization Pass2ConstantIdentification +Inlining Noop Cast [1] (signed byte~) main::$0 ← (signed byte)(byte) main::i#2 keeping main::i#2 +Inlining Noop Cast [2] (signed byte~) main::$1 ← (signed byte)(byte) main::i#2 keeping main::i#2 +Inlining Noop Cast [4] (signed byte~) main::$3 ← (signed byte)(byte) main::i#2 keeping main::i#2 +Successful SSA optimization Pass2NopCastInlining +Rewriting multiplication to use shift and addition[5] (byte~) main::$6 ← (byte) main::i#2 * (const byte) SIZEOF_STRUCT_POINT +Rewriting multiplication to use shift and addition[12] (byte~) main::$7 ← (byte) main::i1#2 * (const byte) SIZEOF_STRUCT_POINT +Inlining constant with var siblings (const byte) main::i#0 +Inlining constant with var siblings (const byte) main::i1#0 +Constant inlined main::$16 = (signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z +Constant inlined main::$12 = (signed byte*)(const struct Point[4]) points#0 +Constant inlined main::i#0 = (byte) 0 +Constant inlined main::i1#0 = (byte) 0 +Constant inlined main::$13 = (signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y +Constant inlined main::$14 = (signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y +Constant inlined main::$15 = (signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z +Constant inlined main::$9 = (signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y +Constant inlined main::$10 = (signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z +Constant inlined main::$8 = (signed byte*)(const struct Point[4]) points#0 +Constant inlined main::$11 = (signed byte*)(const struct Point*) main::SCREEN#0 +Successful SSA optimization Pass2ConstantInlining +Alias (byte~) main::$6 = (byte) main::$18 +Alias (byte~) main::$7 = (byte) main::$20 +Successful SSA optimization Pass2AliasElimination +Eliminating unused constant (const byte) SIZEOF_STRUCT_POINT +Successful SSA optimization PassNEliminateUnusedVars +Added new block during phi lifting main::@5(between main::@1 and main::@1) +Added new block during phi lifting main::@6(between main::@3 and main::@3) +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@2 +CALL GRAPH +Calls in [] to main:2 + +Created 2 initial phi equivalence classes +Coalesced [25] main::i1#3 ← main::i1#1 +Coalesced [26] main::i#3 ← main::i#1 +Coalesced down to 2 phi equivalence classes +Culled Empty Block (label) @2 +Culled Empty Block (label) main::@2 +Culled Empty Block (label) main::@6 +Culled Empty Block (label) main::@5 +Renumbering block main::@3 to main::@2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main + +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() + to:main::@1 +main::@1: scope:[main] from main main::@1 + [5] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 ) + [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 + [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 + [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 + [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 + [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 + [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 + [12] (byte) main::i#1 ← ++ (byte) main::i#2 + [13] if((byte) main::i#1!=(byte) 4) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + [14] (byte) main::i1#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::i1#1 ) + [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 + [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 + [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) + [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) + [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) + [20] (byte) main::i1#1 ← ++ (byte) main::i1#2 + [21] if((byte) main::i1#1!=(byte) 4) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@2 + [22] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(signed byte) Point::x +(signed byte) Point::y +(signed byte) Point::z +(void()) main() +(byte) main::$17 22.0 +(byte) main::$19 22.0 +(signed byte~) main::$2 5.5 +(byte~) main::$6 14.666666666666666 +(byte~) main::$7 25.666666666666668 +(struct Point*) main::SCREEN +(byte) main::i +(byte) main::i#1 16.5 +(byte) main::i#2 6.285714285714286 +(byte) main::i1 +(byte) main::i1#1 16.5 +(byte) main::i1#2 7.333333333333333 +(struct Point[4]) points + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ main::i1#2 main::i1#1 ] +Added variable main::$2 to zero page equivalence class [ main::$2 ] +Added variable main::$17 to zero page equivalence class [ main::$17 ] +Added variable main::$6 to zero page equivalence class [ main::$6 ] +Added variable main::$19 to zero page equivalence class [ main::$19 ] +Added variable main::$7 to zero page equivalence class [ main::$7 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::i1#2 main::i1#1 ] +[ main::$2 ] +[ main::$17 ] +[ main::$6 ] +[ main::$19 ] +[ main::$7 ] +Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Allocated zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ] +Allocated zp ZP_BYTE:4 [ main::$2 ] +Allocated zp ZP_BYTE:5 [ main::$17 ] +Allocated zp ZP_BYTE:6 [ main::$6 ] +Allocated zp ZP_BYTE:7 [ main::$19 ] +Allocated zp ZP_BYTE:8 [ main::$7 ] + +INITIAL ASM +//SEG0 File Comments +// Minimal struct - array of 3-byte structs (required *3) +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_POINT_Z = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label SCREEN = $400 + .label _2 = 4 + .label _6 = 6 + .label _7 = 8 + .label i = 2 + .label i1 = 3 + .label _17 = 5 + .label _19 = 7 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta i + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsz2 + lda i + eor #$ff + clc + adc #1 + sta _2 + //SEG17 [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda i + asl + sta _17 + //SEG18 [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _17 + clc + adc i + sta _6 + //SEG19 [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 -- pbsc1_derefidx_vbuz1=vbsz2 + lda i + ldy _6 + sta points,y + //SEG20 [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 -- pbsc1_derefidx_vbuz1=vbsz2 + lda _2 + ldy _6 + sta points+OFFSET_STRUCT_POINT_Y,y + //SEG21 [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 -- pbsc1_derefidx_vbuz1=vbsz2 + lda i + ldy _6 + sta points+OFFSET_STRUCT_POINT_Z,y + //SEG22 [12] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 + inc i + //SEG23 [13] if((byte) main::i#1!=(byte) 4) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #4 + cmp i + bne b1_from_b1 + //SEG24 [14] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + //SEG25 [14] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1 + lda #0 + sta i1 + jmp b2 + //SEG26 [14] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + b2_from_b2: + //SEG27 [14] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy + jmp b2 + //SEG28 main::@2 + b2: + //SEG29 [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda i1 + asl + sta _19 + //SEG30 [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 -- vbuz1=vbuz2_plus_vbuz3 + lda _19 + clc + adc i1 + sta _7 + //SEG31 [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) -- pbsc1_derefidx_vbuz1=pbsc2_derefidx_vbuz1 + ldy _7 + lda points,y + sta SCREEN,y + //SEG32 [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) -- pbsc1_derefidx_vbuz1=pbsc2_derefidx_vbuz1 + ldy _7 + lda points+OFFSET_STRUCT_POINT_Y,y + sta SCREEN+OFFSET_STRUCT_POINT_Y,y + //SEG33 [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) -- pbsc1_derefidx_vbuz1=pbsc2_derefidx_vbuz1 + ldy _7 + lda points+OFFSET_STRUCT_POINT_Z,y + sta SCREEN+OFFSET_STRUCT_POINT_Z,y + //SEG34 [20] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuz1=_inc_vbuz1 + inc i1 + //SEG35 [21] if((byte) main::i1#1!=(byte) 4) goto main::@2 -- vbuz1_neq_vbuc1_then_la1 + lda #4 + cmp i1 + bne b2_from_b2 + jmp breturn + //SEG36 main::@return + breturn: + //SEG37 [22] return + rts +} + points: .fill 3*4, 0 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::$2 ] ( main:2 [ main::i#2 main::$2 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Statement [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 [ main::i#2 main::$2 main::$17 ] ( main:2 [ main::i#2 main::$2 main::$17 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::$2 ] +Statement [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 [ main::i#2 main::$2 main::$6 ] ( main:2 [ main::i#2 main::$2 main::$6 ] ) always clobbers reg byte a +Statement [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 [ main::i#2 main::$2 main::$6 ] ( main:2 [ main::i#2 main::$2 main::$6 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ main::$6 ] +Statement [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 [ main::i#2 main::$6 ] ( main:2 [ main::i#2 main::$6 ] ) always clobbers reg byte a +Statement [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a +Statement [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 [ main::i1#2 main::$19 ] ( main:2 [ main::i1#2 main::$19 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ] +Statement [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 [ main::i1#2 main::$7 ] ( main:2 [ main::i1#2 main::$7 ] ) always clobbers reg byte a +Statement [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) [ main::i1#2 main::$7 ] ( main:2 [ main::i1#2 main::$7 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:8 [ main::$7 ] +Statement [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) [ main::i1#2 main::$7 ] ( main:2 [ main::i1#2 main::$7 ] ) always clobbers reg byte a +Statement [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) [ main::i1#2 ] ( main:2 [ main::i1#2 ] ) always clobbers reg byte a +Statement [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::$2 ] ( main:2 [ main::i#2 main::$2 ] ) always clobbers reg byte a +Statement [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 [ main::i#2 main::$2 main::$17 ] ( main:2 [ main::i#2 main::$2 main::$17 ] ) always clobbers reg byte a +Statement [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 [ main::i#2 main::$2 main::$6 ] ( main:2 [ main::i#2 main::$2 main::$6 ] ) always clobbers reg byte a +Statement [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 [ main::i#2 main::$2 main::$6 ] ( main:2 [ main::i#2 main::$2 main::$6 ] ) always clobbers reg byte a +Statement [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 [ main::i#2 main::$6 ] ( main:2 [ main::i#2 main::$6 ] ) always clobbers reg byte a +Statement [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a +Statement [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 [ main::i1#2 main::$19 ] ( main:2 [ main::i1#2 main::$19 ] ) always clobbers reg byte a +Statement [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 [ main::i1#2 main::$7 ] ( main:2 [ main::i1#2 main::$7 ] ) always clobbers reg byte a +Statement [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) [ main::i1#2 main::$7 ] ( main:2 [ main::i1#2 main::$7 ] ) always clobbers reg byte a +Statement [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) [ main::i1#2 main::$7 ] ( main:2 [ main::i1#2 main::$7 ] ) always clobbers reg byte a +Statement [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) [ main::i1#2 ] ( main:2 [ main::i1#2 ] ) always clobbers reg byte a +Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ main::$2 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ main::$17 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:6 [ main::$6 ] : zp ZP_BYTE:6 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:7 [ main::$19 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:8 [ main::$7 ] : zp ZP_BYTE:8 , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 25.67: zp ZP_BYTE:8 [ main::$7 ] 23.83: zp ZP_BYTE:3 [ main::i1#2 main::i1#1 ] 22.79: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:5 [ main::$17 ] 22: zp ZP_BYTE:7 [ main::$19 ] 14.67: zp ZP_BYTE:6 [ main::$6 ] 5.5: zp ZP_BYTE:4 [ main::$2 ] +Uplift Scope [Point] +Uplift Scope [] + +Uplifting [main] best 1353 combination reg byte y [ main::$7 ] reg byte x [ main::i1#2 main::i1#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$17 ] zp ZP_BYTE:7 [ main::$19 ] zp ZP_BYTE:6 [ main::$6 ] zp ZP_BYTE:4 [ main::$2 ] +Limited combination testing to 100 combinations of 3888 possible. +Uplifting [Point] best 1353 combination +Uplifting [] best 1353 combination +Attempting to uplift remaining variables inzp ZP_BYTE:7 [ main::$19 ] +Uplifting [main] best 1333 combination reg byte a [ main::$19 ] +Attempting to uplift remaining variables inzp ZP_BYTE:6 [ main::$6 ] +Uplifting [main] best 1233 combination reg byte y [ main::$6 ] +Attempting to uplift remaining variables inzp ZP_BYTE:4 [ main::$2 ] +Uplifting [main] best 1233 combination zp ZP_BYTE:4 [ main::$2 ] +Allocated (was zp ZP_BYTE:4) zp ZP_BYTE:2 [ main::$2 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Minimal struct - array of 3-byte structs (required *3) +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_POINT_Z = 2 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label SCREEN = $400 + .label _2 = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + ldx #0 + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsxx + txa + eor #$ff + clc + adc #1 + sta _2 + //SEG17 [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG18 [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 -- vbuyy=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + tay + //SEG19 [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 -- pbsc1_derefidx_vbuyy=vbsxx + txa + sta points,y + //SEG20 [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 -- pbsc1_derefidx_vbuyy=vbsz1 + lda _2 + sta points+OFFSET_STRUCT_POINT_Y,y + //SEG21 [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 -- pbsc1_derefidx_vbuyy=vbsxx + txa + sta points+OFFSET_STRUCT_POINT_Z,y + //SEG22 [12] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + inx + //SEG23 [13] if((byte) main::i#1!=(byte) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + cpx #4 + bne b1_from_b1 + //SEG24 [14] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + //SEG25 [14] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1 + ldx #0 + jmp b2 + //SEG26 [14] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + b2_from_b2: + //SEG27 [14] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy + jmp b2 + //SEG28 main::@2 + b2: + //SEG29 [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG30 [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 -- vbuyy=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + tay + //SEG31 [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) -- pbsc1_derefidx_vbuyy=pbsc2_derefidx_vbuyy + lda points,y + sta SCREEN,y + //SEG32 [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) -- pbsc1_derefidx_vbuyy=pbsc2_derefidx_vbuyy + lda points+OFFSET_STRUCT_POINT_Y,y + sta SCREEN+OFFSET_STRUCT_POINT_Y,y + //SEG33 [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) -- pbsc1_derefidx_vbuyy=pbsc2_derefidx_vbuyy + lda points+OFFSET_STRUCT_POINT_Z,y + sta SCREEN+OFFSET_STRUCT_POINT_Z,y + //SEG34 [20] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuxx=_inc_vbuxx + inx + //SEG35 [21] if((byte) main::i1#1!=(byte) 4) goto main::@2 -- vbuxx_neq_vbuc1_then_la1 + cpx #4 + bne b2_from_b2 + jmp breturn + //SEG36 main::@return + breturn: + //SEG37 [22] return + rts +} + points: .fill 3*4, 0 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing label b1_from_b1 with b1 +Replacing label b2_from_b2 with b2 +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_b1: +Removing instruction b2_from_b2: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction b1_from_main: +Removing instruction b2_from_b1: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction jmp b1 +Removing instruction jmp b2 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_Y OFFSET_STRUCT_POINT_Y = (byte) 1 +(const byte) OFFSET_STRUCT_POINT_Z OFFSET_STRUCT_POINT_Z = (byte) 2 +(signed byte) Point::x +(signed byte) Point::y +(signed byte) Point::z +(void()) main() +(byte) main::$17 reg byte a 22.0 +(byte) main::$19 reg byte a 22.0 +(signed byte~) main::$2 $2 zp ZP_BYTE:2 5.5 +(byte~) main::$6 reg byte y 14.666666666666666 +(byte~) main::$7 reg byte y 25.666666666666668 +(label) main::@1 +(label) main::@2 +(label) main::@return +(struct Point*) main::SCREEN +(const struct Point*) main::SCREEN#0 SCREEN = (struct Point*) 1024 +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 6.285714285714286 +(byte) main::i1 +(byte) main::i1#1 reg byte x 16.5 +(byte) main::i1#2 reg byte x 7.333333333333333 +(struct Point[4]) points +(const struct Point[4]) points#0 points = { fill( 4, 0) } + +reg byte x [ main::i#2 main::i#1 ] +reg byte x [ main::i1#2 main::i1#1 ] +zp ZP_BYTE:2 [ main::$2 ] +reg byte a [ main::$17 ] +reg byte y [ main::$6 ] +reg byte a [ main::$19 ] +reg byte y [ main::$7 ] + + +FINAL ASSEMBLER +Score: 1071 + +//SEG0 File Comments +// Minimal struct - array of 3-byte structs (required *3) +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const OFFSET_STRUCT_POINT_Y = 1 + .const OFFSET_STRUCT_POINT_Z = 2 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .label SCREEN = $400 + .label _2 = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + //SEG12 [5] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + ldx #0 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy + //SEG15 main::@1 + b1: + //SEG16 [6] (signed byte~) main::$2 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsxx + txa + eor #$ff + clc + adc #1 + sta _2 + //SEG17 [7] (byte) main::$17 ← (byte) main::i#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG18 [8] (byte~) main::$6 ← (byte) main::$17 + (byte) main::i#2 -- vbuyy=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + tay + //SEG19 [9] *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$6) ← (signed byte)(byte) main::i#2 -- pbsc1_derefidx_vbuyy=vbsxx + txa + sta points,y + //SEG20 [10] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$6) ← (signed byte~) main::$2 -- pbsc1_derefidx_vbuyy=vbsz1 + lda _2 + sta points+OFFSET_STRUCT_POINT_Y,y + //SEG21 [11] *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$6) ← (signed byte)(byte) main::i#2 -- pbsc1_derefidx_vbuyy=vbsxx + txa + sta points+OFFSET_STRUCT_POINT_Z,y + //SEG22 [12] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + inx + //SEG23 [13] if((byte) main::i#1!=(byte) 4) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + cpx #4 + bne b1 + //SEG24 [14] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG25 [14] phi (byte) main::i1#2 = (byte) 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1 + ldx #0 + //SEG26 [14] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + //SEG27 [14] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@2->main::@2#0] -- register_copy + //SEG28 main::@2 + b2: + //SEG29 [15] (byte) main::$19 ← (byte) main::i1#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG30 [16] (byte~) main::$7 ← (byte) main::$19 + (byte) main::i1#2 -- vbuyy=vbuaa_plus_vbuxx + stx $ff + clc + adc $ff + tay + //SEG31 [17] *((signed byte*)(const struct Point*) main::SCREEN#0 + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0 + (byte~) main::$7) -- pbsc1_derefidx_vbuyy=pbsc2_derefidx_vbuyy + lda points,y + sta SCREEN,y + //SEG32 [18] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Y + (byte~) main::$7) -- pbsc1_derefidx_vbuyy=pbsc2_derefidx_vbuyy + lda points+OFFSET_STRUCT_POINT_Y,y + sta SCREEN+OFFSET_STRUCT_POINT_Y,y + //SEG33 [19] *((signed byte*)(const struct Point*) main::SCREEN#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) ← *((signed byte*)(const struct Point[4]) points#0+(const byte) OFFSET_STRUCT_POINT_Z + (byte~) main::$7) -- pbsc1_derefidx_vbuyy=pbsc2_derefidx_vbuyy + lda points+OFFSET_STRUCT_POINT_Z,y + sta SCREEN+OFFSET_STRUCT_POINT_Z,y + //SEG34 [20] (byte) main::i1#1 ← ++ (byte) main::i1#2 -- vbuxx=_inc_vbuxx + inx + //SEG35 [21] if((byte) main::i1#1!=(byte) 4) goto main::@2 -- vbuxx_neq_vbuc1_then_la1 + cpx #4 + bne b2 + //SEG36 main::@return + //SEG37 [22] return + rts +} + points: .fill 3*4, 0 + diff --git a/src/test/ref/struct-ptr-11.sym b/src/test/ref/struct-ptr-11.sym new file mode 100644 index 000000000..26e0a3e60 --- /dev/null +++ b/src/test/ref/struct-ptr-11.sym @@ -0,0 +1,35 @@ +(label) @1 +(label) @begin +(label) @end +(const byte) OFFSET_STRUCT_POINT_Y OFFSET_STRUCT_POINT_Y = (byte) 1 +(const byte) OFFSET_STRUCT_POINT_Z OFFSET_STRUCT_POINT_Z = (byte) 2 +(signed byte) Point::x +(signed byte) Point::y +(signed byte) Point::z +(void()) main() +(byte) main::$17 reg byte a 22.0 +(byte) main::$19 reg byte a 22.0 +(signed byte~) main::$2 $2 zp ZP_BYTE:2 5.5 +(byte~) main::$6 reg byte y 14.666666666666666 +(byte~) main::$7 reg byte y 25.666666666666668 +(label) main::@1 +(label) main::@2 +(label) main::@return +(struct Point*) main::SCREEN +(const struct Point*) main::SCREEN#0 SCREEN = (struct Point*) 1024 +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 6.285714285714286 +(byte) main::i1 +(byte) main::i1#1 reg byte x 16.5 +(byte) main::i1#2 reg byte x 7.333333333333333 +(struct Point[4]) points +(const struct Point[4]) points#0 points = { fill( 4, 0) } + +reg byte x [ main::i#2 main::i#1 ] +reg byte x [ main::i1#2 main::i1#1 ] +zp ZP_BYTE:2 [ main::$2 ] +reg byte a [ main::$17 ] +reg byte y [ main::$6 ] +reg byte a [ main::$19 ] +reg byte y [ main::$7 ]