From 23d9af8420d878031eaa431252b4bdd532ad8c90 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Wed, 23 Aug 2017 09:37:16 +0200 Subject: [PATCH] Started work on phi transition optimization --- .../kickc/passes/Pass4CodeGeneration.java | 84 +- .../kickc/test/TestCompilationOutput.java | 4 + .../camelot64/kickc/test/ref/bresenhamarr.asm | 47 + .../camelot64/kickc/test/ref/bresenhamarr.cfg | 25 + .../camelot64/kickc/test/ref/bresenhamarr.log | 1805 +++++++++++++++++ .../camelot64/kickc/test/ref/bresenhamarr.sym | 35 + 6 files changed, 1999 insertions(+), 1 deletion(-) create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.asm create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.cfg create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.log create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.sym diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 4566ac0a6..ffcdfddaf 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -10,7 +10,6 @@ import java.util.*; */ public class Pass4CodeGeneration { - private Program program; public Pass4CodeGeneration(Program program) { @@ -215,6 +214,81 @@ public class Pass4CodeGeneration { } } + + /** Keeps track of the phi transitions into blocks during code generation. + * Used to ensure that duplicate transitions are only code generated once. + * Maps to-block label to the transition information*/ + private Map transitions; + + /** + * Keeps track of the phi transitions into a single block during code generation. + * Used to ensure that duplicate transitions are only code generated once. + */ + public static class PhiTransitions { + + /** Label of the to-block. */ + private ControlFlowBlock toBlock; + + /** The phi-block of the to-block. */ + private StatementPhiBlock phiBlock; + + public PhiTransition getTransition(LabelRef fromBlock) { + return null; + } + + + /** + * A single transition into a to-block. + * The transition contains the assignments necessary to enter the to-block from specific from-block(s). + * The transition may be shared between multiple from-blocks, if the assignments are identical. + */ + public class PhiTransition { + + private List fromBlocks; + + private boolean generated; + + public List getAssignments() { + return null; + } + + public boolean isGenerated() { + return generated; + } + + public void setGenerated(boolean generated) { + this.generated = generated; + } + + /** + * Assignment of a single value during a phi transition + */ + public class PhiAssignment { + + private StatementPhiBlock.PhiVariable phiVariable; + + private StatementPhiBlock.PhiRValue phiRValue; + + } + + + } + + } + + + + /** + * Generate a phi block transition. The transition performs all necessary assignment operations when moving from one block to another. + * The transition can be inserted either at the start of the to-block (used for conditional jumps) + * or at the end of the from-block ( used at default block transitions and before JMP/JSR) + * @param asm The ASP program to generate the transition into. + * @param fromBlock The from-block + * @param toBlock The to-block + * @param scope The scope where the ASM code is being inserted. Used to ensure that labels inserted in the code reference the right variables. + * If the transition code is inserted in the to-block, this is the scope of the to-block. + * If the transition code is inserted in the from-block this is the scope of the from-block. + */ private void genBlockPhiTransition(AsmProgram asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock, ScopeRef scope) { Statement toFirstStatement = toBlock.getStatements().get(0); asm.startSegment(toFirstStatement.getIndex(), "[" + toFirstStatement.getIndex() + "]" + " phi from " + fromBlock.getLabel().getFullName() + " to " + toBlock.getLabel().getFullName()); @@ -250,6 +324,14 @@ public class Pass4CodeGeneration { } } + /** + * Generate ASM assigning a value (rValue) to a variable (lValue). + * @param asm The ASM program to generate into + * @param lValue The lValue that should be assigned the value + * @param rValue The rValue to assign to the lValue. + * @param statement The ICL statement that is the cause of the assignment. + * @param scope The scope where the ASM code is being inserted. Used to ensure that labels inserted in the code reference the right variables. + */ private void genAsmMove(AsmProgram asm, LValue lValue, RValue rValue, Statement statement, ScopeRef scope) { asm.startSegment(statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program)); if (isRegisterCopy(lValue, rValue)) { diff --git a/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java b/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java index 3ac56b323..0aeddb4fe 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java +++ b/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java @@ -44,6 +44,10 @@ public class TestCompilationOutput extends TestCase { compileAndCompare("bresenham"); } + public void testBresenhamArr() throws IOException, URISyntaxException { + compileAndCompare("bresenhamarr"); + } + public void testMinus() throws IOException, URISyntaxException { compileAndCompare("minus"); } diff --git a/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.asm b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.asm new file mode 100644 index 000000000..e3733a97c --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.asm @@ -0,0 +1,47 @@ + .label idx = 2 + .label y = 4 + lda #$0 + sta y + ldy #$c + ldx #$0 + lda #$0 + sta idx + lda #$0 + sta idx+$1 +b1: + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 + inx + inc idx + bne !+ + inc idx+$1 +!: + tya + clc + adc #$18 + tay + cpy #$27 + bcc b2 + inc y + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: + tya + sec + sbc #$27 + tay +b2: + cpx #$28 + bcc b1 diff --git a/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.cfg b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.cfg new file mode 100644 index 000000000..e3dbb0c31 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.cfg @@ -0,0 +1,25 @@ +@begin: scope:[] from + to:@1 +@1: scope:[] from @2 @begin + [0] (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [0] (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) 12 ) [ idx#3 x#2 e#3 y#2 ] + [0] (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [0] (word) idx#3 ← phi( @2/(word) idx#5 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] + [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] + [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] + [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] + [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] + to:@3 +@3: scope:[] from @1 + [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] + [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] + [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] + to:@2 +@2: scope:[] from @1 @3 + [9] (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) [ idx#5 x#1 e#5 y#4 ] + [9] (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) [ idx#5 x#1 e#5 y#4 ] + [9] (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) [ idx#5 x#1 e#5 y#4 ] + [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] + to:@end +@end: scope:[] from @2 diff --git a/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.log b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.log new file mode 100644 index 000000000..a5b54c0e8 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.log @@ -0,0 +1,1805 @@ +byte STAR = 81; +byte[40*25] screen = $0400; +byte x0 = 0; +byte y0 = 0; +byte x1 = 39; +byte y1 = 24; +byte xd = x1-x0; +byte yd = y1-y0; +byte x = x0; +byte y = y0; +byte e = yd/2; +word idx = x+y*40; +do { + screen[idx] = STAR; + x = x + 1; + idx = idx + 1; + e = e+yd; + if(xd= (byte) e#1 from (boolean~) $8 ← (byte) xd#1 < (byte) e#1 +Succesful SSA optimization Pass2UnaryNotSimplification +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte~) $0 ← (byte) 39 - (byte) 0 + (byte) xd#0 ← (byte~) $0 + (byte~) $1 ← (byte) 24 - (byte) 0 + (byte) yd#0 ← (byte~) $1 + (byte) x#0 ← (byte) 0 + (byte) y#0 ← (byte) 0 + (byte~) $2 ← (byte) yd#0 / (byte) 2 + (byte) e#0 ← (byte~) $2 + (byte~) $3 ← (byte) y#0 * (byte) 40 + (byte~) $4 ← (byte) x#0 + (byte~) $3 + (word) idx#0 ← (byte~) $4 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#3 ← phi( @2/(byte) y#4 @begin/(byte) y#0 ) + (byte) x1#2 ← phi( @2/(byte) x1#1 @begin/(byte) 39 ) + (byte) xd#1 ← phi( @2/(byte) xd#3 @begin/(byte) xd#0 ) + (byte) yd#1 ← phi( @2/(byte) yd#2 @begin/(byte) yd#0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#3 @begin/(byte) x#0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + (byte[1000]) screen#1 ← phi( @2/(byte[1000]) screen#2 @begin/(word) 1024 ) + (byte) STAR#1 ← phi( @2/(byte) STAR#2 @begin/(byte) 81 ) + *((byte[1000]) screen#1 + (word) idx#3) ← (byte) STAR#1 + (byte~) $5 ← (byte) x#2 + (byte) 1 + (byte) x#1 ← (byte~) $5 + (word~) $6 ← (word) idx#3 + (byte) 1 + (word) idx#1 ← (word~) $6 + (byte~) $7 ← (byte) e#3 + (byte) yd#1 + (byte) e#1 ← (byte~) $7 + (boolean~) $9 ← (byte) xd#1 >= (byte) e#1 + if((boolean~) $9) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#3 @3/(byte) y#1 ) + (byte) xd#3 ← phi( @1/(byte) xd#1 @3/(byte) xd#2 ) + (byte) yd#2 ← phi( @1/(byte) yd#1 @3/(byte) yd#3 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte[1000]) screen#2 ← phi( @1/(byte[1000]) screen#1 @3/(byte[1000]) screen#3 ) + (byte) STAR#2 ← phi( @1/(byte) STAR#1 @3/(byte) STAR#3 ) + (byte) x#3 ← phi( @1/(byte) x#1 @3/(byte) x#4 ) + (byte) x1#1 ← phi( @1/(byte) x1#2 @3/(byte) x1#3 ) + (byte~) $13 ← (byte) x1#1 + (byte) 1 + (boolean~) $14 ← (byte) x#3 < (byte~) $13 + if((boolean~) $14) goto @1 + to:@end +@3: scope:[] from @1 + (byte) yd#3 ← phi( @1/(byte) yd#1 ) + (byte[1000]) screen#3 ← phi( @1/(byte[1000]) screen#1 ) + (byte) STAR#3 ← phi( @1/(byte) STAR#1 ) + (byte) x#4 ← phi( @1/(byte) x#1 ) + (byte) x1#3 ← phi( @1/(byte) x1#2 ) + (byte) xd#2 ← phi( @1/(byte) xd#1 ) + (byte) e#4 ← phi( @1/(byte) e#1 ) + (word) idx#4 ← phi( @1/(word) idx#1 ) + (byte) y#2 ← phi( @1/(byte) y#3 ) + (byte~) $10 ← (byte) y#2 + (byte) 1 + (byte) y#1 ← (byte~) $10 + (word~) $11 ← (word) idx#4 + (byte) 40 + (word) idx#2 ← (word~) $11 + (byte~) $12 ← (byte) e#4 - (byte) xd#2 + (byte) e#2 ← (byte~) $12 + to:@2 +@end: scope:[] from @2 + +Alias (byte) xd#0 = (byte~) $0 +Alias (byte) yd#0 = (byte~) $1 +Alias (byte) e#0 = (byte~) $2 +Alias (word) idx#0 = (byte~) $4 +Alias (byte) x#1 = (byte~) $5 (byte) x#4 +Alias (word) idx#1 = (word~) $6 (word) idx#4 +Alias (byte) e#1 = (byte~) $7 (byte) e#4 +Alias (byte) y#2 = (byte) y#3 +Alias (byte) xd#1 = (byte) xd#2 +Alias (byte) x1#2 = (byte) x1#3 +Alias (byte) STAR#1 = (byte) STAR#3 +Alias (byte[1000]) screen#1 = (byte[1000]) screen#3 +Alias (byte) yd#1 = (byte) yd#3 +Alias (byte) y#1 = (byte~) $10 +Alias (word) idx#2 = (word~) $11 +Alias (byte) e#2 = (byte~) $12 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte) xd#0 ← (byte) 39 - (byte) 0 + (byte) yd#0 ← (byte) 24 - (byte) 0 + (byte) x#0 ← (byte) 0 + (byte) y#0 ← (byte) 0 + (byte) e#0 ← (byte) yd#0 / (byte) 2 + (byte~) $3 ← (byte) y#0 * (byte) 40 + (word) idx#0 ← (byte) x#0 + (byte~) $3 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) y#0 ) + (byte) x1#2 ← phi( @2/(byte) x1#1 @begin/(byte) 39 ) + (byte) xd#1 ← phi( @2/(byte) xd#3 @begin/(byte) xd#0 ) + (byte) yd#1 ← phi( @2/(byte) yd#2 @begin/(byte) yd#0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#3 @begin/(byte) x#0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + (byte[1000]) screen#1 ← phi( @2/(byte[1000]) screen#2 @begin/(word) 1024 ) + (byte) STAR#1 ← phi( @2/(byte) STAR#2 @begin/(byte) 81 ) + *((byte[1000]) screen#1 + (word) idx#3) ← (byte) STAR#1 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) yd#1 + (boolean~) $9 ← (byte) xd#1 >= (byte) e#1 + if((boolean~) $9) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) xd#3 ← phi( @1/(byte) xd#1 @3/(byte) xd#1 ) + (byte) yd#2 ← phi( @1/(byte) yd#1 @3/(byte) yd#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte[1000]) screen#2 ← phi( @1/(byte[1000]) screen#1 @3/(byte[1000]) screen#1 ) + (byte) STAR#2 ← phi( @1/(byte) STAR#1 @3/(byte) STAR#1 ) + (byte) x#3 ← phi( @1/(byte) x#1 @3/(byte) x#1 ) + (byte) x1#1 ← phi( @1/(byte) x1#2 @3/(byte) x1#2 ) + (byte~) $13 ← (byte) x1#1 + (byte) 1 + (boolean~) $14 ← (byte) x#3 < (byte~) $13 + if((boolean~) $14) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) xd#1 + to:@2 +@end: scope:[] from @2 + +Redundant Phi (byte) x1#1 (byte) x1#2 +Redundant Phi (byte) x#3 (byte) x#1 +Redundant Phi (byte) STAR#2 (byte) STAR#1 +Redundant Phi (byte[1000]) screen#2 (byte[1000]) screen#1 +Redundant Phi (byte) yd#2 (byte) yd#1 +Redundant Phi (byte) xd#3 (byte) xd#1 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte) xd#0 ← (byte) 39 - (byte) 0 + (byte) yd#0 ← (byte) 24 - (byte) 0 + (byte) x#0 ← (byte) 0 + (byte) y#0 ← (byte) 0 + (byte) e#0 ← (byte) yd#0 / (byte) 2 + (byte~) $3 ← (byte) y#0 * (byte) 40 + (word) idx#0 ← (byte) x#0 + (byte~) $3 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) y#0 ) + (byte) x1#2 ← phi( @2/(byte) x1#2 @begin/(byte) 39 ) + (byte) xd#1 ← phi( @2/(byte) xd#1 @begin/(byte) xd#0 ) + (byte) yd#1 ← phi( @2/(byte) yd#1 @begin/(byte) yd#0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) x#0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + (byte[1000]) screen#1 ← phi( @2/(byte[1000]) screen#1 @begin/(word) 1024 ) + (byte) STAR#1 ← phi( @2/(byte) STAR#1 @begin/(byte) 81 ) + *((byte[1000]) screen#1 + (word) idx#3) ← (byte) STAR#1 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) yd#1 + (boolean~) $9 ← (byte) xd#1 >= (byte) e#1 + if((boolean~) $9) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte~) $13 ← (byte) x1#2 + (byte) 1 + (boolean~) $14 ← (byte) x#1 < (byte~) $13 + if((boolean~) $14) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) xd#1 + to:@2 +@end: scope:[] from @2 + +Self Phi Eliminated (byte) STAR#1 +Self Phi Eliminated (byte[1000]) screen#1 +Self Phi Eliminated (byte) yd#1 +Self Phi Eliminated (byte) xd#1 +Self Phi Eliminated (byte) x1#2 +Succesful SSA optimization Pass2SelfPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte) xd#0 ← (byte) 39 - (byte) 0 + (byte) yd#0 ← (byte) 24 - (byte) 0 + (byte) x#0 ← (byte) 0 + (byte) y#0 ← (byte) 0 + (byte) e#0 ← (byte) yd#0 / (byte) 2 + (byte~) $3 ← (byte) y#0 * (byte) 40 + (word) idx#0 ← (byte) x#0 + (byte~) $3 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) y#0 ) + (byte) x1#2 ← phi( @begin/(byte) 39 ) + (byte) xd#1 ← phi( @begin/(byte) xd#0 ) + (byte) yd#1 ← phi( @begin/(byte) yd#0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) x#0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + (byte[1000]) screen#1 ← phi( @begin/(word) 1024 ) + (byte) STAR#1 ← phi( @begin/(byte) 81 ) + *((byte[1000]) screen#1 + (word) idx#3) ← (byte) STAR#1 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) yd#1 + (boolean~) $9 ← (byte) xd#1 >= (byte) e#1 + if((boolean~) $9) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte~) $13 ← (byte) x1#2 + (byte) 1 + (boolean~) $14 ← (byte) x#1 < (byte~) $13 + if((boolean~) $14) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) xd#1 + to:@2 +@end: scope:[] from @2 + +Simple Condition (boolean~) $9 if((byte) xd#1>=(byte) e#1) goto @2 +Simple Condition (boolean~) $14 if((byte) x#1<(byte~) $13) goto @1 +Succesful SSA optimization Pass2ConditionalJumpSimplification +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte) xd#0 ← (byte) 39 - (byte) 0 + (byte) yd#0 ← (byte) 24 - (byte) 0 + (byte) x#0 ← (byte) 0 + (byte) y#0 ← (byte) 0 + (byte) e#0 ← (byte) yd#0 / (byte) 2 + (byte~) $3 ← (byte) y#0 * (byte) 40 + (word) idx#0 ← (byte) x#0 + (byte~) $3 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) y#0 ) + (byte) x1#2 ← phi( @begin/(byte) 39 ) + (byte) xd#1 ← phi( @begin/(byte) xd#0 ) + (byte) yd#1 ← phi( @begin/(byte) yd#0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) x#0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + (byte[1000]) screen#1 ← phi( @begin/(word) 1024 ) + (byte) STAR#1 ← phi( @begin/(byte) 81 ) + *((byte[1000]) screen#1 + (word) idx#3) ← (byte) STAR#1 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) yd#1 + if((byte) xd#1>=(byte) e#1) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte~) $13 ← (byte) x1#2 + (byte) 1 + if((byte) x#1<(byte~) $13) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) xd#1 + to:@2 +@end: scope:[] from @2 + +Constant (byte) xd#0 (byte) 39 +Constant (byte) yd#0 (byte) 24 +Constant (byte) x#0 (byte) 0 +Constant (byte) y#0 (byte) 0 +Constant (byte) STAR#1 (byte) 81 +Constant (byte[1000]) screen#1 (word) 1024 +Constant (byte) x1#2 (byte) 39 +Succesful SSA optimization Pass2ConstantPropagation +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte) e#0 ← (byte) 24 / (byte) 2 + (byte~) $3 ← (byte) 0 * (byte) 40 + (word) idx#0 ← (byte) 0 + (byte~) $3 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) + (byte) xd#1 ← phi( @begin/(byte) 39 ) + (byte) yd#1 ← phi( @begin/(byte) 24 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + *((word) 1024 + (word) idx#3) ← (byte) 81 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) yd#1 + if((byte) xd#1>=(byte) e#1) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte~) $13 ← (byte) 39 + (byte) 1 + if((byte) x#1<(byte~) $13) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) xd#1 + to:@2 +@end: scope:[] from @2 + +Multiple usages for variable. Not optimizing sub-constant (byte) y#2 +Multiple usages for variable. Not optimizing sub-constant (word) idx#1 +Redundant Phi (byte) yd#1 (byte) 24 +Redundant Phi (byte) xd#1 (byte) 39 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte) e#0 ← (byte) 24 / (byte) 2 + (byte~) $3 ← (byte) 0 * (byte) 40 + (word) idx#0 ← (byte) 0 + (byte~) $3 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) e#0 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + *((word) 1024 + (word) idx#3) ← (byte) 81 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) 24 + if((byte) 39>=(byte) e#1) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + (byte~) $13 ← (byte) 39 + (byte) 1 + if((byte) x#1<(byte~) $13) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) 39 + to:@2 +@end: scope:[] from @2 + +Constant (byte) e#0 (byte) 12 +Constant (byte~) $3 (byte) 0 +Constant (byte~) $13 (byte) 40 +Succesful SSA optimization Pass2ConstantPropagation +CONTROL FLOW GRAPH +@begin: scope:[] from + (word) idx#0 ← (byte) 0 + (byte) 0 + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) 12 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(word) idx#0 ) + *((word) 1024 + (word) idx#3) ← (byte) 81 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) 24 + if((byte) 39>=(byte) e#1) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + if((byte) x#1<(byte) 40) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) 39 + to:@2 +@end: scope:[] from @2 + +Multiple usages for variable. Not optimizing sub-constant (byte) y#2 +Multiple usages for variable. Not optimizing sub-constant (word) idx#1 +Constant (word) idx#0 (byte) 0 +Succesful SSA optimization Pass2ConstantPropagation +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +@1: scope:[] from @2 @begin + (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) + (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) 12 ) + (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) + (word) idx#3 ← phi( @2/(word) idx#5 @begin/(byte) 0 ) + *((word) 1024 + (word) idx#3) ← (byte) 81 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) 24 + if((byte) 39>=(byte) e#1) goto @2 + to:@3 +@2: scope:[] from @1 @3 + (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) + (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) + (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) + if((byte) x#1<(byte) 40) goto @1 + to:@end +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) 39 + to:@2 +@end: scope:[] from @2 + +Multiple usages for variable. Not optimizing sub-constant (byte) y#2 +Multiple usages for variable. Not optimizing sub-constant (word) idx#1 +Multiple usages for variable. Not optimizing sub-constant (byte) y#2 +Multiple usages for variable. Not optimizing sub-constant (word) idx#1 +FINAL SYMBOL TABLE +(label) @1 +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte) STAR +(byte) e +(byte) e#1 +(byte) e#2 +(byte) e#3 +(byte) e#5 +(word) idx +(word) idx#1 +(word) idx#2 +(word) idx#3 +(word) idx#5 +(byte[1000]) screen +(byte) x +(byte) x#1 +(byte) x#2 +(byte) x0 +(byte) x1 +(byte) xd +(byte) y +(byte) y#1 +(byte) y#2 +(byte) y#4 +(byte) y0 +(byte) y1 +(byte) yd + +Block Sequence Planned @begin @1 @3 @2 @end +Added new block during phi lifting @5(between @2 and @1) +Added new block during phi lifting @6(between @1 and @2) +Block Sequence Planned @begin @1 @3 @2 @end @5 @6 +CONTROL FLOW GRAPH - PHI LIFTED +@begin: scope:[] from + to:@1 +@1: scope:[] from @5 @begin + (byte) y#2 ← phi( @5/(byte~) y#5 @begin/(byte) 0 ) + (byte) e#3 ← phi( @5/(byte~) e#6 @begin/(byte) 12 ) + (byte) x#2 ← phi( @5/(byte~) x#5 @begin/(byte) 0 ) + (word) idx#3 ← phi( @5/(word~) idx#6 @begin/(byte) 0 ) + *((word) 1024 + (word) idx#3) ← (byte) 81 + (byte) x#1 ← (byte) x#2 + (byte) 1 + (word) idx#1 ← (word) idx#3 + (byte) 1 + (byte) e#1 ← (byte) e#3 + (byte) 24 + if((byte) 39>=(byte) e#1) goto @6 + to:@3 +@3: scope:[] from @1 + (byte) y#1 ← (byte) y#2 + (byte) 1 + (word) idx#2 ← (word) idx#1 + (byte) 40 + (byte) e#2 ← (byte) e#1 - (byte) 39 + (word~) idx#8 ← (word) idx#2 + (byte~) e#8 ← (byte) e#2 + (byte~) y#7 ← (byte) y#1 + to:@2 +@2: scope:[] from @3 @6 + (byte) y#4 ← phi( @6/(byte~) y#6 @3/(byte~) y#7 ) + (byte) e#5 ← phi( @6/(byte~) e#7 @3/(byte~) e#8 ) + (word) idx#5 ← phi( @6/(word~) idx#7 @3/(word~) idx#8 ) + if((byte) x#1<(byte) 40) goto @5 + to:@end +@end: scope:[] from @2 +@5: scope:[] from @2 + (word~) idx#6 ← (word) idx#5 + (byte~) x#5 ← (byte) x#1 + (byte~) e#6 ← (byte) e#5 + (byte~) y#5 ← (byte) y#4 + to:@1 +@6: scope:[] from @1 + (word~) idx#7 ← (word) idx#1 + (byte~) e#7 ← (byte) e#1 + (byte~) y#6 ← (byte) y#2 + to:@2 + +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - LIVE RANGES +@begin: scope:[] from + to:@1 +@1: scope:[] from @5 @begin + [0] (byte) y#2 ← phi( @5/(byte~) y#5 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [0] (byte) e#3 ← phi( @5/(byte~) e#6 @begin/(byte) 12 ) [ idx#3 x#2 e#3 y#2 ] + [0] (byte) x#2 ← phi( @5/(byte~) x#5 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [0] (word) idx#3 ← phi( @5/(word~) idx#6 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] + [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ idx#3 e#3 y#2 x#1 ] + [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ e#3 y#2 idx#1 x#1 ] + [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ e#1 y#2 idx#1 x#1 ] + [5] if((byte) 39>=(byte) e#1) goto @6 [ e#1 y#2 idx#1 x#1 ] + to:@3 +@3: scope:[] from @1 + [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ e#1 idx#1 y#1 x#1 ] + [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ e#1 idx#2 y#1 x#1 ] + [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ idx#2 e#2 y#1 x#1 ] + [9] (word~) idx#8 ← (word) idx#2 [ e#2 y#1 idx#8 x#1 ] + [10] (byte~) e#8 ← (byte) e#2 [ y#1 idx#8 e#8 x#1 ] + [11] (byte~) y#7 ← (byte) y#1 [ idx#8 e#8 y#7 x#1 ] + to:@2 +@2: scope:[] from @3 @6 + [12] (byte) y#4 ← phi( @6/(byte~) y#6 @3/(byte~) y#7 ) [ x#1 idx#5 e#5 y#4 ] + [12] (byte) e#5 ← phi( @6/(byte~) e#7 @3/(byte~) e#8 ) [ x#1 idx#5 e#5 y#4 ] + [12] (word) idx#5 ← phi( @6/(word~) idx#7 @3/(word~) idx#8 ) [ x#1 idx#5 e#5 y#4 ] + [13] if((byte) x#1<(byte) 40) goto @5 [ x#1 idx#5 e#5 y#4 ] + to:@end +@end: scope:[] from @2 +@5: scope:[] from @2 + [14] (word~) idx#6 ← (word) idx#5 [ idx#6 x#1 e#5 y#4 ] + [15] (byte~) x#5 ← (byte) x#1 [ idx#6 x#5 e#5 y#4 ] + [16] (byte~) e#6 ← (byte) e#5 [ idx#6 x#5 e#6 y#4 ] + [17] (byte~) y#5 ← (byte) y#4 [ idx#6 x#5 e#6 y#5 ] + to:@1 +@6: scope:[] from @1 + [18] (word~) idx#7 ← (word) idx#1 [ e#1 y#2 idx#7 x#1 ] + [19] (byte~) e#7 ← (byte) e#1 [ y#2 idx#7 e#7 x#1 ] + [20] (byte~) y#6 ← (byte) y#2 [ idx#7 e#7 y#6 x#1 ] + to:@2 + +Created 7 initial phi equivalence classes +Coalesced [9] idx#8 ← idx#2 +Coalesced [10] e#8 ← e#2 +Coalesced [11] y#7 ← y#1 +Coalesced [14] idx#6 ← idx#5 +Coalesced [15] x#5 ← x#1 +Coalesced [16] e#6 ← e#5 +Coalesced [17] y#5 ← y#4 +Coalesced [18] idx#7 ← idx#1 +Coalesced [19] e#7 ← e#1 +Coalesced (already) [20] y#6 ← y#2 +Coalesced down to 4 phi equivalence classes +Culled Empty Block (label) @5 +Culled Empty Block (label) @6 +Block Sequence Planned @begin @1 @3 @2 @end +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - PHI MEM COALESCED +@begin: scope:[] from + to:@1 +@1: scope:[] from @2 @begin + [0] (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [0] (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) 12 ) [ idx#3 x#2 e#3 y#2 ] + [0] (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [0] (word) idx#3 ← phi( @2/(word) idx#5 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ] + [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] + [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] + [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] + [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] + [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] + to:@3 +@3: scope:[] from @1 + [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] + [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] + [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] + to:@2 +@2: scope:[] from @1 @3 + [9] (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) [ idx#5 x#1 e#5 y#4 ] + [9] (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) [ idx#5 x#1 e#5 y#4 ] + [9] (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) [ idx#5 x#1 e#5 y#4 ] + [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] + to:@end +@end: scope:[] from @2 + +CALL GRAPH + +DOMINATORS +@begin dominated by @begin +@1 dominated by @1 @begin +@3 dominated by @1 @3 @begin +@2 dominated by @1 @2 @begin +@end dominated by @1 @2 @end @begin + +Found back edge: Loop head: @1 tails: @2 blocks: null +Populated: Loop head: @1 tails: @2 blocks: @2 @1 @3 +NATURAL LOOPS +Loop head: @1 tails: @2 blocks: @2 @1 @3 + +Found 1 loops in scope [] + Loop head: @1 tails: @2 blocks: @2 @1 @3 +NATURAL LOOPS WITH DEPTH +Loop head: @1 tails: @2 blocks: @2 @1 @3 depth: 1 + + +VARIABLE REGISTER WEIGHTS +(byte) STAR +(byte) e +(byte) e#1 11.0 +(byte) e#2 22.0 +(byte) e#3 5.5 +(byte) e#5 16.5 +(word) idx +(word) idx#1 8.25 +(word) idx#2 11.0 +(word) idx#3 11.0 +(word) idx#5 16.5 +(byte[1000]) screen +(byte) x +(byte) x#1 3.666666666666667 +(byte) x#2 11.0 +(byte) x0 +(byte) x1 +(byte) xd +(byte) y +(byte) y#1 7.333333333333333 +(byte) y#2 5.5 +(byte) y#4 16.5 +(byte) y0 +(byte) y1 +(byte) yd + +Initial phi equivalence classes +[ idx#3 idx#5 idx#1 idx#2 ] +[ x#2 x#1 ] +[ e#3 e#5 e#1 e#2 ] +[ y#2 y#4 y#1 ] +Complete equivalence classes +[ idx#3 idx#5 idx#1 idx#2 ] +[ x#2 x#1 ] +[ e#3 e#5 e#1 e#2 ] +[ y#2 y#4 y#1 ] +Allocated zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ] +Allocated zp ZP_BYTE:4 [ x#2 x#1 ] +Allocated zp ZP_BYTE:5 [ e#3 e#5 e#1 e#2 ] +Allocated zp ZP_BYTE:6 [ y#2 y#4 y#1 ] +INITIAL ASM +//SEG0 Global ZP labels + .label x = 4 + .label idx = 2 + .label e = 5 + .label y = 6 +//SEG1 @begin +bbegin: +//SEG2 [0] phi from @begin to @1 +b1_from_bbegin: +//SEG3 [0] phi (byte) y#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta y +//SEG4 [0] phi (byte) e#3 = (byte) 12 -- zpby1=coby1 + lda #$c + sta e +//SEG5 [0] phi (byte) x#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta x +//SEG6 [0] phi (word) idx#3 = (byte) 0 -- zpwo1=coby1 + lda #$0 + sta idx + lda #$0 + sta idx+$1 + jmp b1 +//SEG7 [0] phi from @2 to @1 +b1_from_b2: +//SEG8 [0] phi (byte) y#2 = (byte) y#4 -- register_copy +//SEG9 [0] phi (byte) e#3 = (byte) e#5 -- register_copy +//SEG10 [0] phi (byte) x#2 = (byte) x#1 -- register_copy +//SEG11 [0] phi (word) idx#3 = (word) idx#5 -- register_copy + jmp b1 +//SEG12 @1 +b1: +//SEG13 [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] -- cowo1_staridx_zpwo1=coby2 + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 +//SEG14 [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] -- zpby1=zpby1_plus_1 + inc x +//SEG15 [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] -- zpwo1=zpwo1_plus_1 + inc idx + bne !+ + inc idx+$1 +!: +//SEG16 [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] -- zpby1=zpby1_plus_coby1 + lda e + clc + adc #$18 + sta e +//SEG17 [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] -- coby1_ge_zpby1_then_la1 + lda #$27 + cmp e + bcs b2_from_b1 + jmp b3 +//SEG18 @3 +b3: +//SEG19 [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] -- zpby1=zpby1_plus_1 + inc y +//SEG20 [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] -- zpwo1=zpwo1_plus_coby1 + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: +//SEG21 [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] -- zpby1=zpby1_minus_coby1 + lda e + sec + sbc #$27 + sta e +//SEG22 [9] phi from @3 to @2 +b2_from_b3: +//SEG23 [9] phi (byte) y#4 = (byte) y#1 -- register_copy +//SEG24 [9] phi (byte) e#5 = (byte) e#2 -- register_copy +//SEG25 [9] phi (word) idx#5 = (word) idx#2 -- register_copy + jmp b2 +//SEG26 [9] phi from @1 to @2 +b2_from_b1: +//SEG27 [9] phi (byte) y#4 = (byte) y#2 -- register_copy +//SEG28 [9] phi (byte) e#5 = (byte) e#1 -- register_copy +//SEG29 [9] phi (word) idx#5 = (word) idx#1 -- register_copy + jmp b2 +//SEG30 @2 +b2: +//SEG31 [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] -- zpby1_lt_coby1_then_la1 + lda x + cmp #$28 + bcc b1_from_b2 + jmp bend +//SEG32 @end +bend: + +Statement [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ x#2 x#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ e#3 e#5 e#1 e#2 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ y#2 y#4 y#1 ] +Statement [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] always clobbers reg byte a +Statement [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] always clobbers reg byte a +Statement [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] always clobbers reg byte a +Statement [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] always clobbers reg byte a +Statement [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] always clobbers reg byte a +Statement [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] always clobbers reg byte a +Statement [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] always clobbers reg byte a +REGISTER UPLIFT POTENTIAL REGISTERS +Potential registers zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ] : zp ZP_WORD:2 , +Potential registers zp ZP_BYTE:4 [ x#2 x#1 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ e#3 e#5 e#1 e#2 ] : zp ZP_BYTE:5 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:6 [ y#2 y#4 y#1 ] : zp ZP_BYTE:6 , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [] 55: zp ZP_BYTE:5 [ e#3 e#5 e#1 e#2 ] 46.75: zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ] 29.33: zp ZP_BYTE:6 [ y#2 y#4 y#1 ] 14.67: zp ZP_BYTE:4 [ x#2 x#1 ] + +Uplifting [] best 1250 combination reg byte y [ e#3 e#5 e#1 e#2 ] zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ] zp ZP_BYTE:6 [ y#2 y#4 y#1 ] reg byte x [ x#2 x#1 ] +Allocated (was zp ZP_BYTE:6) zp ZP_BYTE:4 [ y#2 y#4 y#1 ] +Removing instruction jmp b1 +Removing instruction jmp b3 +Removing instruction jmp b2 +Removing instruction jmp bend +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Global ZP labels + .label idx = 2 + .label y = 4 +//SEG1 @begin +bbegin: +//SEG2 [0] phi from @begin to @1 +b1_from_bbegin: +//SEG3 [0] phi (byte) y#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta y +//SEG4 [0] phi (byte) e#3 = (byte) 12 -- yby=coby1 + ldy #$c +//SEG5 [0] phi (byte) x#2 = (byte) 0 -- xby=coby1 + ldx #$0 +//SEG6 [0] phi (word) idx#3 = (byte) 0 -- zpwo1=coby1 + lda #$0 + sta idx + lda #$0 + sta idx+$1 + jmp b1 +//SEG7 [0] phi from @2 to @1 +b1_from_b2: +//SEG8 [0] phi (byte) y#2 = (byte) y#4 -- register_copy +//SEG9 [0] phi (byte) e#3 = (byte) e#5 -- register_copy +//SEG10 [0] phi (byte) x#2 = (byte) x#1 -- register_copy +//SEG11 [0] phi (word) idx#3 = (word) idx#5 -- register_copy +//SEG12 @1 +b1: +//SEG13 [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] -- cowo1_staridx_zpwo1=coby2 + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 +//SEG14 [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] -- xby=xby_plus_1 + inx +//SEG15 [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] -- zpwo1=zpwo1_plus_1 + inc idx + bne !+ + inc idx+$1 +!: +//SEG16 [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] -- yby=yby_plus_coby1 + tya + clc + adc #$18 + tay +//SEG17 [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] -- coby1_ge_yby_then_la1 + cpy #$27 + bcc b2_from_b1 +//SEG18 @3 +b3: +//SEG19 [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] -- zpby1=zpby1_plus_1 + inc y +//SEG20 [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] -- zpwo1=zpwo1_plus_coby1 + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: +//SEG21 [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] -- yby=yby_minus_coby1 + tya + sec + sbc #$27 + tay +//SEG22 [9] phi from @3 to @2 +b2_from_b3: +//SEG23 [9] phi (byte) y#4 = (byte) y#1 -- register_copy +//SEG24 [9] phi (byte) e#5 = (byte) e#2 -- register_copy +//SEG25 [9] phi (word) idx#5 = (word) idx#2 -- register_copy + jmp b2 +//SEG26 [9] phi from @1 to @2 +b2_from_b1: +//SEG27 [9] phi (byte) y#4 = (byte) y#2 -- register_copy +//SEG28 [9] phi (byte) e#5 = (byte) e#1 -- register_copy +//SEG29 [9] phi (word) idx#5 = (word) idx#1 -- register_copy +//SEG30 @2 +b2: +//SEG31 [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] -- xby_lt_coby1_then_la1 + cpx #$28 + bcc b1_from_b2 +//SEG32 @end +bend: + +Replacing label b2_from_b1 with b2 +Replacing label b1_from_b2 with b1 +Removing instruction b1_from_bbegin: +Removing instruction b1_from_b2: +Removing instruction b2_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +ASSEMBLER +//SEG0 Global ZP labels + .label idx = 2 + .label y = 4 +//SEG1 @begin +bbegin: +//SEG2 [0] phi from @begin to @1 +//SEG3 [0] phi (byte) y#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta y +//SEG4 [0] phi (byte) e#3 = (byte) 12 -- yby=coby1 + ldy #$c +//SEG5 [0] phi (byte) x#2 = (byte) 0 -- xby=coby1 + ldx #$0 +//SEG6 [0] phi (word) idx#3 = (byte) 0 -- zpwo1=coby1 + lda #$0 + sta idx + lda #$0 + sta idx+$1 + jmp b1 +//SEG7 [0] phi from @2 to @1 +//SEG8 [0] phi (byte) y#2 = (byte) y#4 -- register_copy +//SEG9 [0] phi (byte) e#3 = (byte) e#5 -- register_copy +//SEG10 [0] phi (byte) x#2 = (byte) x#1 -- register_copy +//SEG11 [0] phi (word) idx#3 = (word) idx#5 -- register_copy +//SEG12 @1 +b1: +//SEG13 [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] -- cowo1_staridx_zpwo1=coby2 + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 +//SEG14 [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] -- xby=xby_plus_1 + inx +//SEG15 [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] -- zpwo1=zpwo1_plus_1 + inc idx + bne !+ + inc idx+$1 +!: +//SEG16 [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] -- yby=yby_plus_coby1 + tya + clc + adc #$18 + tay +//SEG17 [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] -- coby1_ge_yby_then_la1 + cpy #$27 + bcc b2 +//SEG18 @3 +b3: +//SEG19 [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] -- zpby1=zpby1_plus_1 + inc y +//SEG20 [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] -- zpwo1=zpwo1_plus_coby1 + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: +//SEG21 [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] -- yby=yby_minus_coby1 + tya + sec + sbc #$27 + tay +//SEG22 [9] phi from @3 to @2 +b2_from_b3: +//SEG23 [9] phi (byte) y#4 = (byte) y#1 -- register_copy +//SEG24 [9] phi (byte) e#5 = (byte) e#2 -- register_copy +//SEG25 [9] phi (word) idx#5 = (word) idx#2 -- register_copy + jmp b2 +//SEG26 [9] phi from @1 to @2 +//SEG27 [9] phi (byte) y#4 = (byte) y#2 -- register_copy +//SEG28 [9] phi (byte) e#5 = (byte) e#1 -- register_copy +//SEG29 [9] phi (word) idx#5 = (word) idx#1 -- register_copy +//SEG30 @2 +b2: +//SEG31 [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] -- xby_lt_coby1_then_la1 + cpx #$28 + bcc b1 +//SEG32 @end +bend: + +Removing instruction bbegin: +Removing instruction b3: +Removing instruction b2_from_b3: +Removing instruction bend: +Succesful ASM optimization Pass5UnusedLabelElimination +ASSEMBLER +//SEG0 Global ZP labels + .label idx = 2 + .label y = 4 +//SEG1 @begin +//SEG2 [0] phi from @begin to @1 +//SEG3 [0] phi (byte) y#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta y +//SEG4 [0] phi (byte) e#3 = (byte) 12 -- yby=coby1 + ldy #$c +//SEG5 [0] phi (byte) x#2 = (byte) 0 -- xby=coby1 + ldx #$0 +//SEG6 [0] phi (word) idx#3 = (byte) 0 -- zpwo1=coby1 + lda #$0 + sta idx + lda #$0 + sta idx+$1 + jmp b1 +//SEG7 [0] phi from @2 to @1 +//SEG8 [0] phi (byte) y#2 = (byte) y#4 -- register_copy +//SEG9 [0] phi (byte) e#3 = (byte) e#5 -- register_copy +//SEG10 [0] phi (byte) x#2 = (byte) x#1 -- register_copy +//SEG11 [0] phi (word) idx#3 = (word) idx#5 -- register_copy +//SEG12 @1 +b1: +//SEG13 [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] -- cowo1_staridx_zpwo1=coby2 + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 +//SEG14 [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] -- xby=xby_plus_1 + inx +//SEG15 [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] -- zpwo1=zpwo1_plus_1 + inc idx + bne !+ + inc idx+$1 +!: +//SEG16 [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] -- yby=yby_plus_coby1 + tya + clc + adc #$18 + tay +//SEG17 [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] -- coby1_ge_yby_then_la1 + cpy #$27 + bcc b2 +//SEG18 @3 +//SEG19 [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] -- zpby1=zpby1_plus_1 + inc y +//SEG20 [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] -- zpwo1=zpwo1_plus_coby1 + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: +//SEG21 [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] -- yby=yby_minus_coby1 + tya + sec + sbc #$27 + tay +//SEG22 [9] phi from @3 to @2 +//SEG23 [9] phi (byte) y#4 = (byte) y#1 -- register_copy +//SEG24 [9] phi (byte) e#5 = (byte) e#2 -- register_copy +//SEG25 [9] phi (word) idx#5 = (word) idx#2 -- register_copy + jmp b2 +//SEG26 [9] phi from @1 to @2 +//SEG27 [9] phi (byte) y#4 = (byte) y#2 -- register_copy +//SEG28 [9] phi (byte) e#5 = (byte) e#1 -- register_copy +//SEG29 [9] phi (word) idx#5 = (word) idx#1 -- register_copy +//SEG30 @2 +b2: +//SEG31 [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] -- xby_lt_coby1_then_la1 + cpx #$28 + bcc b1 +//SEG32 @end + +Removing instruction jmp b1 +Removing instruction jmp b2 +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Global ZP labels + .label idx = 2 + .label y = 4 +//SEG1 @begin +//SEG2 [0] phi from @begin to @1 +//SEG3 [0] phi (byte) y#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta y +//SEG4 [0] phi (byte) e#3 = (byte) 12 -- yby=coby1 + ldy #$c +//SEG5 [0] phi (byte) x#2 = (byte) 0 -- xby=coby1 + ldx #$0 +//SEG6 [0] phi (word) idx#3 = (byte) 0 -- zpwo1=coby1 + lda #$0 + sta idx + lda #$0 + sta idx+$1 +//SEG7 [0] phi from @2 to @1 +//SEG8 [0] phi (byte) y#2 = (byte) y#4 -- register_copy +//SEG9 [0] phi (byte) e#3 = (byte) e#5 -- register_copy +//SEG10 [0] phi (byte) x#2 = (byte) x#1 -- register_copy +//SEG11 [0] phi (word) idx#3 = (word) idx#5 -- register_copy +//SEG12 @1 +b1: +//SEG13 [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] -- cowo1_staridx_zpwo1=coby2 + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 +//SEG14 [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] -- xby=xby_plus_1 + inx +//SEG15 [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] -- zpwo1=zpwo1_plus_1 + inc idx + bne !+ + inc idx+$1 +!: +//SEG16 [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] -- yby=yby_plus_coby1 + tya + clc + adc #$18 + tay +//SEG17 [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] -- coby1_ge_yby_then_la1 + cpy #$27 + bcc b2 +//SEG18 @3 +//SEG19 [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] -- zpby1=zpby1_plus_1 + inc y +//SEG20 [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] -- zpwo1=zpwo1_plus_coby1 + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: +//SEG21 [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] -- yby=yby_minus_coby1 + tya + sec + sbc #$27 + tay +//SEG22 [9] phi from @3 to @2 +//SEG23 [9] phi (byte) y#4 = (byte) y#1 -- register_copy +//SEG24 [9] phi (byte) e#5 = (byte) e#2 -- register_copy +//SEG25 [9] phi (word) idx#5 = (word) idx#2 -- register_copy +//SEG26 [9] phi from @1 to @2 +//SEG27 [9] phi (byte) y#4 = (byte) y#2 -- register_copy +//SEG28 [9] phi (byte) e#5 = (byte) e#1 -- register_copy +//SEG29 [9] phi (word) idx#5 = (word) idx#1 -- register_copy +//SEG30 @2 +b2: +//SEG31 [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] -- xby_lt_coby1_then_la1 + cpx #$28 + bcc b1 +//SEG32 @end + +FINAL SYMBOL TABLE +(label) @1 +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte) STAR +(byte) e +(byte) e#1 reg byte y 11.0 +(byte) e#2 reg byte y 22.0 +(byte) e#3 reg byte y 5.5 +(byte) e#5 reg byte y 16.5 +(word) idx +(word) idx#1 idx zp ZP_WORD:2 8.25 +(word) idx#2 idx zp ZP_WORD:2 11.0 +(word) idx#3 idx zp ZP_WORD:2 11.0 +(word) idx#5 idx zp ZP_WORD:2 16.5 +(byte[1000]) screen +(byte) x +(byte) x#1 reg byte x 3.666666666666667 +(byte) x#2 reg byte x 11.0 +(byte) x0 +(byte) x1 +(byte) xd +(byte) y +(byte) y#1 y zp ZP_BYTE:4 7.333333333333333 +(byte) y#2 y zp ZP_BYTE:4 5.5 +(byte) y#4 y zp ZP_BYTE:4 16.5 +(byte) y0 +(byte) y1 +(byte) yd + +zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ] +reg byte x [ x#2 x#1 ] +reg byte y [ e#3 e#5 e#1 e#2 ] +zp ZP_BYTE:4 [ y#2 y#4 y#1 ] + +FINAL CODE +//SEG0 Global ZP labels + .label idx = 2 + .label y = 4 +//SEG1 @begin +//SEG2 [0] phi from @begin to @1 +//SEG3 [0] phi (byte) y#2 = (byte) 0 -- zpby1=coby1 + lda #$0 + sta y +//SEG4 [0] phi (byte) e#3 = (byte) 12 -- yby=coby1 + ldy #$c +//SEG5 [0] phi (byte) x#2 = (byte) 0 -- xby=coby1 + ldx #$0 +//SEG6 [0] phi (word) idx#3 = (byte) 0 -- zpwo1=coby1 + lda #$0 + sta idx + lda #$0 + sta idx+$1 +//SEG7 [0] phi from @2 to @1 +//SEG8 [0] phi (byte) y#2 = (byte) y#4 -- register_copy +//SEG9 [0] phi (byte) e#3 = (byte) e#5 -- register_copy +//SEG10 [0] phi (byte) x#2 = (byte) x#1 -- register_copy +//SEG11 [0] phi (word) idx#3 = (word) idx#5 -- register_copy +//SEG12 @1 +b1: +//SEG13 [1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ] -- cowo1_staridx_zpwo1=coby2 + lda #<$400 + clc + adc idx + sta !s++$1 + lda #>$400 + adc idx+$1 + sta !s++$2 + lda #$51 +!s: + sta $400 +//SEG14 [2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ] -- xby=xby_plus_1 + inx +//SEG15 [3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ] -- zpwo1=zpwo1_plus_1 + inc idx + bne !+ + inc idx+$1 +!: +//SEG16 [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ] -- yby=yby_plus_coby1 + tya + clc + adc #$18 + tay +//SEG17 [5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ] -- coby1_ge_yby_then_la1 + cpy #$27 + bcc b2 +//SEG18 @3 +//SEG19 [6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ] -- zpby1=zpby1_plus_1 + inc y +//SEG20 [7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ] -- zpwo1=zpwo1_plus_coby1 + lda idx + clc + adc #<$28 + sta idx + bcc !+ + inc idx+$1 +!: +//SEG21 [8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ] -- yby=yby_minus_coby1 + tya + sec + sbc #$27 + tay +//SEG22 [9] phi from @3 to @2 +//SEG23 [9] phi (byte) y#4 = (byte) y#1 -- register_copy +//SEG24 [9] phi (byte) e#5 = (byte) e#2 -- register_copy +//SEG25 [9] phi (word) idx#5 = (word) idx#2 -- register_copy +//SEG26 [9] phi from @1 to @2 +//SEG27 [9] phi (byte) y#4 = (byte) y#2 -- register_copy +//SEG28 [9] phi (byte) e#5 = (byte) e#1 -- register_copy +//SEG29 [9] phi (word) idx#5 = (word) idx#1 -- register_copy +//SEG30 @2 +b2: +//SEG31 [10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ] -- xby_lt_coby1_then_la1 + cpx #$28 + bcc b1 +//SEG32 @end + diff --git a/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.sym b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.sym new file mode 100644 index 000000000..cfe231899 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.sym @@ -0,0 +1,35 @@ +(label) @1 +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte) STAR +(byte) e +(byte) e#1 reg byte y 11.0 +(byte) e#2 reg byte y 22.0 +(byte) e#3 reg byte y 5.5 +(byte) e#5 reg byte y 16.5 +(word) idx +(word) idx#1 idx zp ZP_WORD:2 8.25 +(word) idx#2 idx zp ZP_WORD:2 11.0 +(word) idx#3 idx zp ZP_WORD:2 11.0 +(word) idx#5 idx zp ZP_WORD:2 16.5 +(byte[1000]) screen +(byte) x +(byte) x#1 reg byte x 3.666666666666667 +(byte) x#2 reg byte x 11.0 +(byte) x0 +(byte) x1 +(byte) xd +(byte) y +(byte) y#1 y zp ZP_BYTE:4 7.333333333333333 +(byte) y#2 y zp ZP_BYTE:4 5.5 +(byte) y#4 y zp ZP_BYTE:4 16.5 +(byte) y0 +(byte) y1 +(byte) yd + +zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ] +reg byte x [ x#2 x#1 ] +reg byte y [ e#3 e#5 e#1 e#2 ] +zp ZP_BYTE:4 [ y#2 y#4 y#1 ]