diff --git a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java index a2d308c07..12ee69671 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java @@ -28,6 +28,10 @@ public class TestPrograms extends TestCase { compileAndCompare("bitmap-bresenham"); } + public void testAsmClobber() throws IOException, URISyntaxException { + compileAndCompare("asm-clobber"); + } + public void testInlineAsm() throws IOException, URISyntaxException { compileAndCompare("inline-asm"); } diff --git a/src/main/java/dk/camelot64/kickc/test/asm-clobber.kc b/src/main/java/dk/camelot64/kickc/test/asm-clobber.kc new file mode 100644 index 000000000..a41217e56 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/asm-clobber.kc @@ -0,0 +1,21 @@ +// Tests that inline ASM clobbering is taken into account when assigning registers +byte* SCREEN = $0400; +void main() { + // First loop with no clobber + for(byte i : 0..100) { + for(byte j: 0..100) { + SCREEN[i] = j; + } + } + // Then loop with clobbering A&X + for(byte k : 0..100) { + for(byte l: 0..100) { + asm { + // Clobber all registers + eor #$55 + tax + }; + SCREEN[k] = l; + } + } +} diff --git a/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.asm b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.asm new file mode 100644 index 000000000..69344a6a5 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.asm @@ -0,0 +1,37 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const SCREEN = $400 + jsr main +main: { + .label l = 2 + ldx #0 + b1: + lda #0 + b2: + sta SCREEN,x + clc + adc #1 + cmp #$65 + bne b2 + inx + cpx #$65 + bne b1 + ldy #0 + b3: + lda #0 + sta l + b4: + eor #$55 + tax + lda l + sta SCREEN,y + inc l + lda l + cmp #$65 + bne b4 + iny + cpy #$65 + bne b3 + rts +} diff --git a/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.cfg b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.cfg new file mode 100644 index 000000000..237070146 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.cfg @@ -0,0 +1,39 @@ +@begin: scope:[] from + to:@1 +@1: scope:[] from @begin + [0] call main param-assignment [ ] + to:@end +@end: scope:[] from @1 +main: scope:[main] from @1 + [1] phi() [ ] + to:main::@1 +main::@1: scope:[main] from main main::@5 + [2] (byte) main::i#4 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) [ main::i#4 ] + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + [3] (byte) main::j#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::j#1 ) [ main::i#4 main::j#2 ] + [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] + [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] + [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] + to:main::@5 +main::@5: scope:[main] from main::@2 + [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] + [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] + to:main::@3 +main::@3: scope:[main] from main::@5 main::@7 + [9] (byte) main::k#4 ← phi( main::@5/(byte) 0 main::@7/(byte) main::k#1 ) [ main::k#4 ] + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + [10] (byte) main::l#2 ← phi( main::@3/(byte) 0 main::@4/(byte) main::l#1 ) [ main::k#4 main::l#2 ] + asm { eor#$55tax } + [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] + [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] + [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] + to:main::@7 +main::@7: scope:[main] from main::@4 + [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] + [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] + to:main::@return +main::@return: scope:[main] from main::@7 + [17] return [ ] + to:@return diff --git a/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.log b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.log new file mode 100644 index 000000000..0aa56b7c4 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.log @@ -0,0 +1,1871 @@ +// Tests that inline ASM clobbering is taken into account when assigning registers +byte* SCREEN = $0400; +void main() { + // First loop with no clobber + for(byte i : 0..100) { + for(byte j: 0..100) { + SCREEN[i] = j; + } + } + // Then loop with clobbering A&X + for(byte k : 0..100) { + for(byte l: 0..100) { + asm { + // Clobber all registers + eor #$55 + tax + }; + SCREEN[k] = l; + } + } +} + +PROGRAM + (byte*) SCREEN ← (word) 1024 +proc (void()) main() + (byte) main::i ← (byte) 0 +main::@1: + (byte) main::j ← (byte) 0 +main::@2: + *((byte*) SCREEN + (byte) main::i) ← (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$0 ← (byte) main::j != (byte) 101 + if((boolean~) main::$0) goto main::@2 + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 101 + if((boolean~) main::$1) goto main::@1 + (byte) main::k ← (byte) 0 +main::@3: + (byte) main::l ← (byte) 0 +main::@4: + asm { eor#$55tax } + *((byte*) SCREEN + (byte) main::k) ← (byte) main::l + (byte) main::l ← ++ (byte) main::l + (boolean~) main::$2 ← (byte) main::l != (byte) 101 + if((boolean~) main::$2) goto main::@4 + (byte) main::k ← ++ (byte) main::k + (boolean~) main::$3 ← (byte) main::k != (byte) 101 + if((boolean~) main::$3) goto main::@3 +main::@return: + return +endproc // main() + call main + +SYMBOLS +(byte*) SCREEN +(void()) main() +(boolean~) main::$0 +(boolean~) main::$1 +(boolean~) main::$2 +(boolean~) main::$3 +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@return +(byte) main::i +(byte) main::j +(byte) main::k +(byte) main::l + +INITIAL CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN ← (word) 1024 + to:@1 +main: scope:[main] from + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::j ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + *((byte*) SCREEN + (byte) main::i) ← (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$0 ← (byte) main::j != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::l ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + asm { eor#$55tax } + *((byte*) SCREEN + (byte) main::k) ← (byte) main::l + (byte) main::l ← ++ (byte) main::l + (boolean~) main::$2 ← (byte) main::l != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k ← ++ (byte) main::k + (boolean~) main::$3 ← (byte) main::k != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@8 +main::@8: scope:[main] from main::@7 + to:main::@return +main::@return: scope:[main] from main::@8 + return + to:@return +@1: scope:[] from @begin + call main + to:@end +@end: scope:[] from @1 + +Removing empty block main::@8 +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN ← (word) 1024 + to:@1 +main: scope:[main] from + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::j ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + *((byte*) SCREEN + (byte) main::i) ← (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$0 ← (byte) main::j != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::l ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + asm { eor#$55tax } + *((byte*) SCREEN + (byte) main::k) ← (byte) main::l + (byte) main::l ← ++ (byte) main::l + (boolean~) main::$2 ← (byte) main::l != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k ← ++ (byte) main::k + (boolean~) main::$3 ← (byte) main::k != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main + to:@end +@end: scope:[] from @1 + +PROCEDURE MODIFY VARIABLE ANALYSIS + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL +@begin: scope:[] from + (byte*) SCREEN ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::j ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + *((byte*) SCREEN + (byte) main::i) ← (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$0 ← (byte) main::j != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::l ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + asm { eor#$55tax } + *((byte*) SCREEN + (byte) main::k) ← (byte) main::l + (byte) main::l ← ++ (byte) main::l + (boolean~) main::$2 ← (byte) main::l != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k ← ++ (byte) main::k + (boolean~) main::$3 ← (byte) main::k != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte*) SCREEN#5 ← phi( @1/(byte*) SCREEN#9 ) + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#5 main::@5/(byte*) SCREEN#6 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::i#2 ← phi( main::@1/(byte) main::i#4 main::@2/(byte) main::i#2 ) + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#3 main::@2/(byte*) SCREEN#1 ) + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#1 + (byte) main::i#2) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$0 ← (byte) main::j#1 != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte*) SCREEN#6 ← phi( main::@2/(byte*) SCREEN#1 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#2 ) + (byte) main::i#1 ← ++ (byte) main::i#3 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte*) SCREEN#7 ← phi( main::@5/(byte*) SCREEN#6 ) + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#7 main::@7/(byte*) SCREEN#8 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::k#2 ← phi( main::@3/(byte) main::k#4 main::@4/(byte) main::k#2 ) + (byte*) SCREEN#2 ← phi( main::@3/(byte*) SCREEN#4 main::@4/(byte*) SCREEN#2 ) + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#2 + (byte) main::k#2) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + (boolean~) main::$2 ← (byte) main::l#1 != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte*) SCREEN#8 ← phi( main::@4/(byte*) SCREEN#2 ) + (byte) main::k#3 ← phi( main::@4/(byte) main::k#2 ) + (byte) main::k#1 ← ++ (byte) main::k#3 + (boolean~) main::$3 ← (byte) main::k#1 != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + (byte*) SCREEN#9 ← phi( @begin/(byte*) SCREEN#0 ) + call main param-assignment + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte*) SCREEN#5 ← phi( @1/(byte*) SCREEN#9 ) + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#5 main::@5/(byte*) SCREEN#6 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::i#2 ← phi( main::@1/(byte) main::i#4 main::@2/(byte) main::i#2 ) + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#3 main::@2/(byte*) SCREEN#1 ) + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#1 + (byte) main::i#2) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$0 ← (byte) main::j#1 != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte*) SCREEN#6 ← phi( main::@2/(byte*) SCREEN#1 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#2 ) + (byte) main::i#1 ← ++ (byte) main::i#3 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte*) SCREEN#7 ← phi( main::@5/(byte*) SCREEN#6 ) + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#7 main::@7/(byte*) SCREEN#8 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::k#2 ← phi( main::@3/(byte) main::k#4 main::@4/(byte) main::k#2 ) + (byte*) SCREEN#2 ← phi( main::@3/(byte*) SCREEN#4 main::@4/(byte*) SCREEN#2 ) + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#2 + (byte) main::k#2) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + (boolean~) main::$2 ← (byte) main::l#1 != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte*) SCREEN#8 ← phi( main::@4/(byte*) SCREEN#2 ) + (byte) main::k#3 ← phi( main::@4/(byte) main::k#2 ) + (byte) main::k#1 ← ++ (byte) main::k#3 + (boolean~) main::$3 ← (byte) main::k#1 != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + (byte*) SCREEN#9 ← phi( @begin/(byte*) SCREEN#0 ) + call main param-assignment + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +INITIAL SSA SYMBOL TABLE +(label) @1 +(label) @2 +(label) @begin +(label) @end +(byte*) SCREEN +(byte*) SCREEN#0 +(byte*) SCREEN#1 +(byte*) SCREEN#2 +(byte*) SCREEN#3 +(byte*) SCREEN#4 +(byte*) SCREEN#5 +(byte*) SCREEN#6 +(byte*) SCREEN#7 +(byte*) SCREEN#8 +(byte*) SCREEN#9 +(void()) main() +(boolean~) main::$0 +(boolean~) main::$1 +(boolean~) main::$2 +(boolean~) main::$3 +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@return +(byte) main::i +(byte) main::i#0 +(byte) main::i#1 +(byte) main::i#2 +(byte) main::i#3 +(byte) main::i#4 +(byte) main::j +(byte) main::j#0 +(byte) main::j#1 +(byte) main::j#2 +(byte) main::k +(byte) main::k#0 +(byte) main::k#1 +(byte) main::k#2 +(byte) main::k#3 +(byte) main::k#4 +(byte) main::l +(byte) main::l#0 +(byte) main::l#1 +(byte) main::l#2 + +Culled Empty Block (label) @2 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte*) SCREEN#5 ← phi( @1/(byte*) SCREEN#9 ) + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#5 main::@5/(byte*) SCREEN#6 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::i#2 ← phi( main::@1/(byte) main::i#4 main::@2/(byte) main::i#2 ) + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#3 main::@2/(byte*) SCREEN#1 ) + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#1 + (byte) main::i#2) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$0 ← (byte) main::j#1 != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte*) SCREEN#6 ← phi( main::@2/(byte*) SCREEN#1 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#2 ) + (byte) main::i#1 ← ++ (byte) main::i#3 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte*) SCREEN#7 ← phi( main::@5/(byte*) SCREEN#6 ) + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#7 main::@7/(byte*) SCREEN#8 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::k#2 ← phi( main::@3/(byte) main::k#4 main::@4/(byte) main::k#2 ) + (byte*) SCREEN#2 ← phi( main::@3/(byte*) SCREEN#4 main::@4/(byte*) SCREEN#2 ) + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#2 + (byte) main::k#2) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + (boolean~) main::$2 ← (byte) main::l#1 != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte*) SCREEN#8 ← phi( main::@4/(byte*) SCREEN#2 ) + (byte) main::k#3 ← phi( main::@4/(byte) main::k#2 ) + (byte) main::k#1 ← ++ (byte) main::k#3 + (boolean~) main::$3 ← (byte) main::k#1 != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + (byte*) SCREEN#9 ← phi( @begin/(byte*) SCREEN#0 ) + call main param-assignment + to:@end +@end: scope:[] from @1 + +Alias (byte*) SCREEN#0 = (byte*) SCREEN#5 (byte*) SCREEN#9 +Alias (byte) main::i#2 = (byte) main::i#3 +Alias (byte*) SCREEN#1 = (byte*) SCREEN#6 (byte*) SCREEN#7 +Alias (byte) main::k#2 = (byte) main::k#3 +Alias (byte*) SCREEN#2 = (byte*) SCREEN#8 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#0 main::@5/(byte*) SCREEN#1 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::i#2 ← phi( main::@1/(byte) main::i#4 main::@2/(byte) main::i#2 ) + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#3 main::@2/(byte*) SCREEN#1 ) + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#1 + (byte) main::i#2) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$0 ← (byte) main::j#1 != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#1 main::@7/(byte*) SCREEN#2 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::k#2 ← phi( main::@3/(byte) main::k#4 main::@4/(byte) main::k#2 ) + (byte*) SCREEN#2 ← phi( main::@3/(byte*) SCREEN#4 main::@4/(byte*) SCREEN#2 ) + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#2 + (byte) main::k#2) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + (boolean~) main::$2 ← (byte) main::l#1 != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#2 + (boolean~) main::$3 ← (byte) main::k#1 != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Self Phi Eliminated (byte*) SCREEN#1 +Self Phi Eliminated (byte) main::i#2 +Self Phi Eliminated (byte*) SCREEN#2 +Self Phi Eliminated (byte) main::k#2 +Succesful SSA optimization Pass2SelfPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#0 main::@5/(byte*) SCREEN#1 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::i#2 ← phi( main::@1/(byte) main::i#4 ) + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#3 ) + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#1 + (byte) main::i#2) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$0 ← (byte) main::j#1 != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#1 main::@7/(byte*) SCREEN#2 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::k#2 ← phi( main::@3/(byte) main::k#4 ) + (byte*) SCREEN#2 ← phi( main::@3/(byte*) SCREEN#4 ) + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#2 + (byte) main::k#2) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + (boolean~) main::$2 ← (byte) main::l#1 != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#2 + (boolean~) main::$3 ← (byte) main::k#1 != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Redundant Phi (byte*) SCREEN#1 (byte*) SCREEN#3 +Redundant Phi (byte) main::i#2 (byte) main::i#4 +Redundant Phi (byte*) SCREEN#2 (byte*) SCREEN#4 +Redundant Phi (byte) main::k#2 (byte) main::k#4 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#0 main::@5/(byte*) SCREEN#3 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#3 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$0 ← (byte) main::j#1 != (byte) 101 + if((boolean~) main::$0) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 101 + if((boolean~) main::$1) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#3 main::@7/(byte*) SCREEN#4 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#4 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + (boolean~) main::$2 ← (byte) main::l#1 != (byte) 101 + if((boolean~) main::$2) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + (boolean~) main::$3 ← (byte) main::k#1 != (byte) 101 + if((boolean~) main::$3) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Simple Condition (boolean~) main::$0 if((byte) main::j#1!=(byte) 101) goto main::@2 +Simple Condition (boolean~) main::$1 if((byte) main::i#1!=(byte) 101) goto main::@1 +Simple Condition (boolean~) main::$2 if((byte) main::l#1!=(byte) 101) goto main::@4 +Simple Condition (boolean~) main::$3 if((byte) main::k#1!=(byte) 101) goto main::@3 +Succesful SSA optimization Pass2ConditionalJumpSimplification +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@1 +main: scope:[main] from @1 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(byte*) SCREEN#0 main::@5/(byte*) SCREEN#3 ) + (byte) main::j#0 ← (byte) 0 + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#3 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) main::k#0 ← (byte) 0 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#3 main::@7/(byte*) SCREEN#4 ) + (byte) main::l#0 ← (byte) 0 + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#4 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Constant (const byte*) SCREEN#0 = 1024 +Constant (const byte) main::i#0 = 0 +Constant (const byte) main::j#0 = 0 +Constant (const byte) main::k#0 = 0 +Constant (const byte) main::l#0 = 0 +Succesful SSA optimization Pass2ConstantIdentification +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(const byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(const byte*) SCREEN#0 main::@5/(byte*) SCREEN#3 ) + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(const byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#3 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@1 + to:main::@6 +main::@6: scope:[main] from main::@5 + to:main::@3 +main::@3: scope:[main] from main::@6 main::@7 + (byte) main::k#4 ← phi( main::@6/(const byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@6/(byte*) SCREEN#3 main::@7/(byte*) SCREEN#4 ) + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(const byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#4 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Culled Empty Block (label) main::@6 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(const byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(const byte*) SCREEN#0 main::@5/(byte*) SCREEN#3 ) + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(const byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#3 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 main::@7 + (byte) main::k#4 ← phi( main::@5/(const byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@5/(byte*) SCREEN#3 main::@7/(byte*) SCREEN#4 ) + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(const byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#4 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Self Phi Eliminated (byte*) SCREEN#3 +Self Phi Eliminated (byte*) SCREEN#4 +Succesful SSA optimization Pass2SelfPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(const byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte*) SCREEN#3 ← phi( main/(const byte*) SCREEN#0 ) + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(const byte) main::j#0 main::@2/(byte) main::j#1 ) + *((byte*) SCREEN#3 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 main::@7 + (byte) main::k#4 ← phi( main::@5/(const byte) main::k#0 main::@7/(byte) main::k#1 ) + (byte*) SCREEN#4 ← phi( main::@5/(byte*) SCREEN#3 ) + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(const byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((byte*) SCREEN#4 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Redundant Phi (byte*) SCREEN#3 (const byte*) SCREEN#0 +Redundant Phi (byte*) SCREEN#4 (byte*) SCREEN#3 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(const byte) main::i#0 main::@5/(byte) main::i#1 ) + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(const byte) main::j#0 main::@2/(byte) main::j#1 ) + *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 main::@7 + (byte) main::k#4 ← phi( main::@5/(const byte) main::k#0 main::@7/(byte) main::k#1 ) + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(const byte) main::l#0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +Inlining constant with var siblings (const byte) main::i#0 +Inlining constant with var siblings (const byte) main::i#0 +Inlining constant with var siblings (const byte) main::j#0 +Inlining constant with var siblings (const byte) main::j#0 +Inlining constant with var siblings (const byte) main::k#0 +Inlining constant with var siblings (const byte) main::k#0 +Inlining constant with var siblings (const byte) main::l#0 +Inlining constant with var siblings (const byte) main::l#0 +Constant inlined main::l#0 = (byte) 0 +Constant inlined main::k#0 = (byte) 0 +Constant inlined main::j#0 = (byte) 0 +Constant inlined main::i#0 = (byte) 0 +Succesful SSA optimization Pass2ConstantInlining +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#4 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + (byte) main::j#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::j#1 ) + *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@2 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 main::@7 + (byte) main::k#4 ← phi( main::@5/(byte) 0 main::@7/(byte) main::k#1 ) + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + (byte) main::l#2 ← phi( main::@3/(byte) 0 main::@4/(byte) main::l#1 ) + asm { eor#$55tax } + *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@4 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@3 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) SCREEN +(const byte*) SCREEN#0 = (word) 1024 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@7 +(label) main::@return +(byte) main::i +(byte) main::i#1 +(byte) main::i#4 +(byte) main::j +(byte) main::j#1 +(byte) main::j#2 +(byte) main::k +(byte) main::k#1 +(byte) main::k#4 +(byte) main::l +(byte) main::l#1 +(byte) main::l#2 + +Block Sequence Planned @begin @1 @end main main::@1 main::@2 main::@5 main::@3 main::@4 main::@7 main::@return +Added new block during phi lifting main::@9(between main::@5 and main::@1) +Added new block during phi lifting main::@10(between main::@2 and main::@2) +Added new block during phi lifting main::@11(between main::@7 and main::@3) +Added new block during phi lifting main::@12(between main::@4 and main::@4) +Block Sequence Planned @begin @1 @end main main::@1 main::@2 main::@5 main::@3 main::@4 main::@7 main::@return main::@11 main::@12 main::@9 main::@10 +CONTROL FLOW GRAPH - PHI LIFTED +@begin: scope:[] from + to:@1 +@1: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @1 +main: scope:[main] from @1 + to:main::@1 +main::@1: scope:[main] from main main::@9 + (byte) main::i#4 ← phi( main/(byte) 0 main::@9/(byte~) main::i#5 ) + to:main::@2 +main::@2: scope:[main] from main::@1 main::@10 + (byte) main::j#2 ← phi( main::@1/(byte) 0 main::@10/(byte~) main::j#3 ) + *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 101) goto main::@10 + to:main::@5 +main::@5: scope:[main] from main::@2 + (byte) main::i#1 ← ++ (byte) main::i#4 + if((byte) main::i#1!=(byte) 101) goto main::@9 + to:main::@3 +main::@3: scope:[main] from main::@11 main::@5 + (byte) main::k#4 ← phi( main::@5/(byte) 0 main::@11/(byte~) main::k#5 ) + to:main::@4 +main::@4: scope:[main] from main::@12 main::@3 + (byte) main::l#2 ← phi( main::@3/(byte) 0 main::@12/(byte~) main::l#3 ) + asm { eor#$55tax } + *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 + (byte) main::l#1 ← ++ (byte) main::l#2 + if((byte) main::l#1!=(byte) 101) goto main::@12 + to:main::@7 +main::@7: scope:[main] from main::@4 + (byte) main::k#1 ← ++ (byte) main::k#4 + if((byte) main::k#1!=(byte) 101) goto main::@11 + to:main::@return +main::@return: scope:[main] from main::@7 + return + to:@return +main::@11: scope:[main] from main::@7 + (byte~) main::k#5 ← (byte) main::k#1 + to:main::@3 +main::@12: scope:[main] from main::@4 + (byte~) main::l#3 ← (byte) main::l#1 + to:main::@4 +main::@9: scope:[main] from main::@5 + (byte~) main::i#5 ← (byte) main::i#1 + to:main::@1 +main::@10: scope:[main] from main::@2 + (byte~) main::j#3 ← (byte) main::j#1 + to:main::@2 + +Adding NOP phi() at start of main +CALL GRAPH +Calls in [] to 0:main + +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - LIVE RANGES FOUND +@begin: scope:[] from + to:@1 +@1: scope:[] from @begin + [0] call main param-assignment [ ] + to:@end +@end: scope:[] from @1 +main: scope:[main] from @1 + [1] phi() [ ] + to:main::@1 +main::@1: scope:[main] from main main::@9 + [2] (byte) main::i#4 ← phi( main/(byte) 0 main::@9/(byte~) main::i#5 ) [ main::i#4 ] + to:main::@2 +main::@2: scope:[main] from main::@1 main::@10 + [3] (byte) main::j#2 ← phi( main::@1/(byte) 0 main::@10/(byte~) main::j#3 ) [ main::i#4 main::j#2 ] + [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] + [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] + [6] if((byte) main::j#1!=(byte) 101) goto main::@10 [ main::i#4 main::j#1 ] + to:main::@5 +main::@5: scope:[main] from main::@2 + [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] + [8] if((byte) main::i#1!=(byte) 101) goto main::@9 [ main::i#1 ] + to:main::@3 +main::@3: scope:[main] from main::@11 main::@5 + [9] (byte) main::k#4 ← phi( main::@5/(byte) 0 main::@11/(byte~) main::k#5 ) [ main::k#4 ] + to:main::@4 +main::@4: scope:[main] from main::@12 main::@3 + [10] (byte) main::l#2 ← phi( main::@3/(byte) 0 main::@12/(byte~) main::l#3 ) [ main::k#4 main::l#2 ] + asm { eor#$55tax } + [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] + [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] + [14] if((byte) main::l#1!=(byte) 101) goto main::@12 [ main::k#4 main::l#1 ] + to:main::@7 +main::@7: scope:[main] from main::@4 + [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] + [16] if((byte) main::k#1!=(byte) 101) goto main::@11 [ main::k#1 ] + to:main::@return +main::@return: scope:[main] from main::@7 + [17] return [ ] + to:@return +main::@11: scope:[main] from main::@7 + [18] (byte~) main::k#5 ← (byte) main::k#1 [ main::k#5 ] + to:main::@3 +main::@12: scope:[main] from main::@4 + [19] (byte~) main::l#3 ← (byte) main::l#1 [ main::k#4 main::l#3 ] + to:main::@4 +main::@9: scope:[main] from main::@5 + [20] (byte~) main::i#5 ← (byte) main::i#1 [ main::i#5 ] + to:main::@1 +main::@10: scope:[main] from main::@2 + [21] (byte~) main::j#3 ← (byte) main::j#1 [ main::i#4 main::j#3 ] + to:main::@2 + +Created 4 initial phi equivalence classes +Coalesced [18] main::k#5 ← main::k#1 +Coalesced [19] main::l#3 ← main::l#1 +Coalesced [20] main::i#5 ← main::i#1 +Coalesced [21] main::j#3 ← main::j#1 +Coalesced down to 4 phi equivalence classes +Culled Empty Block (label) main::@11 +Culled Empty Block (label) main::@12 +Culled Empty Block (label) main::@9 +Culled Empty Block (label) main::@10 +Block Sequence Planned @begin @1 @end main main::@1 main::@2 main::@5 main::@3 main::@4 main::@7 main::@return +Adding NOP phi() at start of main +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 @begin + [0] call main param-assignment [ ] + to:@end +@end: scope:[] from @1 +main: scope:[main] from @1 + [1] phi() [ ] + to:main::@1 +main::@1: scope:[main] from main main::@5 + [2] (byte) main::i#4 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) [ main::i#4 ] + to:main::@2 +main::@2: scope:[main] from main::@1 main::@2 + [3] (byte) main::j#2 ← phi( main::@1/(byte) 0 main::@2/(byte) main::j#1 ) [ main::i#4 main::j#2 ] + [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] + [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] + [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] + to:main::@5 +main::@5: scope:[main] from main::@2 + [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] + [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] + to:main::@3 +main::@3: scope:[main] from main::@5 main::@7 + [9] (byte) main::k#4 ← phi( main::@5/(byte) 0 main::@7/(byte) main::k#1 ) [ main::k#4 ] + to:main::@4 +main::@4: scope:[main] from main::@3 main::@4 + [10] (byte) main::l#2 ← phi( main::@3/(byte) 0 main::@4/(byte) main::l#1 ) [ main::k#4 main::l#2 ] + asm { eor#$55tax } + [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] + [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] + [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] + to:main::@7 +main::@7: scope:[main] from main::@4 + [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] + [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] + to:main::@return +main::@return: scope:[main] from main::@7 + [17] return [ ] + to:@return + +DOMINATORS +@begin dominated by @begin +@1 dominated by @1 @begin +@end dominated by @1 @end @begin +main dominated by @1 @begin main +main::@1 dominated by @1 @begin main::@1 main +main::@2 dominated by @1 @begin main::@2 main::@1 main +main::@5 dominated by @1 @begin main::@2 main::@1 main::@5 main +main::@3 dominated by @1 @begin main::@2 main::@1 main::@3 main::@5 main +main::@4 dominated by @1 @begin main::@2 main::@1 main::@4 main::@3 main::@5 main +main::@7 dominated by main::@7 @1 @begin main::@2 main::@1 main::@4 main::@3 main::@5 main +main::@return dominated by main::@7 @1 main::@return @begin main::@2 main::@1 main::@4 main::@3 main::@5 main + +Found back edge: Loop head: main::@2 tails: main::@2 blocks: null +Found back edge: Loop head: main::@1 tails: main::@5 blocks: null +Found back edge: Loop head: main::@4 tails: main::@4 blocks: null +Found back edge: Loop head: main::@3 tails: main::@7 blocks: null +Populated: Loop head: main::@2 tails: main::@2 blocks: main::@2 +Populated: Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@2 main::@1 +Populated: Loop head: main::@4 tails: main::@4 blocks: main::@4 +Populated: Loop head: main::@3 tails: main::@7 blocks: main::@7 main::@4 main::@3 +NATURAL LOOPS +Loop head: main::@2 tails: main::@2 blocks: main::@2 +Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@2 main::@1 +Loop head: main::@4 tails: main::@4 blocks: main::@4 +Loop head: main::@3 tails: main::@7 blocks: main::@7 main::@4 main::@3 + +Found 0 loops in scope [] +Found 4 loops in scope [main] + Loop head: main::@2 tails: main::@2 blocks: main::@2 + Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@2 main::@1 + Loop head: main::@4 tails: main::@4 blocks: main::@4 + Loop head: main::@3 tails: main::@7 blocks: main::@7 main::@4 main::@3 +NATURAL LOOPS WITH DEPTH +Loop head: main::@2 tails: main::@2 blocks: main::@2 depth: 2 +Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@2 main::@1 depth: 1 +Loop head: main::@4 tails: main::@4 blocks: main::@4 depth: 2 +Loop head: main::@3 tails: main::@7 blocks: main::@7 main::@4 main::@3 depth: 1 + + +VARIABLE REGISTER WEIGHTS +(byte*) SCREEN +(void()) main() +(byte) main::i +(byte) main::i#1 16.5 +(byte) main::i#4 24.599999999999998 +(byte) main::j +(byte) main::j#1 151.5 +(byte) main::j#2 151.5 +(byte) main::k +(byte) main::k#1 16.5 +(byte) main::k#4 20.499999999999996 +(byte) main::l +(byte) main::l#1 151.5 +(byte) main::l#2 101.0 + +Initial phi equivalence classes +[ main::i#4 main::i#1 ] +[ main::j#2 main::j#1 ] +[ main::k#4 main::k#1 ] +[ main::l#2 main::l#1 ] +Complete equivalence classes +[ main::i#4 main::i#1 ] +[ main::j#2 main::j#1 ] +[ main::k#4 main::k#1 ] +[ main::l#2 main::l#1 ] +Allocated zp ZP_BYTE:2 [ main::i#4 main::i#1 ] +Allocated zp ZP_BYTE:3 [ main::j#2 main::j#1 ] +Allocated zp ZP_BYTE:4 [ main::k#4 main::k#1 ] +Allocated zp ZP_BYTE:5 [ main::l#2 main::l#1 ] +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +bbegin: + jmp b1 +//SEG3 @1 +b1: +//SEG4 [0] call main param-assignment [ ] +//SEG5 [1] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main + jmp bend +//SEG6 @end +bend: +//SEG7 main +main: { + .label j = 3 + .label i = 2 + .label l = 5 + .label k = 4 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG9 [2] phi (byte) main::i#4 = (byte) 0 [phi:main->main::@1#0] -- zpby1=coby1 + lda #0 + sta i + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + b1_from_b5: + //SEG11 [2] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + jmp b1 + //SEG12 main::@1 + b1: + //SEG13 [3] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + //SEG14 [3] phi (byte) main::j#2 = (byte) 0 [phi:main::@1->main::@2#0] -- zpby1=coby1 + lda #0 + sta j + jmp b2 + //SEG15 [3] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + b2_from_b2: + //SEG16 [3] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@2->main::@2#0] -- register_copy + jmp b2 + //SEG17 main::@2 + b2: + //SEG18 [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] -- cowo1_staridx_zpby1=zpby2 + lda j + ldx i + sta SCREEN,x + //SEG19 [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] -- zpby1=_inc_zpby1 + inc j + //SEG20 [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] -- zpby1_neq_coby1_then_la1 + lda j + cmp #$65 + bne b2_from_b2 + jmp b5 + //SEG21 main::@5 + b5: + //SEG22 [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] -- zpby1=_inc_zpby1 + inc i + //SEG23 [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] -- zpby1_neq_coby1_then_la1 + lda i + cmp #$65 + bne b1_from_b5 + //SEG24 [9] phi from main::@5 to main::@3 [phi:main::@5->main::@3] + b3_from_b5: + //SEG25 [9] phi (byte) main::k#4 = (byte) 0 [phi:main::@5->main::@3#0] -- zpby1=coby1 + lda #0 + sta k + jmp b3 + //SEG26 [9] phi from main::@7 to main::@3 [phi:main::@7->main::@3] + b3_from_b7: + //SEG27 [9] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy + jmp b3 + //SEG28 main::@3 + b3: + //SEG29 [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + b4_from_b3: + //SEG30 [10] phi (byte) main::l#2 = (byte) 0 [phi:main::@3->main::@4#0] -- zpby1=coby1 + lda #0 + sta l + jmp b4 + //SEG31 [10] phi from main::@4 to main::@4 [phi:main::@4->main::@4] + b4_from_b4: + //SEG32 [10] phi (byte) main::l#2 = (byte) main::l#1 [phi:main::@4->main::@4#0] -- register_copy + jmp b4 + //SEG33 main::@4 + b4: + //SEG34 asm { eor#$55tax } + eor #$55 + tax + //SEG35 [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] -- cowo1_staridx_zpby1=zpby2 + lda l + ldx k + sta SCREEN,x + //SEG36 [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] -- zpby1=_inc_zpby1 + inc l + //SEG37 [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] -- zpby1_neq_coby1_then_la1 + lda l + cmp #$65 + bne b4_from_b4 + jmp b7 + //SEG38 main::@7 + b7: + //SEG39 [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] -- zpby1=_inc_zpby1 + inc k + //SEG40 [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] -- zpby1_neq_coby1_then_la1 + lda k + cmp #$65 + bne b3_from_b7 + jmp breturn + //SEG41 main::@return + breturn: + //SEG42 [17] return [ ] + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement asm { eor#$55tax } always clobbers reg byte a reg byte x +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::k#4 main::k#1 ] +Removing always clobbered register reg byte x as potential for zp ZP_BYTE:4 [ main::k#4 main::k#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ main::l#2 main::l#1 ] +Removing always clobbered register reg byte x as potential for zp ZP_BYTE:5 [ main::l#2 main::l#1 ] +Statement [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] always clobbers reg byte a +Statement asm { eor#$55tax } always clobbers reg byte a reg byte x +Statement [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] always clobbers reg byte a +Potential registers zp ZP_BYTE:2 [ main::i#4 main::i#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::j#2 main::j#1 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ main::k#4 main::k#1 ] : zp ZP_BYTE:4 , reg byte y , +Potential registers zp ZP_BYTE:5 [ main::l#2 main::l#1 ] : zp ZP_BYTE:5 , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 303: zp ZP_BYTE:3 [ main::j#2 main::j#1 ] 252.5: zp ZP_BYTE:5 [ main::l#2 main::l#1 ] 41.1: zp ZP_BYTE:2 [ main::i#4 main::i#1 ] 37: zp ZP_BYTE:4 [ main::k#4 main::k#1 ] +Uplift Scope [] + +Uplifting [main] best 6665 combination reg byte a [ main::j#2 main::j#1 ] zp ZP_BYTE:5 [ main::l#2 main::l#1 ] reg byte x [ main::i#4 main::i#1 ] reg byte y [ main::k#4 main::k#1 ] +Uplifting [] best 6665 combination +Attempting to uplift remaining variables inzp ZP_BYTE:5 [ main::l#2 main::l#1 ] +Uplifting [main] best 6665 combination zp ZP_BYTE:5 [ main::l#2 main::l#1 ] +Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:2 [ main::l#2 main::l#1 ] +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b5 +Removing instruction jmp b3 +Removing instruction jmp b4 +Removing instruction jmp b7 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +bbegin: +//SEG3 @1 +b1: +//SEG4 [0] call main param-assignment [ ] +//SEG5 [1] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG6 @end +bend: +//SEG7 main +main: { + .label l = 2 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG9 [2] phi (byte) main::i#4 = (byte) 0 [phi:main->main::@1#0] -- xby=coby1 + ldx #0 + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + b1_from_b5: + //SEG11 [2] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + //SEG14 [3] phi (byte) main::j#2 = (byte) 0 [phi:main::@1->main::@2#0] -- aby=coby1 + lda #0 + jmp b2 + //SEG15 [3] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + b2_from_b2: + //SEG16 [3] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@2->main::@2#0] -- register_copy + //SEG17 main::@2 + b2: + //SEG18 [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] -- cowo1_staridx_xby=aby + sta SCREEN,x + //SEG19 [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] -- aby=_inc_aby + clc + adc #1 + //SEG20 [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] -- aby_neq_coby1_then_la1 + cmp #$65 + bne b2_from_b2 + //SEG21 main::@5 + b5: + //SEG22 [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] -- xby=_inc_xby + inx + //SEG23 [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] -- xby_neq_coby1_then_la1 + cpx #$65 + bne b1_from_b5 + //SEG24 [9] phi from main::@5 to main::@3 [phi:main::@5->main::@3] + b3_from_b5: + //SEG25 [9] phi (byte) main::k#4 = (byte) 0 [phi:main::@5->main::@3#0] -- yby=coby1 + ldy #0 + jmp b3 + //SEG26 [9] phi from main::@7 to main::@3 [phi:main::@7->main::@3] + b3_from_b7: + //SEG27 [9] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy + //SEG28 main::@3 + b3: + //SEG29 [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + b4_from_b3: + //SEG30 [10] phi (byte) main::l#2 = (byte) 0 [phi:main::@3->main::@4#0] -- zpby1=coby1 + lda #0 + sta l + jmp b4 + //SEG31 [10] phi from main::@4 to main::@4 [phi:main::@4->main::@4] + b4_from_b4: + //SEG32 [10] phi (byte) main::l#2 = (byte) main::l#1 [phi:main::@4->main::@4#0] -- register_copy + //SEG33 main::@4 + b4: + //SEG34 asm { eor#$55tax } + eor #$55 + tax + //SEG35 [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] -- cowo1_staridx_yby=zpby1 + lda l + sta SCREEN,y + //SEG36 [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] -- zpby1=_inc_zpby1 + inc l + //SEG37 [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] -- zpby1_neq_coby1_then_la1 + lda l + cmp #$65 + bne b4_from_b4 + //SEG38 main::@7 + b7: + //SEG39 [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] -- yby=_inc_yby + iny + //SEG40 [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] -- yby_neq_coby1_then_la1 + cpy #$65 + bne b3_from_b7 + //SEG41 main::@return + breturn: + //SEG42 [17] return [ ] + rts +} + +Replacing label b2_from_b2 with b2 +Replacing label b1_from_b5 with b1 +Replacing label b4_from_b4 with b4 +Replacing label b3_from_b7 with b3 +Removing instruction bbegin: +Removing instruction main_from_b1: +Removing instruction b1_from_b5: +Removing instruction b2_from_b1: +Removing instruction b2_from_b2: +Removing instruction b3_from_b7: +Removing instruction b4_from_b3: +Removing instruction b4_from_b4: +Succesful ASM optimization Pass5RedundantLabelElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @1 +b1: +//SEG4 [0] call main param-assignment [ ] +//SEG5 [1] phi from @1 to main [phi:@1->main] + jsr main +//SEG6 @end +bend: +//SEG7 main +main: { + .label l = 2 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG9 [2] phi (byte) main::i#4 = (byte) 0 [phi:main->main::@1#0] -- xby=coby1 + ldx #0 + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG14 [3] phi (byte) main::j#2 = (byte) 0 [phi:main::@1->main::@2#0] -- aby=coby1 + lda #0 + jmp b2 + //SEG15 [3] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + //SEG16 [3] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@2->main::@2#0] -- register_copy + //SEG17 main::@2 + b2: + //SEG18 [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] -- cowo1_staridx_xby=aby + sta SCREEN,x + //SEG19 [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] -- aby=_inc_aby + clc + adc #1 + //SEG20 [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] -- aby_neq_coby1_then_la1 + cmp #$65 + bne b2 + //SEG21 main::@5 + b5: + //SEG22 [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] -- xby=_inc_xby + inx + //SEG23 [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] -- xby_neq_coby1_then_la1 + cpx #$65 + bne b1 + //SEG24 [9] phi from main::@5 to main::@3 [phi:main::@5->main::@3] + b3_from_b5: + //SEG25 [9] phi (byte) main::k#4 = (byte) 0 [phi:main::@5->main::@3#0] -- yby=coby1 + ldy #0 + jmp b3 + //SEG26 [9] phi from main::@7 to main::@3 [phi:main::@7->main::@3] + //SEG27 [9] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy + //SEG28 main::@3 + b3: + //SEG29 [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + //SEG30 [10] phi (byte) main::l#2 = (byte) 0 [phi:main::@3->main::@4#0] -- zpby1=coby1 + lda #0 + sta l + jmp b4 + //SEG31 [10] phi from main::@4 to main::@4 [phi:main::@4->main::@4] + //SEG32 [10] phi (byte) main::l#2 = (byte) main::l#1 [phi:main::@4->main::@4#0] -- register_copy + //SEG33 main::@4 + b4: + //SEG34 asm { eor#$55tax } + eor #$55 + tax + //SEG35 [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] -- cowo1_staridx_yby=zpby1 + lda l + sta SCREEN,y + //SEG36 [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] -- zpby1=_inc_zpby1 + inc l + //SEG37 [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] -- zpby1_neq_coby1_then_la1 + lda l + cmp #$65 + bne b4 + //SEG38 main::@7 + b7: + //SEG39 [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] -- yby=_inc_yby + iny + //SEG40 [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] -- yby_neq_coby1_then_la1 + cpy #$65 + bne b3 + //SEG41 main::@return + breturn: + //SEG42 [17] return [ ] + rts +} + +Removing instruction b1: +Removing instruction bend: +Removing instruction b1_from_main: +Removing instruction b5: +Removing instruction b3_from_b5: +Removing instruction b7: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @1 +//SEG4 [0] call main param-assignment [ ] +//SEG5 [1] phi from @1 to main [phi:@1->main] + jsr main +//SEG6 @end +//SEG7 main +main: { + .label l = 2 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + //SEG9 [2] phi (byte) main::i#4 = (byte) 0 [phi:main->main::@1#0] -- xby=coby1 + ldx #0 + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG14 [3] phi (byte) main::j#2 = (byte) 0 [phi:main::@1->main::@2#0] -- aby=coby1 + lda #0 + jmp b2 + //SEG15 [3] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + //SEG16 [3] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@2->main::@2#0] -- register_copy + //SEG17 main::@2 + b2: + //SEG18 [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] -- cowo1_staridx_xby=aby + sta SCREEN,x + //SEG19 [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] -- aby=_inc_aby + clc + adc #1 + //SEG20 [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] -- aby_neq_coby1_then_la1 + cmp #$65 + bne b2 + //SEG21 main::@5 + //SEG22 [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] -- xby=_inc_xby + inx + //SEG23 [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] -- xby_neq_coby1_then_la1 + cpx #$65 + bne b1 + //SEG24 [9] phi from main::@5 to main::@3 [phi:main::@5->main::@3] + //SEG25 [9] phi (byte) main::k#4 = (byte) 0 [phi:main::@5->main::@3#0] -- yby=coby1 + ldy #0 + jmp b3 + //SEG26 [9] phi from main::@7 to main::@3 [phi:main::@7->main::@3] + //SEG27 [9] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy + //SEG28 main::@3 + b3: + //SEG29 [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + //SEG30 [10] phi (byte) main::l#2 = (byte) 0 [phi:main::@3->main::@4#0] -- zpby1=coby1 + lda #0 + sta l + jmp b4 + //SEG31 [10] phi from main::@4 to main::@4 [phi:main::@4->main::@4] + //SEG32 [10] phi (byte) main::l#2 = (byte) main::l#1 [phi:main::@4->main::@4#0] -- register_copy + //SEG33 main::@4 + b4: + //SEG34 asm { eor#$55tax } + eor #$55 + tax + //SEG35 [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] -- cowo1_staridx_yby=zpby1 + lda l + sta SCREEN,y + //SEG36 [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] -- zpby1=_inc_zpby1 + inc l + //SEG37 [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] -- zpby1_neq_coby1_then_la1 + lda l + cmp #$65 + bne b4 + //SEG38 main::@7 + //SEG39 [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] -- yby=_inc_yby + iny + //SEG40 [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] -- yby_neq_coby1_then_la1 + cpy #$65 + bne b3 + //SEG41 main::@return + //SEG42 [17] return [ ] + rts +} + +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp b4 +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @1 +//SEG4 [0] call main param-assignment [ ] +//SEG5 [1] phi from @1 to main [phi:@1->main] + jsr main +//SEG6 @end +//SEG7 main +main: { + .label l = 2 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + //SEG9 [2] phi (byte) main::i#4 = (byte) 0 [phi:main->main::@1#0] -- xby=coby1 + ldx #0 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG14 [3] phi (byte) main::j#2 = (byte) 0 [phi:main::@1->main::@2#0] -- aby=coby1 + lda #0 + //SEG15 [3] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + //SEG16 [3] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@2->main::@2#0] -- register_copy + //SEG17 main::@2 + b2: + //SEG18 [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] -- cowo1_staridx_xby=aby + sta SCREEN,x + //SEG19 [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] -- aby=_inc_aby + clc + adc #1 + //SEG20 [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] -- aby_neq_coby1_then_la1 + cmp #$65 + bne b2 + //SEG21 main::@5 + //SEG22 [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] -- xby=_inc_xby + inx + //SEG23 [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] -- xby_neq_coby1_then_la1 + cpx #$65 + bne b1 + //SEG24 [9] phi from main::@5 to main::@3 [phi:main::@5->main::@3] + //SEG25 [9] phi (byte) main::k#4 = (byte) 0 [phi:main::@5->main::@3#0] -- yby=coby1 + ldy #0 + //SEG26 [9] phi from main::@7 to main::@3 [phi:main::@7->main::@3] + //SEG27 [9] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy + //SEG28 main::@3 + b3: + //SEG29 [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + //SEG30 [10] phi (byte) main::l#2 = (byte) 0 [phi:main::@3->main::@4#0] -- zpby1=coby1 + lda #0 + sta l + //SEG31 [10] phi from main::@4 to main::@4 [phi:main::@4->main::@4] + //SEG32 [10] phi (byte) main::l#2 = (byte) main::l#1 [phi:main::@4->main::@4#0] -- register_copy + //SEG33 main::@4 + b4: + //SEG34 asm { eor#$55tax } + eor #$55 + tax + //SEG35 [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] -- cowo1_staridx_yby=zpby1 + lda l + sta SCREEN,y + //SEG36 [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] -- zpby1=_inc_zpby1 + inc l + //SEG37 [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] -- zpby1_neq_coby1_then_la1 + lda l + cmp #$65 + bne b4 + //SEG38 main::@7 + //SEG39 [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] -- yby=_inc_yby + iny + //SEG40 [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] -- yby_neq_coby1_then_la1 + cpy #$65 + bne b3 + //SEG41 main::@return + //SEG42 [17] return [ ] + rts +} + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = (word) 1024 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@7 +(label) main::@return +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#4 reg byte x 24.599999999999998 +(byte) main::j +(byte) main::j#1 reg byte a 151.5 +(byte) main::j#2 reg byte a 151.5 +(byte) main::k +(byte) main::k#1 reg byte y 16.5 +(byte) main::k#4 reg byte y 20.499999999999996 +(byte) main::l +(byte) main::l#1 l zp ZP_BYTE:2 151.5 +(byte) main::l#2 l zp ZP_BYTE:2 101.0 + +reg byte x [ main::i#4 main::i#1 ] +reg byte a [ main::j#2 main::j#1 ] +reg byte y [ main::k#4 main::k#1 ] +zp ZP_BYTE:2 [ main::l#2 main::l#1 ] + +FINAL CODE +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @1 +//SEG4 [0] call main param-assignment [ ] +//SEG5 [1] phi from @1 to main [phi:@1->main] + jsr main +//SEG6 @end +//SEG7 main +main: { + .label l = 2 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + //SEG9 [2] phi (byte) main::i#4 = (byte) 0 [phi:main->main::@1#0] -- xby=coby1 + ldx #0 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#4 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG14 [3] phi (byte) main::j#2 = (byte) 0 [phi:main::@1->main::@2#0] -- aby=coby1 + lda #0 + //SEG15 [3] phi from main::@2 to main::@2 [phi:main::@2->main::@2] + //SEG16 [3] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@2->main::@2#0] -- register_copy + //SEG17 main::@2 + b2: + //SEG18 [4] *((const byte*) SCREEN#0 + (byte) main::i#4) ← (byte) main::j#2 [ main::i#4 main::j#2 ] -- cowo1_staridx_xby=aby + sta SCREEN,x + //SEG19 [5] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::i#4 main::j#1 ] -- aby=_inc_aby + clc + adc #1 + //SEG20 [6] if((byte) main::j#1!=(byte) 101) goto main::@2 [ main::i#4 main::j#1 ] -- aby_neq_coby1_then_la1 + cmp #$65 + bne b2 + //SEG21 main::@5 + //SEG22 [7] (byte) main::i#1 ← ++ (byte) main::i#4 [ main::i#1 ] -- xby=_inc_xby + inx + //SEG23 [8] if((byte) main::i#1!=(byte) 101) goto main::@1 [ main::i#1 ] -- xby_neq_coby1_then_la1 + cpx #$65 + bne b1 + //SEG24 [9] phi from main::@5 to main::@3 [phi:main::@5->main::@3] + //SEG25 [9] phi (byte) main::k#4 = (byte) 0 [phi:main::@5->main::@3#0] -- yby=coby1 + ldy #0 + //SEG26 [9] phi from main::@7 to main::@3 [phi:main::@7->main::@3] + //SEG27 [9] phi (byte) main::k#4 = (byte) main::k#1 [phi:main::@7->main::@3#0] -- register_copy + //SEG28 main::@3 + b3: + //SEG29 [10] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + //SEG30 [10] phi (byte) main::l#2 = (byte) 0 [phi:main::@3->main::@4#0] -- zpby1=coby1 + lda #0 + sta l + //SEG31 [10] phi from main::@4 to main::@4 [phi:main::@4->main::@4] + //SEG32 [10] phi (byte) main::l#2 = (byte) main::l#1 [phi:main::@4->main::@4#0] -- register_copy + //SEG33 main::@4 + b4: + //SEG34 asm { eor#$55tax } + eor #$55 + tax + //SEG35 [12] *((const byte*) SCREEN#0 + (byte) main::k#4) ← (byte) main::l#2 [ main::k#4 main::l#2 ] -- cowo1_staridx_yby=zpby1 + lda l + sta SCREEN,y + //SEG36 [13] (byte) main::l#1 ← ++ (byte) main::l#2 [ main::k#4 main::l#1 ] -- zpby1=_inc_zpby1 + inc l + //SEG37 [14] if((byte) main::l#1!=(byte) 101) goto main::@4 [ main::k#4 main::l#1 ] -- zpby1_neq_coby1_then_la1 + lda l + cmp #$65 + bne b4 + //SEG38 main::@7 + //SEG39 [15] (byte) main::k#1 ← ++ (byte) main::k#4 [ main::k#1 ] -- yby=_inc_yby + iny + //SEG40 [16] if((byte) main::k#1!=(byte) 101) goto main::@3 [ main::k#1 ] -- yby_neq_coby1_then_la1 + cpy #$65 + bne b3 + //SEG41 main::@return + //SEG42 [17] return [ ] + rts +} + diff --git a/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.sym b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.sym new file mode 100644 index 000000000..edf1055ec --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/asm-clobber.sym @@ -0,0 +1,30 @@ +(label) @1 +(label) @begin +(label) @end +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = (word) 1024 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@7 +(label) main::@return +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#4 reg byte x 24.599999999999998 +(byte) main::j +(byte) main::j#1 reg byte a 151.5 +(byte) main::j#2 reg byte a 151.5 +(byte) main::k +(byte) main::k#1 reg byte y 16.5 +(byte) main::k#4 reg byte y 20.499999999999996 +(byte) main::l +(byte) main::l#1 l zp ZP_BYTE:2 151.5 +(byte) main::l#2 l zp ZP_BYTE:2 101.0 + +reg byte x [ main::i#4 main::i#1 ] +reg byte a [ main::j#2 main::j#1 ] +reg byte y [ main::k#4 main::k#1 ] +zp ZP_BYTE:2 [ main::l#2 main::l#1 ]