diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 8fe19db8f..a47d4a43e 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -45,10 +45,14 @@ public class TestPrograms { } @Test - public void testInterruptVolatileReuseProblem() throws IOException, URISyntaxException { - compileAndCompare("interrupt-volatile-reuse-problem"); + public void testInterruptVolatileReuseProblem2() throws IOException, URISyntaxException { + compileAndCompare("interrupt-volatile-reuse-problem2"); } + @Test + public void testInterruptVolatileReuseProblem1() throws IOException, URISyntaxException { + compileAndCompare("interrupt-volatile-reuse-problem1"); + } @Test public void testInitVolatiles() throws IOException, URISyntaxException { diff --git a/src/test/kc/interrupt-volatile-reuse-problem.kc b/src/test/kc/interrupt-volatile-reuse-problem.kc deleted file mode 100644 index 8a034c5f4..000000000 --- a/src/test/kc/interrupt-volatile-reuse-problem.kc +++ /dev/null @@ -1,28 +0,0 @@ -// Illustrates problem where volatiles reuse ZP addresses of other variables - and reuses the same address for multiple volatiles -const void()** KERNEL_IRQ = $0314; -const byte* BORDERCOL = $d021; -const byte* BGCOL = $d020; -volatile byte col1 = 0; -volatile byte col2 = 8; -void main() { - byte* SCREEN=$400; - byte qwe = 32; - byte asd = 0; - byte row = 12; - for(byte x:0..10) { - SCREEN[x] = ++row; - ++qwe; - asd += qwe; - } - SCREEN[0] = qwe; - SCREEN[1] = asd; - *KERNEL_IRQ = &irq; -} - -interrupt(kernel_min) void irq() { - asm { - lda $dc0d - } - *BGCOL = col1++; - *BORDERCOL = col2++; -} diff --git a/src/test/kc/interrupt-volatile-reuse-problem1.kc b/src/test/kc/interrupt-volatile-reuse-problem1.kc new file mode 100644 index 000000000..cca1b6c6a --- /dev/null +++ b/src/test/kc/interrupt-volatile-reuse-problem1.kc @@ -0,0 +1,14 @@ +// Illustrates problem where volatiles reuse the same ZP addresses for multiple overlapping volatiles +const void()** KERNEL_IRQ = $0314; +const byte* SCREEN=$400; +volatile byte col1 = 0; +volatile byte col2 = 8; + +void main() { + *KERNEL_IRQ = &irq; +} + +interrupt void irq() { + SCREEN[40] = col1++; + SCREEN[41] = col2++; +} diff --git a/src/test/kc/interrupt-volatile-reuse-problem2.kc b/src/test/kc/interrupt-volatile-reuse-problem2.kc new file mode 100644 index 000000000..3ba57d6fa --- /dev/null +++ b/src/test/kc/interrupt-volatile-reuse-problem2.kc @@ -0,0 +1,27 @@ +// Illustrates problem where volatiles reuse ZP addresses of other variables +const void()** KERNEL_IRQ = $0314; +const byte* IRQ_STATUS = $d019; +const byte* CIA1_INTERRUPT = $dc0d; + +const byte* SCREEN=$400; +volatile byte col1 = 0; + +void main() { + *KERNEL_IRQ = &irq; + while(true) { + for(byte x: 0..10) { + for(byte y: 0..10) { + for (byte a:0..10) { + SCREEN[x] = a+y; + } + } + } + } +} + +interrupt void irq() { + // Acknowledge the IRQ + *IRQ_STATUS = 1; + asm { lda $dc0d } + SCREEN[40] = col1++; +} diff --git a/src/test/ref/interrupt-volatile-reuse-problem.asm b/src/test/ref/interrupt-volatile-reuse-problem.asm deleted file mode 100644 index 357bfdaca..000000000 --- a/src/test/ref/interrupt-volatile-reuse-problem.asm +++ /dev/null @@ -1,53 +0,0 @@ -.pc = $801 "Basic" -:BasicUpstart(main) -.pc = $80d "Program" - .label KERNEL_IRQ = $314 - .label BORDERCOL = $d021 - .label BGCOL = $d020 - .label col1 = 2 - .label col2 = 2 - lda #0 - sta col1 - lda #8 - sta col2 - jsr main -main: { - .label SCREEN = $400 - .label row = 2 - .label asd = 3 - lda #0 - sta asd - ldx #$20 - tay - lda #$c - sta row - b1: - inc row - lda row - sta SCREEN,y - inx - txa - clc - adc asd - sta asd - iny - cpy #$b - bne b1 - stx SCREEN - sta SCREEN+1 - lda #irq - sta KERNEL_IRQ+1 - rts -} -irq: { - lda $dc0d - lda col1 - sta BGCOL - inc col1 - lda col2 - sta BORDERCOL - inc col2 - jmp $ea81 -} diff --git a/src/test/ref/interrupt-volatile-reuse-problem.cfg b/src/test/ref/interrupt-volatile-reuse-problem.cfg deleted file mode 100644 index 8b3b76c80..000000000 --- a/src/test/ref/interrupt-volatile-reuse-problem.cfg +++ /dev/null @@ -1,43 +0,0 @@ -@begin: scope:[] from - [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 - [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 - to:@2 -@2: scope:[] from @begin - [2] phi() - [3] call main - to:@end -@end: scope:[] from @2 - [4] phi() -main: scope:[main] from @2 - [5] phi() - to:main::@1 -main::@1: scope:[main] from main main::@1 - [6] (byte) main::asd#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::asd#1 ) - [6] (byte) main::qwe#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 32 main::@1/(byte) main::qwe#1 ) - [6] (byte) main::x#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::x#1 ) - [6] (byte) main::row#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 12 main::@1/(byte) main::row#1 ) - [7] (byte) main::row#1 ← ++ (byte) main::row#2 - [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 - [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 - [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 - [11] (byte) main::x#1 ← ++ (byte) main::x#2 - [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 - to:main::@2 -main::@2: scope:[main] from main::@1 - [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 - [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 - [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() - to:main::@return -main::@return: scope:[main] from main::@2 - [16] return - to:@return -irq: scope:[irq] from - asm { lda$dc0d } - [18] *((const byte*) BGCOL#0) ← (byte) col1#0 - [19] (byte) col1#1 ← ++ (byte) col1#0 - [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 - [21] (byte) col2#1 ← ++ (byte) col2#0 - to:irq::@return -irq::@return: scope:[irq] from irq - [22] return - to:@return diff --git a/src/test/ref/interrupt-volatile-reuse-problem.log b/src/test/ref/interrupt-volatile-reuse-problem.log deleted file mode 100644 index d144f050d..000000000 --- a/src/test/ref/interrupt-volatile-reuse-problem.log +++ /dev/null @@ -1,775 +0,0 @@ -Resolved forward reference irq to interrupt(KERNEL_MIN)(void()) irq() - -CONTROL FLOW GRAPH SSA -@begin: scope:[] from - (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 - (byte*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) 53281 - (byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53280 - (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 - (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 - to:@2 -main: scope:[main] from @2 - (byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024 - (byte) main::qwe#0 ← (byte/signed byte/word/signed word/dword/signed dword) 32 - (byte) main::asd#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 - (byte) main::row#0 ← (byte/signed byte/word/signed word/dword/signed dword) 12 - (byte) main::x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 - to:main::@1 -main::@1: scope:[main] from main main::@1 - (byte) main::asd#2 ← phi( main/(byte) main::asd#0 main::@1/(byte) main::asd#1 ) - (byte) main::qwe#2 ← phi( main/(byte) main::qwe#0 main::@1/(byte) main::qwe#1 ) - (byte) main::x#2 ← phi( main/(byte) main::x#0 main::@1/(byte) main::x#1 ) - (byte*) main::SCREEN#1 ← phi( main/(byte*) main::SCREEN#0 main::@1/(byte*) main::SCREEN#1 ) - (byte) main::row#2 ← phi( main/(byte) main::row#0 main::@1/(byte) main::row#1 ) - (byte) main::row#1 ← ++ (byte) main::row#2 - *((byte*) main::SCREEN#1 + (byte) main::x#2) ← (byte) main::row#1 - (byte) main::qwe#1 ← ++ (byte) main::qwe#2 - (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 - (byte) main::x#1 ← (byte) main::x#2 + rangenext(0,10) - (bool~) main::$0 ← (byte) main::x#1 != rangelast(0,10) - if((bool~) main::$0) goto main::@1 - to:main::@2 -main::@2: scope:[main] from main::@1 - (byte) main::asd#3 ← phi( main::@1/(byte) main::asd#1 ) - (byte*) main::SCREEN#2 ← phi( main::@1/(byte*) main::SCREEN#1 ) - (byte) main::qwe#3 ← phi( main::@1/(byte) main::qwe#1 ) - *((byte*) main::SCREEN#2 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← (byte) main::qwe#3 - *((byte*) main::SCREEN#2 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#3 - (void()*~) main::$1 ← & interrupt(KERNEL_MIN)(void()) irq() - *((void()**) KERNEL_IRQ#0) ← (void()*~) main::$1 - to:main::@return -main::@return: scope:[main] from main::@2 - return - to:@return -irq: scope:[irq] from - (byte) col2#3 ← phi( @2/(byte) col2#5 ) - (byte) col1#3 ← phi( @2/(byte) col1#5 ) - asm { lda$dc0d } - *((byte*) BGCOL#0) ← (byte) col1#3 - (byte) col1#1 ← ++ (byte) col1#3 - *((byte*) BORDERCOL#0) ← (byte) col2#3 - (byte) col2#1 ← ++ (byte) col2#3 - to:irq::@return -irq::@return: scope:[irq] from irq - (byte) col2#4 ← phi( irq/(byte) col2#1 ) - (byte) col1#4 ← phi( irq/(byte) col1#1 ) - (byte) col1#2 ← (byte) col1#4 - (byte) col2#2 ← (byte) col2#4 - return - to:@return -@2: scope:[] from @begin - (byte) col2#5 ← phi( @begin/(byte) col2#0 ) - (byte) col1#5 ← phi( @begin/(byte) col1#0 ) - call main - to:@3 -@3: scope:[] from @2 - to:@end -@end: scope:[] from @3 - -SYMBOL TABLE SSA -(label) @2 -(label) @3 -(label) @begin -(label) @end -(byte*) BGCOL -(byte*) BGCOL#0 -(byte*) BORDERCOL -(byte*) BORDERCOL#0 -(void()**) KERNEL_IRQ -(void()**) KERNEL_IRQ#0 -(byte) col1 -(byte) col1#0 -(byte) col1#1 -(byte) col1#2 -(byte) col1#3 -(byte) col1#4 -(byte) col1#5 -(byte) col2 -(byte) col2#0 -(byte) col2#1 -(byte) col2#2 -(byte) col2#3 -(byte) col2#4 -(byte) col2#5 -interrupt(KERNEL_MIN)(void()) irq() -(label) irq::@return -(void()) main() -(bool~) main::$0 -(void()*~) main::$1 -(label) main::@1 -(label) main::@2 -(label) main::@return -(byte*) main::SCREEN -(byte*) main::SCREEN#0 -(byte*) main::SCREEN#1 -(byte*) main::SCREEN#2 -(byte) main::asd -(byte) main::asd#0 -(byte) main::asd#1 -(byte) main::asd#2 -(byte) main::asd#3 -(byte) main::qwe -(byte) main::qwe#0 -(byte) main::qwe#1 -(byte) main::qwe#2 -(byte) main::qwe#3 -(byte) main::row -(byte) main::row#0 -(byte) main::row#1 -(byte) main::row#2 -(byte) main::x -(byte) main::x#0 -(byte) main::x#1 -(byte) main::x#2 - -Culled Empty Block (label) @3 -Successful SSA optimization Pass2CullEmptyBlocks -Alias (byte) main::qwe#1 = (byte) main::qwe#3 -Alias (byte*) main::SCREEN#1 = (byte*) main::SCREEN#2 -Alias (byte) main::asd#1 = (byte) main::asd#3 -Alias (byte) col1#1 = (byte) col1#4 (byte) col1#2 -Alias (byte) col2#1 = (byte) col2#4 (byte) col2#2 -Alias (byte) col1#0 = (byte) col1#5 -Alias (byte) col2#0 = (byte) col2#5 -Successful SSA optimization Pass2AliasElimination -Self Phi Eliminated (byte*) main::SCREEN#1 -Successful SSA optimization Pass2SelfPhiElimination -Redundant Phi (byte*) main::SCREEN#1 (byte*) main::SCREEN#0 -Redundant Phi (byte) col1#3 (byte) col1#0 -Redundant Phi (byte) col2#3 (byte) col2#0 -Successful SSA optimization Pass2RedundantPhiElimination -Simple Condition (bool~) main::$0 if((byte) main::x#1!=rangelast(0,10)) goto main::@1 -Successful SSA optimization Pass2ConditionalJumpSimplification -Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 -Constant (const byte*) BORDERCOL#0 = ((byte*))53281 -Constant (const byte*) BGCOL#0 = ((byte*))53280 -Constant (const byte*) main::SCREEN#0 = ((byte*))1024 -Constant (const byte) main::qwe#0 = 32 -Constant (const byte) main::asd#0 = 0 -Constant (const byte) main::row#0 = 12 -Constant (const byte) main::x#0 = 0 -Constant (const void()*) main::$1 = &irq -Successful SSA optimization Pass2ConstantIdentification -Consolidated array index constant in *(main::SCREEN#0+0) -Consolidated array index constant in *(main::SCREEN#0+1) -Successful SSA optimization Pass2ConstantAdditionElimination -Resolved ranged next value main::x#1 ← ++ main::x#2 to ++ -Resolved ranged comparison value if(main::x#1!=rangelast(0,10)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 11 -Inlining constant with var siblings (const byte) main::qwe#0 -Inlining constant with var siblings (const byte) main::asd#0 -Inlining constant with var siblings (const byte) main::row#0 -Inlining constant with var siblings (const byte) main::x#0 -Constant inlined main::qwe#0 = (byte/signed byte/word/signed word/dword/signed dword) 32 -Constant inlined main::x#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 -Constant inlined main::asd#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 -Constant inlined main::$1 = &interrupt(KERNEL_MIN)(void()) irq() -Constant inlined main::row#0 = (byte/signed byte/word/signed word/dword/signed dword) 12 -Successful SSA optimization Pass2ConstantInlining -Simplifying constant plus zero main::SCREEN#0+0 -Added new block during phi lifting main::@3(between main::@1 and main::@1) -Adding NOP phi() at start of @2 -Adding NOP phi() at start of @end -Adding NOP phi() at start of main -CALL GRAPH -Calls in [] to main:3 - -Created 4 initial phi equivalence classes -Coalesced [17] main::row#3 ← main::row#1 -Coalesced [18] main::x#3 ← main::x#1 -Coalesced [19] main::qwe#4 ← main::qwe#1 -Coalesced [20] main::asd#4 ← main::asd#1 -Coalesced down to 4 phi equivalence classes -Culled Empty Block (label) main::@3 -Adding NOP phi() at start of @2 -Adding NOP phi() at start of @end -Adding NOP phi() at start of main - -FINAL CONTROL FLOW GRAPH -@begin: scope:[] from - [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 - [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 - to:@2 -@2: scope:[] from @begin - [2] phi() - [3] call main - to:@end -@end: scope:[] from @2 - [4] phi() -main: scope:[main] from @2 - [5] phi() - to:main::@1 -main::@1: scope:[main] from main main::@1 - [6] (byte) main::asd#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::asd#1 ) - [6] (byte) main::qwe#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 32 main::@1/(byte) main::qwe#1 ) - [6] (byte) main::x#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::x#1 ) - [6] (byte) main::row#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 12 main::@1/(byte) main::row#1 ) - [7] (byte) main::row#1 ← ++ (byte) main::row#2 - [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 - [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 - [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 - [11] (byte) main::x#1 ← ++ (byte) main::x#2 - [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 - to:main::@2 -main::@2: scope:[main] from main::@1 - [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 - [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 - [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() - to:main::@return -main::@return: scope:[main] from main::@2 - [16] return - to:@return -irq: scope:[irq] from - asm { lda$dc0d } - [18] *((const byte*) BGCOL#0) ← (byte) col1#0 - [19] (byte) col1#1 ← ++ (byte) col1#0 - [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 - [21] (byte) col2#1 ← ++ (byte) col2#0 - to:irq::@return -irq::@return: scope:[irq] from irq - [22] return - to:@return - - -VARIABLE REGISTER WEIGHTS -(byte*) BGCOL -(byte*) BORDERCOL -(void()**) KERNEL_IRQ -(byte) col1 -(byte) col1#0 3.0 -(byte) col1#1 20.0 -(byte) col2 -(byte) col2#0 1.5 -(byte) col2#1 20.0 -interrupt(KERNEL_MIN)(void()) irq() -(void()) main() -(byte*) main::SCREEN -(byte) main::asd -(byte) main::asd#1 6.0 -(byte) main::asd#2 5.5 -(byte) main::qwe -(byte) main::qwe#1 8.75 -(byte) main::qwe#2 7.333333333333333 -(byte) main::row -(byte) main::row#1 5.5 -(byte) main::row#2 22.0 -(byte) main::x -(byte) main::x#1 16.5 -(byte) main::x#2 6.6000000000000005 - -Initial phi equivalence classes -[ main::row#2 main::row#1 ] -[ main::x#2 main::x#1 ] -[ main::qwe#2 main::qwe#1 ] -[ main::asd#2 main::asd#1 ] -Added variable col1#0 to zero page equivalence class [ col1#0 ] -Added variable col2#0 to zero page equivalence class [ col2#0 ] -Added variable col1#1 to zero page equivalence class [ col1#1 ] -Added variable col2#1 to zero page equivalence class [ col2#1 ] -Complete equivalence classes -[ main::row#2 main::row#1 ] -[ main::x#2 main::x#1 ] -[ main::qwe#2 main::qwe#1 ] -[ main::asd#2 main::asd#1 ] -[ col1#0 ] -[ col2#0 ] -[ col1#1 ] -[ col2#1 ] -Allocated zp ZP_BYTE:2 [ main::row#2 main::row#1 ] -Allocated zp ZP_BYTE:3 [ main::x#2 main::x#1 ] -Allocated zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ] -Allocated zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] -Allocated zp ZP_BYTE:6 [ col1#0 ] -Allocated zp ZP_BYTE:7 [ col2#0 ] -Allocated zp ZP_BYTE:8 [ col1#1 ] -Allocated zp ZP_BYTE:9 [ col2#1 ] - -INITIAL ASM -//SEG0 Basic Upstart -.pc = $801 "Basic" -:BasicUpstart(main) -.pc = $80d "Program" -//SEG1 Global Constants & labels - .label KERNEL_IRQ = $314 - .label BORDERCOL = $d021 - .label BGCOL = $d020 - .label col1 = 6 - .label col2 = 7 - .label col1_1 = 8 - .label col2_1 = 9 -//SEG2 @begin -bbegin: -//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 - lda #0 - sta col1 -//SEG4 [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuz1=vbuc1 - lda #8 - sta col2 -//SEG5 [2] phi from @begin to @2 [phi:@begin->@2] -b2_from_bbegin: - jmp b2 -//SEG6 @2 -b2: -//SEG7 [3] call main -//SEG8 [5] phi from @2 to main [phi:@2->main] -main_from_b2: - jsr main -//SEG9 [4] phi from @2 to @end [phi:@2->@end] -bend_from_b2: - jmp bend -//SEG10 @end -bend: -//SEG11 main -main: { - .label SCREEN = $400 - .label row = 2 - .label qwe = 4 - .label asd = 5 - .label x = 3 - //SEG12 [6] phi from main to main::@1 [phi:main->main::@1] - b1_from_main: - //SEG13 [6] phi (byte) main::asd#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 - lda #0 - sta asd - //SEG14 [6] phi (byte) main::qwe#2 = (byte/signed byte/word/signed word/dword/signed dword) 32 [phi:main->main::@1#1] -- vbuz1=vbuc1 - lda #$20 - sta qwe - //SEG15 [6] phi (byte) main::x#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#2] -- vbuz1=vbuc1 - lda #0 - sta x - //SEG16 [6] phi (byte) main::row#2 = (byte/signed byte/word/signed word/dword/signed dword) 12 [phi:main->main::@1#3] -- vbuz1=vbuc1 - lda #$c - sta row - jmp b1 - //SEG17 [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1] - b1_from_b1: - //SEG18 [6] phi (byte) main::asd#2 = (byte) main::asd#1 [phi:main::@1->main::@1#0] -- register_copy - //SEG19 [6] phi (byte) main::qwe#2 = (byte) main::qwe#1 [phi:main::@1->main::@1#1] -- register_copy - //SEG20 [6] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@1->main::@1#2] -- register_copy - //SEG21 [6] phi (byte) main::row#2 = (byte) main::row#1 [phi:main::@1->main::@1#3] -- register_copy - jmp b1 - //SEG22 main::@1 - b1: - //SEG23 [7] (byte) main::row#1 ← ++ (byte) main::row#2 -- vbuz1=_inc_vbuz1 - inc row - //SEG24 [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 -- pbuc1_derefidx_vbuz1=vbuz2 - lda row - ldy x - sta SCREEN,y - //SEG25 [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 -- vbuz1=_inc_vbuz1 - inc qwe - //SEG26 [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 -- vbuz1=vbuz1_plus_vbuz2 - lda asd - clc - adc qwe - sta asd - //SEG27 [11] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuz1=_inc_vbuz1 - inc x - //SEG28 [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 - lda x - cmp #$b - bne b1_from_b1 - jmp b2 - //SEG29 main::@2 - b2: - //SEG30 [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 -- _deref_pbuc1=vbuz1 - lda qwe - sta SCREEN - //SEG31 [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 -- _deref_pbuc1=vbuz1 - lda asd - sta SCREEN+1 - //SEG32 [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 - lda #irq - sta KERNEL_IRQ+1 - jmp breturn - //SEG33 main::@return - breturn: - //SEG34 [16] return - rts -} -//SEG35 irq -irq: { - //SEG36 entry interrupt(KERNEL_MIN) - //SEG37 asm { lda$dc0d } - lda $dc0d - //SEG38 [18] *((const byte*) BGCOL#0) ← (byte) col1#0 -- _deref_pbuc1=vbuz1 - lda col1 - sta BGCOL - //SEG39 [19] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz2 - ldy col1 - iny - sty col1_1 - //SEG40 [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 -- _deref_pbuc1=vbuz1 - lda col2 - sta BORDERCOL - //SEG41 [21] (byte) col2#1 ← ++ (byte) col2#0 -- vbuz1=_inc_vbuz2 - ldy col2 - iny - sty col2_1 - jmp breturn - //SEG42 irq::@return - breturn: - //SEG43 [22] return - exit interrupt(KERNEL_MIN) - jmp $ea81 -} - -REGISTER UPLIFT POTENTIAL REGISTERS -Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a -Statement [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 [ ] ( ) always clobbers reg byte a -Statement [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ( main:3 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::x#2 main::x#1 ] -Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::row#2 main::row#1 ] -Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ] -Statement [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a -Statement asm { lda$dc0d } always clobbers reg byte a -Statement [18] *((const byte*) BGCOL#0) ← (byte) col1#0 [ col1#0 col2#0 ] ( ) always clobbers reg byte a -Statement [19] (byte) col1#1 ← ++ (byte) col1#0 [ col2#0 ] ( ) always clobbers reg byte y -Statement [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 [ col2#0 ] ( ) always clobbers reg byte a -Statement [21] (byte) col2#1 ← ++ (byte) col2#0 [ ] ( ) always clobbers reg byte y -Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a -Statement [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 [ ] ( ) always clobbers reg byte a -Statement [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ( main:3 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] -Statement [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ( main:3 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ) always clobbers reg byte a -Statement [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a -Statement asm { lda$dc0d } always clobbers reg byte a -Statement [18] *((const byte*) BGCOL#0) ← (byte) col1#0 [ col1#0 col2#0 ] ( ) always clobbers reg byte a -Statement [19] (byte) col1#1 ← ++ (byte) col1#0 [ col2#0 ] ( ) always clobbers reg byte y -Statement [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 [ col2#0 ] ( ) always clobbers reg byte a -Statement [21] (byte) col2#1 ← ++ (byte) col2#0 [ ] ( ) always clobbers reg byte y -Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a -Statement [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 [ ] ( ) always clobbers reg byte a -Statement [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ( main:3 [ main::x#2 main::qwe#2 main::asd#2 main::row#1 ] ) always clobbers reg byte a -Statement [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ( main:3 [ main::x#2 main::row#1 main::qwe#1 main::asd#1 ] ) always clobbers reg byte a -Statement [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:3 [ ] ) always clobbers reg byte a -Statement asm { lda$dc0d } always clobbers reg byte a -Statement [18] *((const byte*) BGCOL#0) ← (byte) col1#0 [ col1#0 col2#0 ] ( ) always clobbers reg byte a -Statement [19] (byte) col1#1 ← ++ (byte) col1#0 [ col2#0 ] ( ) always clobbers reg byte y -Statement [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 [ col2#0 ] ( ) always clobbers reg byte a -Statement [21] (byte) col2#1 ← ++ (byte) col2#0 [ ] ( ) always clobbers reg byte y -Potential registers zp ZP_BYTE:2 [ main::row#2 main::row#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:3 [ main::x#2 main::x#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] : zp ZP_BYTE:5 , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:6 [ col1#0 ] : zp ZP_BYTE:6 , -Potential registers zp ZP_BYTE:7 [ col2#0 ] : zp ZP_BYTE:7 , -Potential registers zp ZP_BYTE:8 [ col1#1 ] : zp ZP_BYTE:8 , -Potential registers zp ZP_BYTE:9 [ col2#1 ] : zp ZP_BYTE:9 , - -REGISTER UPLIFT SCOPES -Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::row#2 main::row#1 ] 23.1: zp ZP_BYTE:3 [ main::x#2 main::x#1 ] 16.08: zp ZP_BYTE:4 [ main::qwe#2 main::qwe#1 ] 11.5: zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] -Uplift Scope [] 20: zp ZP_BYTE:8 [ col1#1 ] 20: zp ZP_BYTE:9 [ col2#1 ] 3: zp ZP_BYTE:6 [ col1#0 ] 1.5: zp ZP_BYTE:7 [ col2#0 ] -Uplift Scope [irq] - -Uplifting [main] best 639 combination zp ZP_BYTE:2 [ main::row#2 main::row#1 ] reg byte y [ main::x#2 main::x#1 ] reg byte x [ main::qwe#2 main::qwe#1 ] zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] -Uplifting [] best 639 combination zp ZP_BYTE:8 [ col1#1 ] zp ZP_BYTE:9 [ col2#1 ] zp ZP_BYTE:6 [ col1#0 ] zp ZP_BYTE:7 [ col2#0 ] -Uplifting [irq] best 639 combination -Attempting to uplift remaining variables inzp ZP_BYTE:2 [ main::row#2 main::row#1 ] -Uplifting [main] best 639 combination zp ZP_BYTE:2 [ main::row#2 main::row#1 ] -Attempting to uplift remaining variables inzp ZP_BYTE:8 [ col1#1 ] -Uplifting [] best 639 combination zp ZP_BYTE:8 [ col1#1 ] -Attempting to uplift remaining variables inzp ZP_BYTE:9 [ col2#1 ] -Uplifting [] best 639 combination zp ZP_BYTE:9 [ col2#1 ] -Attempting to uplift remaining variables inzp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] -Uplifting [main] best 639 combination zp ZP_BYTE:5 [ main::asd#2 main::asd#1 ] -Attempting to uplift remaining variables inzp ZP_BYTE:6 [ col1#0 ] -Uplifting [] best 639 combination zp ZP_BYTE:6 [ col1#0 ] -Attempting to uplift remaining variables inzp ZP_BYTE:7 [ col2#0 ] -Uplifting [] best 639 combination zp ZP_BYTE:7 [ col2#0 ] -Coalescing zero page register with common assignment [ zp ZP_BYTE:6 [ col1#0 ] ] with [ zp ZP_BYTE:8 [ col1#1 ] ] - score: 1 -Coalescing zero page register with common assignment [ zp ZP_BYTE:7 [ col2#0 ] ] with [ zp ZP_BYTE:9 [ col2#1 ] ] - score: 1 -Coalescing zero page register [ zp ZP_BYTE:2 [ main::row#2 main::row#1 ] ] with [ zp ZP_BYTE:6 [ col1#0 col1#1 ] ] -Coalescing zero page register [ zp ZP_BYTE:2 [ main::row#2 main::row#1 col1#0 col1#1 ] ] with [ zp ZP_BYTE:7 [ col2#0 col2#1 ] ] -Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:3 [ main::asd#2 main::asd#1 ] - -ASSEMBLER BEFORE OPTIMIZATION -//SEG0 Basic Upstart -.pc = $801 "Basic" -:BasicUpstart(main) -.pc = $80d "Program" -//SEG1 Global Constants & labels - .label KERNEL_IRQ = $314 - .label BORDERCOL = $d021 - .label BGCOL = $d020 - .label col1 = 2 - .label col2 = 2 -//SEG2 @begin -bbegin: -//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 - lda #0 - sta col1 -//SEG4 [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuz1=vbuc1 - lda #8 - sta col2 -//SEG5 [2] phi from @begin to @2 [phi:@begin->@2] -b2_from_bbegin: - jmp b2 -//SEG6 @2 -b2: -//SEG7 [3] call main -//SEG8 [5] phi from @2 to main [phi:@2->main] -main_from_b2: - jsr main -//SEG9 [4] phi from @2 to @end [phi:@2->@end] -bend_from_b2: - jmp bend -//SEG10 @end -bend: -//SEG11 main -main: { - .label SCREEN = $400 - .label row = 2 - .label asd = 3 - //SEG12 [6] phi from main to main::@1 [phi:main->main::@1] - b1_from_main: - //SEG13 [6] phi (byte) main::asd#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 - lda #0 - sta asd - //SEG14 [6] phi (byte) main::qwe#2 = (byte/signed byte/word/signed word/dword/signed dword) 32 [phi:main->main::@1#1] -- vbuxx=vbuc1 - ldx #$20 - //SEG15 [6] phi (byte) main::x#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#2] -- vbuyy=vbuc1 - ldy #0 - //SEG16 [6] phi (byte) main::row#2 = (byte/signed byte/word/signed word/dword/signed dword) 12 [phi:main->main::@1#3] -- vbuz1=vbuc1 - lda #$c - sta row - jmp b1 - //SEG17 [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1] - b1_from_b1: - //SEG18 [6] phi (byte) main::asd#2 = (byte) main::asd#1 [phi:main::@1->main::@1#0] -- register_copy - //SEG19 [6] phi (byte) main::qwe#2 = (byte) main::qwe#1 [phi:main::@1->main::@1#1] -- register_copy - //SEG20 [6] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@1->main::@1#2] -- register_copy - //SEG21 [6] phi (byte) main::row#2 = (byte) main::row#1 [phi:main::@1->main::@1#3] -- register_copy - jmp b1 - //SEG22 main::@1 - b1: - //SEG23 [7] (byte) main::row#1 ← ++ (byte) main::row#2 -- vbuz1=_inc_vbuz1 - inc row - //SEG24 [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 -- pbuc1_derefidx_vbuyy=vbuz1 - lda row - sta SCREEN,y - //SEG25 [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 -- vbuxx=_inc_vbuxx - inx - //SEG26 [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 -- vbuz1=vbuz1_plus_vbuxx - txa - clc - adc asd - sta asd - //SEG27 [11] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuyy=_inc_vbuyy - iny - //SEG28 [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 - cpy #$b - bne b1_from_b1 - jmp b2 - //SEG29 main::@2 - b2: - //SEG30 [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 -- _deref_pbuc1=vbuxx - stx SCREEN - //SEG31 [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 -- _deref_pbuc1=vbuz1 - lda asd - sta SCREEN+1 - //SEG32 [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 - lda #irq - sta KERNEL_IRQ+1 - jmp breturn - //SEG33 main::@return - breturn: - //SEG34 [16] return - rts -} -//SEG35 irq -irq: { - //SEG36 entry interrupt(KERNEL_MIN) - //SEG37 asm { lda$dc0d } - lda $dc0d - //SEG38 [18] *((const byte*) BGCOL#0) ← (byte) col1#0 -- _deref_pbuc1=vbuz1 - lda col1 - sta BGCOL - //SEG39 [19] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz1 - inc col1 - //SEG40 [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 -- _deref_pbuc1=vbuz1 - lda col2 - sta BORDERCOL - //SEG41 [21] (byte) col2#1 ← ++ (byte) col2#0 -- vbuz1=_inc_vbuz1 - inc col2 - jmp breturn - //SEG42 irq::@return - breturn: - //SEG43 [22] return - exit interrupt(KERNEL_MIN) - jmp $ea81 -} - -ASSEMBLER OPTIMIZATIONS -Removing instruction jmp b2 -Removing instruction jmp bend -Removing instruction jmp b1 -Removing instruction jmp b2 -Removing instruction jmp breturn -Removing instruction jmp breturn -Succesful ASM optimization Pass5NextJumpElimination -Replacing instruction ldy #0 with TAY -Replacing label b1_from_b1 with b1 -Removing instruction b2_from_bbegin: -Removing instruction main_from_b2: -Removing instruction bend_from_b2: -Removing instruction b1_from_b1: -Succesful ASM optimization Pass5RedundantLabelElimination -Removing instruction bbegin: -Removing instruction b2: -Removing instruction bend: -Removing instruction b1_from_main: -Removing instruction b2: -Removing instruction breturn: -Removing instruction breturn: -Succesful ASM optimization Pass5UnusedLabelElimination -Removing instruction jmp b1 -Succesful ASM optimization Pass5NextJumpElimination -Removing instruction lda asd -Succesful ASM optimization Pass5UnnecesaryLoadElimination - -FINAL SYMBOL TABLE -(label) @2 -(label) @begin -(label) @end -(byte*) BGCOL -(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280 -(byte*) BORDERCOL -(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53281 -(void()**) KERNEL_IRQ -(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 -(byte) col1 -(byte) col1#0 col1 zp ZP_BYTE:2 3.0 -(byte) col1#1 col1 zp ZP_BYTE:2 20.0 -(byte) col2 -(byte) col2#0 col2 zp ZP_BYTE:2 1.5 -(byte) col2#1 col2 zp ZP_BYTE:2 20.0 -interrupt(KERNEL_MIN)(void()) irq() -(label) irq::@return -(void()) main() -(label) main::@1 -(label) main::@2 -(label) main::@return -(byte*) main::SCREEN -(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024 -(byte) main::asd -(byte) main::asd#1 asd zp ZP_BYTE:3 6.0 -(byte) main::asd#2 asd zp ZP_BYTE:3 5.5 -(byte) main::qwe -(byte) main::qwe#1 reg byte x 8.75 -(byte) main::qwe#2 reg byte x 7.333333333333333 -(byte) main::row -(byte) main::row#1 row zp ZP_BYTE:2 5.5 -(byte) main::row#2 row zp ZP_BYTE:2 22.0 -(byte) main::x -(byte) main::x#1 reg byte y 16.5 -(byte) main::x#2 reg byte y 6.6000000000000005 - -zp ZP_BYTE:2 [ main::row#2 main::row#1 col1#0 col1#1 col2#0 col2#1 ] -reg byte y [ main::x#2 main::x#1 ] -reg byte x [ main::qwe#2 main::qwe#1 ] -zp ZP_BYTE:3 [ main::asd#2 main::asd#1 ] - - -FINAL ASSEMBLER -Score: 528 - -//SEG0 Basic Upstart -.pc = $801 "Basic" -:BasicUpstart(main) -.pc = $80d "Program" -//SEG1 Global Constants & labels - .label KERNEL_IRQ = $314 - .label BORDERCOL = $d021 - .label BGCOL = $d020 - .label col1 = 2 - .label col2 = 2 -//SEG2 @begin -//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 - lda #0 - sta col1 -//SEG4 [1] (byte) col2#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 -- vbuz1=vbuc1 - lda #8 - sta col2 -//SEG5 [2] phi from @begin to @2 [phi:@begin->@2] -//SEG6 @2 -//SEG7 [3] call main -//SEG8 [5] phi from @2 to main [phi:@2->main] - jsr main -//SEG9 [4] phi from @2 to @end [phi:@2->@end] -//SEG10 @end -//SEG11 main -main: { - .label SCREEN = $400 - .label row = 2 - .label asd = 3 - //SEG12 [6] phi from main to main::@1 [phi:main->main::@1] - //SEG13 [6] phi (byte) main::asd#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 - lda #0 - sta asd - //SEG14 [6] phi (byte) main::qwe#2 = (byte/signed byte/word/signed word/dword/signed dword) 32 [phi:main->main::@1#1] -- vbuxx=vbuc1 - ldx #$20 - //SEG15 [6] phi (byte) main::x#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#2] -- vbuyy=vbuc1 - tay - //SEG16 [6] phi (byte) main::row#2 = (byte/signed byte/word/signed word/dword/signed dword) 12 [phi:main->main::@1#3] -- vbuz1=vbuc1 - lda #$c - sta row - //SEG17 [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1] - //SEG18 [6] phi (byte) main::asd#2 = (byte) main::asd#1 [phi:main::@1->main::@1#0] -- register_copy - //SEG19 [6] phi (byte) main::qwe#2 = (byte) main::qwe#1 [phi:main::@1->main::@1#1] -- register_copy - //SEG20 [6] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@1->main::@1#2] -- register_copy - //SEG21 [6] phi (byte) main::row#2 = (byte) main::row#1 [phi:main::@1->main::@1#3] -- register_copy - //SEG22 main::@1 - b1: - //SEG23 [7] (byte) main::row#1 ← ++ (byte) main::row#2 -- vbuz1=_inc_vbuz1 - inc row - //SEG24 [8] *((const byte*) main::SCREEN#0 + (byte) main::x#2) ← (byte) main::row#1 -- pbuc1_derefidx_vbuyy=vbuz1 - lda row - sta SCREEN,y - //SEG25 [9] (byte) main::qwe#1 ← ++ (byte) main::qwe#2 -- vbuxx=_inc_vbuxx - inx - //SEG26 [10] (byte) main::asd#1 ← (byte) main::asd#2 + (byte) main::qwe#1 -- vbuz1=vbuz1_plus_vbuxx - txa - clc - adc asd - sta asd - //SEG27 [11] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuyy=_inc_vbuyy - iny - //SEG28 [12] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 - cpy #$b - bne b1 - //SEG29 main::@2 - //SEG30 [13] *((const byte*) main::SCREEN#0) ← (byte) main::qwe#1 -- _deref_pbuc1=vbuxx - stx SCREEN - //SEG31 [14] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte) main::asd#1 -- _deref_pbuc1=vbuz1 - sta SCREEN+1 - //SEG32 [15] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 - lda #irq - sta KERNEL_IRQ+1 - //SEG33 main::@return - //SEG34 [16] return - rts -} -//SEG35 irq -irq: { - //SEG36 entry interrupt(KERNEL_MIN) - //SEG37 asm { lda$dc0d } - lda $dc0d - //SEG38 [18] *((const byte*) BGCOL#0) ← (byte) col1#0 -- _deref_pbuc1=vbuz1 - lda col1 - sta BGCOL - //SEG39 [19] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz1 - inc col1 - //SEG40 [20] *((const byte*) BORDERCOL#0) ← (byte) col2#0 -- _deref_pbuc1=vbuz1 - lda col2 - sta BORDERCOL - //SEG41 [21] (byte) col2#1 ← ++ (byte) col2#0 -- vbuz1=_inc_vbuz1 - inc col2 - //SEG42 irq::@return - //SEG43 [22] return - exit interrupt(KERNEL_MIN) - jmp $ea81 -} - diff --git a/src/test/ref/interrupt-volatile-reuse-problem.sym b/src/test/ref/interrupt-volatile-reuse-problem.sym deleted file mode 100644 index 3c0b4f9bc..000000000 --- a/src/test/ref/interrupt-volatile-reuse-problem.sym +++ /dev/null @@ -1,40 +0,0 @@ -(label) @2 -(label) @begin -(label) @end -(byte*) BGCOL -(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280 -(byte*) BORDERCOL -(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53281 -(void()**) KERNEL_IRQ -(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 -(byte) col1 -(byte) col1#0 col1 zp ZP_BYTE:2 3.0 -(byte) col1#1 col1 zp ZP_BYTE:2 20.0 -(byte) col2 -(byte) col2#0 col2 zp ZP_BYTE:2 1.5 -(byte) col2#1 col2 zp ZP_BYTE:2 20.0 -interrupt(KERNEL_MIN)(void()) irq() -(label) irq::@return -(void()) main() -(label) main::@1 -(label) main::@2 -(label) main::@return -(byte*) main::SCREEN -(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024 -(byte) main::asd -(byte) main::asd#1 asd zp ZP_BYTE:3 6.0 -(byte) main::asd#2 asd zp ZP_BYTE:3 5.5 -(byte) main::qwe -(byte) main::qwe#1 reg byte x 8.75 -(byte) main::qwe#2 reg byte x 7.333333333333333 -(byte) main::row -(byte) main::row#1 row zp ZP_BYTE:2 5.5 -(byte) main::row#2 row zp ZP_BYTE:2 22.0 -(byte) main::x -(byte) main::x#1 reg byte y 16.5 -(byte) main::x#2 reg byte y 6.6000000000000005 - -zp ZP_BYTE:2 [ main::row#2 main::row#1 col1#0 col1#1 col2#0 col2#1 ] -reg byte y [ main::x#2 main::x#1 ] -reg byte x [ main::qwe#2 main::qwe#1 ] -zp ZP_BYTE:3 [ main::asd#2 main::asd#1 ] diff --git a/src/test/ref/interrupt-volatile-reuse-problem1.asm b/src/test/ref/interrupt-volatile-reuse-problem1.asm new file mode 100644 index 000000000..b45257390 --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem1.asm @@ -0,0 +1,28 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label KERNEL_IRQ = $314 + .label SCREEN = $400 + .label col1 = 2 + .label col2 = 2 + lda #0 + sta col1 + lda #8 + sta col2 + jsr main +main: { + lda #irq + sta KERNEL_IRQ+1 + rts +} +irq: { + lda col1 + sta SCREEN+$28 + inc col1 + lda col2 + sta SCREEN+$29 + inc col2 + jmp $ea81 +} diff --git a/src/test/ref/interrupt-volatile-reuse-problem1.log b/src/test/ref/interrupt-volatile-reuse-problem1.log new file mode 100644 index 000000000..7a24c365a --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem1.log @@ -0,0 +1,14 @@ +parsing +flex pass 1 +flex pass 2 +flex pass 3 +Output pass + +Memory Map +---------- +Default-segment: + $0801-$080c Basic + $080d-$0833 Program + +Writing prg file: /var/folders/j3/hvhhv4vs6291pncspymzkrfh0000gp/T/kickc-output2800452417889124972/bin/interrupt-volatile-reuse-problem1.prg +Writing Vice symbol file: /var/folders/j3/hvhhv4vs6291pncspymzkrfh0000gp/T/kickc-output2800452417889124972/bin/interrupt-volatile-reuse-problem1.vs diff --git a/src/test/ref/interrupt-volatile-reuse-problem1.prg b/src/test/ref/interrupt-volatile-reuse-problem1.prg new file mode 100644 index 000000000..04114554e Binary files /dev/null and b/src/test/ref/interrupt-volatile-reuse-problem1.prg differ diff --git a/src/test/ref/interrupt-volatile-reuse-problem1.vs b/src/test/ref/interrupt-volatile-reuse-problem1.vs new file mode 100644 index 000000000..7f4489204 --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem1.vs @@ -0,0 +1,7 @@ +al C:314 .KERNEL_IRQ +al C:400 .SCREEN +al C:823 .irq +al C:80b .upstartEnd +al C:818 .main +al C:2 .col2 +al C:2 .col1 diff --git a/src/test/ref/interrupt-volatile-reuse-problem2.asm b/src/test/ref/interrupt-volatile-reuse-problem2.asm new file mode 100644 index 000000000..442429f99 --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem2.asm @@ -0,0 +1,49 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label KERNEL_IRQ = $314 + .label IRQ_STATUS = $d019 + .label SCREEN = $400 + .label col1 = 2 + lda #0 + sta col1 + jsr main +main: { + .label y = 2 + lda #irq + sta KERNEL_IRQ+1 + b1: + ldx #0 + b4: + lda #0 + sta y + b5: + ldy #0 + b6: + tya + clc + adc y + sta SCREEN,x + iny + cpy #$b + bne b6 + inc y + lda y + cmp #$b + bne b5 + inx + cpx #$b + bne b4 + jmp b1 +} +irq: { + lda #1 + sta IRQ_STATUS + lda $dc0d + lda col1 + sta SCREEN+$28 + inc col1 + jmp $ea81 +} diff --git a/src/test/ref/interrupt-volatile-reuse-problem2.cfg b/src/test/ref/interrupt-volatile-reuse-problem2.cfg new file mode 100644 index 000000000..2c35f1759 --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem2.cfg @@ -0,0 +1,45 @@ +@begin: scope:[] from + [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:@2 +@2: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @2 + [3] phi() +main: scope:[main] from @2 + [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() + to:main::@4 +main::@4: scope:[main] from main main::@10 main::@13 + [5] (byte) main::x#6 ← phi( main::@13/(byte) main::x#1 main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@10/(byte/signed byte/word/signed word/dword/signed dword) 0 ) + to:main::@5 +main::@5: scope:[main] from main::@4 main::@9 + [6] (byte) main::y#4 ← phi( main::@4/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@9/(byte) main::y#1 ) + to:main::@6 +main::@6: scope:[main] from main::@5 main::@6 + [7] (byte) main::a#2 ← phi( main::@5/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@6/(byte) main::a#1 ) + [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 + [9] *((const byte*) SCREEN#0 + (byte) main::x#6) ← (byte~) main::$1 + [10] (byte) main::a#1 ← ++ (byte) main::a#2 + [11] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@6 + to:main::@9 +main::@9: scope:[main] from main::@6 + [12] (byte) main::y#1 ← ++ (byte) main::y#4 + [13] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@5 + to:main::@10 +main::@10: scope:[main] from main::@9 + [14] (byte) main::x#1 ← ++ (byte) main::x#6 + [15] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@13 + to:main::@4 +main::@13: scope:[main] from main::@10 + [16] phi() + to:main::@4 +irq: scope:[irq] from + [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 + asm { lda$dc0d } + [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 + [20] (byte) col1#1 ← ++ (byte) col1#0 + to:irq::@return +irq::@return: scope:[irq] from irq + [21] return + to:@return diff --git a/src/test/ref/interrupt-volatile-reuse-problem2.log b/src/test/ref/interrupt-volatile-reuse-problem2.log new file mode 100644 index 000000000..08ad78531 --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem2.log @@ -0,0 +1,784 @@ +Resolved forward reference irq to interrupt(KERNEL_MIN)(void()) irq() + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 + (byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273 + (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333 + (byte*) SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024 + (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:@2 +main: scope:[main] from @2 + (void()*~) main::$0 ← & interrupt(KERNEL_MIN)(void()) irq() + *((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0 + to:main::@1 +main::@1: scope:[main] from main main::@10 + if(true) goto main::@2 + to:main::@return +main::@2: scope:[main] from main::@1 + (byte) main::x#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@4 +main::@4: scope:[main] from main::@10 main::@2 + (byte) main::x#6 ← phi( main::@10/(byte) main::x#1 main::@2/(byte) main::x#0 ) + (byte) main::y#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@5 +main::@5: scope:[main] from main::@4 main::@9 + (byte) main::x#4 ← phi( main::@4/(byte) main::x#6 main::@9/(byte) main::x#5 ) + (byte) main::y#4 ← phi( main::@4/(byte) main::y#0 main::@9/(byte) main::y#1 ) + (byte) main::a#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@6 +main::@6: scope:[main] from main::@5 main::@6 + (byte) main::x#2 ← phi( main::@5/(byte) main::x#4 main::@6/(byte) main::x#2 ) + (byte) main::y#2 ← phi( main::@5/(byte) main::y#4 main::@6/(byte) main::y#2 ) + (byte) main::a#2 ← phi( main::@5/(byte) main::a#0 main::@6/(byte) main::a#1 ) + (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#2 + *((byte*) SCREEN#0 + (byte) main::x#2) ← (byte~) main::$1 + (byte) main::a#1 ← (byte) main::a#2 + rangenext(0,10) + (bool~) main::$2 ← (byte) main::a#1 != rangelast(0,10) + if((bool~) main::$2) goto main::@6 + to:main::@9 +main::@9: scope:[main] from main::@6 + (byte) main::x#5 ← phi( main::@6/(byte) main::x#2 ) + (byte) main::y#3 ← phi( main::@6/(byte) main::y#2 ) + (byte) main::y#1 ← (byte) main::y#3 + rangenext(0,10) + (bool~) main::$3 ← (byte) main::y#1 != rangelast(0,10) + if((bool~) main::$3) goto main::@5 + to:main::@10 +main::@10: scope:[main] from main::@9 + (byte) main::x#3 ← phi( main::@9/(byte) main::x#5 ) + (byte) main::x#1 ← (byte) main::x#3 + rangenext(0,10) + (bool~) main::$4 ← (byte) main::x#1 != rangelast(0,10) + if((bool~) main::$4) goto main::@4 + to:main::@1 +main::@return: scope:[main] from main::@1 + return + to:@return +irq: scope:[irq] from + (byte) col1#3 ← phi( @2/(byte) col1#5 ) + *((byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 + asm { lda$dc0d } + *((byte*) SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#3 + (byte) col1#1 ← ++ (byte) col1#3 + to:irq::@return +irq::@return: scope:[irq] from irq + (byte) col1#4 ← phi( irq/(byte) col1#1 ) + (byte) col1#2 ← (byte) col1#4 + return + to:@return +@2: scope:[] from @begin + (byte) col1#5 ← phi( @begin/(byte) col1#0 ) + call main + to:@3 +@3: scope:[] from @2 + to:@end +@end: scope:[] from @3 + +SYMBOL TABLE SSA +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte*) CIA1_INTERRUPT +(byte*) CIA1_INTERRUPT#0 +(byte*) IRQ_STATUS +(byte*) IRQ_STATUS#0 +(void()**) KERNEL_IRQ +(void()**) KERNEL_IRQ#0 +(byte*) SCREEN +(byte*) SCREEN#0 +(byte) col1 +(byte) col1#0 +(byte) col1#1 +(byte) col1#2 +(byte) col1#3 +(byte) col1#4 +(byte) col1#5 +interrupt(KERNEL_MIN)(void()) irq() +(label) irq::@return +(void()) main() +(void()*~) main::$0 +(byte~) main::$1 +(bool~) main::$2 +(bool~) main::$3 +(bool~) main::$4 +(label) main::@1 +(label) main::@10 +(label) main::@2 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@9 +(label) main::@return +(byte) main::a +(byte) main::a#0 +(byte) main::a#1 +(byte) main::a#2 +(byte) main::x +(byte) main::x#0 +(byte) main::x#1 +(byte) main::x#2 +(byte) main::x#3 +(byte) main::x#4 +(byte) main::x#5 +(byte) main::x#6 +(byte) main::y +(byte) main::y#0 +(byte) main::y#1 +(byte) main::y#2 +(byte) main::y#3 +(byte) main::y#4 + +Culled Empty Block (label) @3 +Successful SSA optimization Pass2CullEmptyBlocks +Alias (byte) main::y#2 = (byte) main::y#3 +Alias (byte) main::x#2 = (byte) main::x#5 (byte) main::x#3 +Alias (byte) col1#1 = (byte) col1#4 (byte) col1#2 +Alias (byte) col1#0 = (byte) col1#5 +Successful SSA optimization Pass2AliasElimination +Self Phi Eliminated (byte) main::y#2 +Self Phi Eliminated (byte) main::x#2 +Successful SSA optimization Pass2SelfPhiElimination +Redundant Phi (byte) main::y#2 (byte) main::y#4 +Redundant Phi (byte) main::x#2 (byte) main::x#4 +Redundant Phi (byte) col1#3 (byte) col1#0 +Successful SSA optimization Pass2RedundantPhiElimination +Simple Condition (bool~) main::$2 if((byte) main::a#1!=rangelast(0,10)) goto main::@6 +Simple Condition (bool~) main::$3 if((byte) main::y#1!=rangelast(0,10)) goto main::@5 +Simple Condition (bool~) main::$4 if((byte) main::x#1!=rangelast(0,10)) goto main::@4 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 +Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273 +Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333 +Constant (const byte*) SCREEN#0 = ((byte*))1024 +Constant (const void()*) main::$0 = &irq +Constant (const byte) main::x#0 = 0 +Constant (const byte) main::y#0 = 0 +Constant (const byte) main::a#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Consolidated array index constant in *(SCREEN#0+40) +Successful SSA optimization Pass2ConstantAdditionElimination +if() condition always true - replacing block destination if(true) goto main::@2 +Successful SSA optimization Pass2ConstantIfs +Successful SSA optimization PassNEliminateUnusedVars +Removing unused block main::@return +Successful SSA optimization Pass2EliminateUnusedBlocks +Resolved ranged next value main::a#1 ← ++ main::a#2 to ++ +Resolved ranged comparison value if(main::a#1!=rangelast(0,10)) goto main::@6 to (byte/signed byte/word/signed word/dword/signed dword) 11 +Resolved ranged next value main::y#1 ← ++ main::y#4 to ++ +Resolved ranged comparison value if(main::y#1!=rangelast(0,10)) goto main::@5 to (byte/signed byte/word/signed word/dword/signed dword) 11 +Resolved ranged next value main::x#1 ← ++ main::x#4 to ++ +Resolved ranged comparison value if(main::x#1!=rangelast(0,10)) goto main::@4 to (byte/signed byte/word/signed word/dword/signed dword) 11 +Culled Empty Block (label) main::@1 +Successful SSA optimization Pass2CullEmptyBlocks +Self Phi Eliminated (byte) main::x#4 +Successful SSA optimization Pass2SelfPhiElimination +Redundant Phi (byte) main::x#4 (byte) main::x#6 +Successful SSA optimization Pass2RedundantPhiElimination +Inlining constant with var siblings (const byte) main::x#0 +Inlining constant with var siblings (const byte) main::y#0 +Inlining constant with var siblings (const byte) main::a#0 +Constant inlined main::a#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::x#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::y#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::$0 = &interrupt(KERNEL_MIN)(void()) irq() +Successful SSA optimization Pass2ConstantInlining +Added new block during phi lifting main::@13(between main::@10 and main::@4) +Added new block during phi lifting main::@14(between main::@9 and main::@5) +Added new block during phi lifting main::@15(between main::@6 and main::@6) +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main::@2 +CALL GRAPH +Calls in [] to main:2 + +Created 3 initial phi equivalence classes +Coalesced [17] main::x#7 ← main::x#1 +Coalesced [18] main::y#5 ← main::y#1 +Coalesced [19] main::a#3 ← main::a#1 +Coalesced down to 3 phi equivalence classes +Culled Empty Block (label) main::@2 +Culled Empty Block (label) main::@14 +Culled Empty Block (label) main::@15 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main::@13 + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:@2 +@2: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @2 + [3] phi() +main: scope:[main] from @2 + [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() + to:main::@4 +main::@4: scope:[main] from main main::@10 main::@13 + [5] (byte) main::x#6 ← phi( main::@13/(byte) main::x#1 main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@10/(byte/signed byte/word/signed word/dword/signed dword) 0 ) + to:main::@5 +main::@5: scope:[main] from main::@4 main::@9 + [6] (byte) main::y#4 ← phi( main::@4/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@9/(byte) main::y#1 ) + to:main::@6 +main::@6: scope:[main] from main::@5 main::@6 + [7] (byte) main::a#2 ← phi( main::@5/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@6/(byte) main::a#1 ) + [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 + [9] *((const byte*) SCREEN#0 + (byte) main::x#6) ← (byte~) main::$1 + [10] (byte) main::a#1 ← ++ (byte) main::a#2 + [11] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@6 + to:main::@9 +main::@9: scope:[main] from main::@6 + [12] (byte) main::y#1 ← ++ (byte) main::y#4 + [13] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@5 + to:main::@10 +main::@10: scope:[main] from main::@9 + [14] (byte) main::x#1 ← ++ (byte) main::x#6 + [15] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@13 + to:main::@4 +main::@13: scope:[main] from main::@10 + [16] phi() + to:main::@4 +irq: scope:[irq] from + [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 + asm { lda$dc0d } + [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 + [20] (byte) col1#1 ← ++ (byte) col1#0 + to:irq::@return +irq::@return: scope:[irq] from irq + [21] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte*) CIA1_INTERRUPT +(byte*) IRQ_STATUS +(void()**) KERNEL_IRQ +(byte*) SCREEN +(byte) col1 +(byte) col1#0 2.0 +(byte) col1#1 20.0 +interrupt(KERNEL_MIN)(void()) irq() +(void()) main() +(byte~) main::$1 20002.0 +(byte) main::a +(byte) main::a#1 15001.5 +(byte) main::a#2 10001.0 +(byte) main::x +(byte) main::x#1 71.0 +(byte) main::x#6 1123.6666666666665 +(byte) main::y +(byte) main::y#1 1501.5 +(byte) main::y#4 2000.4999999999998 + +Initial phi equivalence classes +[ main::x#6 main::x#1 ] +[ main::y#4 main::y#1 ] +[ main::a#2 main::a#1 ] +Added variable col1#0 to zero page equivalence class [ col1#0 ] +Added variable main::$1 to zero page equivalence class [ main::$1 ] +Added variable col1#1 to zero page equivalence class [ col1#1 ] +Complete equivalence classes +[ main::x#6 main::x#1 ] +[ main::y#4 main::y#1 ] +[ main::a#2 main::a#1 ] +[ col1#0 ] +[ main::$1 ] +[ col1#1 ] +Allocated zp ZP_BYTE:2 [ main::x#6 main::x#1 ] +Allocated zp ZP_BYTE:3 [ main::y#4 main::y#1 ] +Allocated zp ZP_BYTE:4 [ main::a#2 main::a#1 ] +Allocated zp ZP_BYTE:5 [ col1#0 ] +Allocated zp ZP_BYTE:6 [ main::$1 ] +Allocated zp ZP_BYTE:7 [ col1#1 ] + +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label IRQ_STATUS = $d019 + .label SCREEN = $400 + .label col1 = 5 + .label col1_1 = 7 +//SEG2 @begin +bbegin: +//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 + lda #0 + sta col1 +//SEG4 [1] phi from @begin to @2 [phi:@begin->@2] +b2_from_bbegin: + jmp b2 +//SEG5 @2 +b2: +//SEG6 [2] call main + jsr main +//SEG7 [3] phi from @2 to @end [phi:@2->@end] +bend_from_b2: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .label _1 = 6 + .label a = 4 + .label y = 3 + .label x = 2 + //SEG10 [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG11 [5] phi from main main::@10 to main::@4 [phi:main/main::@10->main::@4] + b4_from_main: + b4_from_b10: + //SEG12 [5] phi (byte) main::x#6 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main/main::@10->main::@4#0] -- vbuz1=vbuc1 + lda #0 + sta x + jmp b4 + //SEG13 main::@4 + b4: + //SEG14 [6] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + b5_from_b4: + //SEG15 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@4->main::@5#0] -- vbuz1=vbuc1 + lda #0 + sta y + jmp b5 + //SEG16 [6] phi from main::@9 to main::@5 [phi:main::@9->main::@5] + b5_from_b9: + //SEG17 [6] phi (byte) main::y#4 = (byte) main::y#1 [phi:main::@9->main::@5#0] -- register_copy + jmp b5 + //SEG18 main::@5 + b5: + //SEG19 [7] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + b6_from_b5: + //SEG20 [7] phi (byte) main::a#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@5->main::@6#0] -- vbuz1=vbuc1 + lda #0 + sta a + jmp b6 + //SEG21 [7] phi from main::@6 to main::@6 [phi:main::@6->main::@6] + b6_from_b6: + //SEG22 [7] phi (byte) main::a#2 = (byte) main::a#1 [phi:main::@6->main::@6#0] -- register_copy + jmp b6 + //SEG23 main::@6 + b6: + //SEG24 [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 -- vbuz1=vbuz2_plus_vbuz3 + lda a + clc + adc y + sta _1 + //SEG25 [9] *((const byte*) SCREEN#0 + (byte) main::x#6) ← (byte~) main::$1 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _1 + ldy x + sta SCREEN,y + //SEG26 [10] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1 + inc a + //SEG27 [11] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@6 -- vbuz1_neq_vbuc1_then_la1 + lda a + cmp #$b + bne b6_from_b6 + jmp b9 + //SEG28 main::@9 + b9: + //SEG29 [12] (byte) main::y#1 ← ++ (byte) main::y#4 -- vbuz1=_inc_vbuz1 + inc y + //SEG30 [13] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@5 -- vbuz1_neq_vbuc1_then_la1 + lda y + cmp #$b + bne b5_from_b9 + jmp b10 + //SEG31 main::@10 + b10: + //SEG32 [14] (byte) main::x#1 ← ++ (byte) main::x#6 -- vbuz1=_inc_vbuz1 + inc x + //SEG33 [15] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@13 -- vbuz1_neq_vbuc1_then_la1 + lda x + cmp #$b + bne b13_from_b10 + jmp b4_from_b10 + //SEG34 [16] phi from main::@10 to main::@13 [phi:main::@10->main::@13] + b13_from_b10: + jmp b13 + //SEG35 main::@13 + b13: + //SEG36 [5] phi from main::@13 to main::@4 [phi:main::@13->main::@4] + b4_from_b13: + //SEG37 [5] phi (byte) main::x#6 = (byte) main::x#1 [phi:main::@13->main::@4#0] -- register_copy + jmp b4 +} +//SEG38 irq +irq: { + //SEG39 entry interrupt(KERNEL_MIN) + //SEG40 [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2 + lda #1 + sta IRQ_STATUS + //SEG41 asm { lda$dc0d } + lda $dc0d + //SEG42 [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 -- _deref_pbuc1=vbuz1 + lda col1 + sta SCREEN+$28 + //SEG43 [20] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz2 + ldy col1 + iny + sty col1_1 + jmp breturn + //SEG44 irq::@return + breturn: + //SEG45 [21] return - exit interrupt(KERNEL_MIN) + jmp $ea81 +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a +Statement [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 [ main::x#6 main::y#4 main::a#2 main::$1 ] ( main:2 [ main::x#6 main::y#4 main::a#2 main::$1 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::x#6 main::x#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::y#4 main::y#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::a#2 main::a#1 ] +Statement [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 [ col1#0 ] ( ) always clobbers reg byte a +Statement asm { lda$dc0d } always clobbers reg byte a +Statement [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 [ col1#0 ] ( ) always clobbers reg byte a +Statement [20] (byte) col1#1 ← ++ (byte) col1#0 [ ] ( ) always clobbers reg byte y +Statement [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( ) always clobbers reg byte a +Statement [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 [ main::x#6 main::y#4 main::a#2 main::$1 ] ( main:2 [ main::x#6 main::y#4 main::a#2 main::$1 ] ) always clobbers reg byte a +Statement [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 [ col1#0 ] ( ) always clobbers reg byte a +Statement asm { lda$dc0d } always clobbers reg byte a +Statement [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 [ col1#0 ] ( ) always clobbers reg byte a +Statement [20] (byte) col1#1 ← ++ (byte) col1#0 [ ] ( ) always clobbers reg byte y +Potential registers zp ZP_BYTE:2 [ main::x#6 main::x#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::y#4 main::y#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ main::a#2 main::a#1 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ col1#0 ] : zp ZP_BYTE:5 , +Potential registers zp ZP_BYTE:6 [ main::$1 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:7 [ col1#1 ] : zp ZP_BYTE:7 , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 25,002.5: zp ZP_BYTE:4 [ main::a#2 main::a#1 ] 20,002: zp ZP_BYTE:6 [ main::$1 ] 3,502: zp ZP_BYTE:3 [ main::y#4 main::y#1 ] 1,194.67: zp ZP_BYTE:2 [ main::x#6 main::x#1 ] +Uplift Scope [] 20: zp ZP_BYTE:7 [ col1#1 ] 2: zp ZP_BYTE:5 [ col1#0 ] +Uplift Scope [irq] + +Uplifting [main] best 323340 combination reg byte y [ main::a#2 main::a#1 ] reg byte a [ main::$1 ] zp ZP_BYTE:3 [ main::y#4 main::y#1 ] reg byte x [ main::x#6 main::x#1 ] +Limited combination testing to 100 combinations of 108 possible. +Uplifting [] best 323340 combination zp ZP_BYTE:7 [ col1#1 ] zp ZP_BYTE:5 [ col1#0 ] +Uplifting [irq] best 323340 combination +Attempting to uplift remaining variables inzp ZP_BYTE:3 [ main::y#4 main::y#1 ] +Uplifting [main] best 323340 combination zp ZP_BYTE:3 [ main::y#4 main::y#1 ] +Attempting to uplift remaining variables inzp ZP_BYTE:7 [ col1#1 ] +Uplifting [] best 323340 combination zp ZP_BYTE:7 [ col1#1 ] +Attempting to uplift remaining variables inzp ZP_BYTE:5 [ col1#0 ] +Uplifting [] best 323340 combination zp ZP_BYTE:5 [ col1#0 ] +Coalescing zero page register with common assignment [ zp ZP_BYTE:5 [ col1#0 ] ] with [ zp ZP_BYTE:7 [ col1#1 ] ] - score: 1 +Coalescing zero page register [ zp ZP_BYTE:3 [ main::y#4 main::y#1 ] ] with [ zp ZP_BYTE:5 [ col1#0 col1#1 ] ] +Allocated (was zp ZP_BYTE:3) zp ZP_BYTE:2 [ main::y#4 main::y#1 col1#0 col1#1 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label IRQ_STATUS = $d019 + .label SCREEN = $400 + .label col1 = 2 +//SEG2 @begin +bbegin: +//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 + lda #0 + sta col1 +//SEG4 [1] phi from @begin to @2 [phi:@begin->@2] +b2_from_bbegin: + jmp b2 +//SEG5 @2 +b2: +//SEG6 [2] call main + jsr main +//SEG7 [3] phi from @2 to @end [phi:@2->@end] +bend_from_b2: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .label y = 2 + //SEG10 [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG11 [5] phi from main main::@10 to main::@4 [phi:main/main::@10->main::@4] + b4_from_main: + b4_from_b10: + //SEG12 [5] phi (byte) main::x#6 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main/main::@10->main::@4#0] -- vbuxx=vbuc1 + ldx #0 + jmp b4 + //SEG13 main::@4 + b4: + //SEG14 [6] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + b5_from_b4: + //SEG15 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@4->main::@5#0] -- vbuz1=vbuc1 + lda #0 + sta y + jmp b5 + //SEG16 [6] phi from main::@9 to main::@5 [phi:main::@9->main::@5] + b5_from_b9: + //SEG17 [6] phi (byte) main::y#4 = (byte) main::y#1 [phi:main::@9->main::@5#0] -- register_copy + jmp b5 + //SEG18 main::@5 + b5: + //SEG19 [7] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + b6_from_b5: + //SEG20 [7] phi (byte) main::a#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@5->main::@6#0] -- vbuyy=vbuc1 + ldy #0 + jmp b6 + //SEG21 [7] phi from main::@6 to main::@6 [phi:main::@6->main::@6] + b6_from_b6: + //SEG22 [7] phi (byte) main::a#2 = (byte) main::a#1 [phi:main::@6->main::@6#0] -- register_copy + jmp b6 + //SEG23 main::@6 + b6: + //SEG24 [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 -- vbuaa=vbuyy_plus_vbuz1 + tya + clc + adc y + //SEG25 [9] *((const byte*) SCREEN#0 + (byte) main::x#6) ← (byte~) main::$1 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN,x + //SEG26 [10] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy + iny + //SEG27 [11] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@6 -- vbuyy_neq_vbuc1_then_la1 + cpy #$b + bne b6_from_b6 + jmp b9 + //SEG28 main::@9 + b9: + //SEG29 [12] (byte) main::y#1 ← ++ (byte) main::y#4 -- vbuz1=_inc_vbuz1 + inc y + //SEG30 [13] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@5 -- vbuz1_neq_vbuc1_then_la1 + lda y + cmp #$b + bne b5_from_b9 + jmp b10 + //SEG31 main::@10 + b10: + //SEG32 [14] (byte) main::x#1 ← ++ (byte) main::x#6 -- vbuxx=_inc_vbuxx + inx + //SEG33 [15] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@13 -- vbuxx_neq_vbuc1_then_la1 + cpx #$b + bne b13_from_b10 + jmp b4_from_b10 + //SEG34 [16] phi from main::@10 to main::@13 [phi:main::@10->main::@13] + b13_from_b10: + jmp b13 + //SEG35 main::@13 + b13: + //SEG36 [5] phi from main::@13 to main::@4 [phi:main::@13->main::@4] + b4_from_b13: + //SEG37 [5] phi (byte) main::x#6 = (byte) main::x#1 [phi:main::@13->main::@4#0] -- register_copy + jmp b4 +} +//SEG38 irq +irq: { + //SEG39 entry interrupt(KERNEL_MIN) + //SEG40 [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2 + lda #1 + sta IRQ_STATUS + //SEG41 asm { lda$dc0d } + lda $dc0d + //SEG42 [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 -- _deref_pbuc1=vbuz1 + lda col1 + sta SCREEN+$28 + //SEG43 [20] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz1 + inc col1 + jmp breturn + //SEG44 irq::@return + breturn: + //SEG45 [21] return - exit interrupt(KERNEL_MIN) + jmp $ea81 +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b2 +Removing instruction jmp bend +Removing instruction jmp b4 +Removing instruction jmp b5 +Removing instruction jmp b6 +Removing instruction jmp b9 +Removing instruction jmp b10 +Removing instruction jmp b13 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing label b6_from_b6 with b6 +Replacing label b5_from_b9 with b5 +Replacing label b13_from_b10 with b13 +Removing instruction b2_from_bbegin: +Removing instruction bend_from_b2: +Removing instruction b4_from_main: +Removing instruction b5_from_b4: +Removing instruction b5_from_b9: +Removing instruction b6_from_b5: +Removing instruction b6_from_b6: +Removing instruction b13_from_b10: +Removing instruction b4_from_b13: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bbegin: +Removing instruction b2: +Removing instruction bend: +Removing instruction b9: +Removing instruction b10: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Skipping double jump to b4 in bne b13 +Succesful ASM optimization Pass5DoubleJumpElimination +Relabelling long label b4_from_b10 to b1 +Succesful ASM optimization Pass5RelabelLongLabels +Removing instruction jmp b5 +Removing instruction jmp b6 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b13: +Succesful ASM optimization Pass5UnusedLabelElimination +Removing unreachable instruction jmp b4 +Succesful ASM optimization Pass5UnreachableCodeElimination + +FINAL SYMBOL TABLE +(label) @2 +(label) @begin +(label) @end +(byte*) CIA1_INTERRUPT +(byte*) IRQ_STATUS +(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024 +(byte) col1 +(byte) col1#0 col1 zp ZP_BYTE:2 2.0 +(byte) col1#1 col1 zp ZP_BYTE:2 20.0 +interrupt(KERNEL_MIN)(void()) irq() +(label) irq::@return +(void()) main() +(byte~) main::$1 reg byte a 20002.0 +(label) main::@10 +(label) main::@13 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@9 +(byte) main::a +(byte) main::a#1 reg byte y 15001.5 +(byte) main::a#2 reg byte y 10001.0 +(byte) main::x +(byte) main::x#1 reg byte x 71.0 +(byte) main::x#6 reg byte x 1123.6666666666665 +(byte) main::y +(byte) main::y#1 y zp ZP_BYTE:2 1501.5 +(byte) main::y#4 y zp ZP_BYTE:2 2000.4999999999998 + +reg byte x [ main::x#6 main::x#1 ] +zp ZP_BYTE:2 [ main::y#4 main::y#1 col1#0 col1#1 ] +reg byte y [ main::a#2 main::a#1 ] +reg byte a [ main::$1 ] + + +FINAL ASSEMBLER +Score: 223698 + +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label KERNEL_IRQ = $314 + .label IRQ_STATUS = $d019 + .label SCREEN = $400 + .label col1 = 2 +//SEG2 @begin +//SEG3 [0] (byte) col1#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- vbuz1=vbuc1 + lda #0 + sta col1 +//SEG4 [1] phi from @begin to @2 [phi:@begin->@2] +//SEG5 @2 +//SEG6 [2] call main + jsr main +//SEG7 [3] phi from @2 to @end [phi:@2->@end] +//SEG8 @end +//SEG9 main +main: { + .label y = 2 + //SEG10 [4] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 + lda #irq + sta KERNEL_IRQ+1 + //SEG11 [5] phi from main main::@10 to main::@4 [phi:main/main::@10->main::@4] + b1: + //SEG12 [5] phi (byte) main::x#6 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main/main::@10->main::@4#0] -- vbuxx=vbuc1 + ldx #0 + //SEG13 main::@4 + b4: + //SEG14 [6] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + //SEG15 [6] phi (byte) main::y#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@4->main::@5#0] -- vbuz1=vbuc1 + lda #0 + sta y + //SEG16 [6] phi from main::@9 to main::@5 [phi:main::@9->main::@5] + //SEG17 [6] phi (byte) main::y#4 = (byte) main::y#1 [phi:main::@9->main::@5#0] -- register_copy + //SEG18 main::@5 + b5: + //SEG19 [7] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + //SEG20 [7] phi (byte) main::a#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::@5->main::@6#0] -- vbuyy=vbuc1 + ldy #0 + //SEG21 [7] phi from main::@6 to main::@6 [phi:main::@6->main::@6] + //SEG22 [7] phi (byte) main::a#2 = (byte) main::a#1 [phi:main::@6->main::@6#0] -- register_copy + //SEG23 main::@6 + b6: + //SEG24 [8] (byte~) main::$1 ← (byte) main::a#2 + (byte) main::y#4 -- vbuaa=vbuyy_plus_vbuz1 + tya + clc + adc y + //SEG25 [9] *((const byte*) SCREEN#0 + (byte) main::x#6) ← (byte~) main::$1 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN,x + //SEG26 [10] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy + iny + //SEG27 [11] if((byte) main::a#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@6 -- vbuyy_neq_vbuc1_then_la1 + cpy #$b + bne b6 + //SEG28 main::@9 + //SEG29 [12] (byte) main::y#1 ← ++ (byte) main::y#4 -- vbuz1=_inc_vbuz1 + inc y + //SEG30 [13] if((byte) main::y#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@5 -- vbuz1_neq_vbuc1_then_la1 + lda y + cmp #$b + bne b5 + //SEG31 main::@10 + //SEG32 [14] (byte) main::x#1 ← ++ (byte) main::x#6 -- vbuxx=_inc_vbuxx + inx + //SEG33 [15] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 11) goto main::@13 -- vbuxx_neq_vbuc1_then_la1 + cpx #$b + bne b4 + jmp b1 + //SEG34 [16] phi from main::@10 to main::@13 [phi:main::@10->main::@13] + //SEG35 main::@13 + //SEG36 [5] phi from main::@13 to main::@4 [phi:main::@13->main::@4] + //SEG37 [5] phi (byte) main::x#6 = (byte) main::x#1 [phi:main::@13->main::@4#0] -- register_copy +} +//SEG38 irq +irq: { + //SEG39 entry interrupt(KERNEL_MIN) + //SEG40 [17] *((const byte*) IRQ_STATUS#0) ← (byte/signed byte/word/signed word/dword/signed dword) 1 -- _deref_pbuc1=vbuc2 + lda #1 + sta IRQ_STATUS + //SEG41 asm { lda$dc0d } + lda $dc0d + //SEG42 [19] *((const byte*) SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 40) ← (byte) col1#0 -- _deref_pbuc1=vbuz1 + lda col1 + sta SCREEN+$28 + //SEG43 [20] (byte) col1#1 ← ++ (byte) col1#0 -- vbuz1=_inc_vbuz1 + inc col1 + //SEG44 irq::@return + //SEG45 [21] return - exit interrupt(KERNEL_MIN) + jmp $ea81 +} + diff --git a/src/test/ref/interrupt-volatile-reuse-problem2.sym b/src/test/ref/interrupt-volatile-reuse-problem2.sym new file mode 100644 index 000000000..ec7349987 --- /dev/null +++ b/src/test/ref/interrupt-volatile-reuse-problem2.sym @@ -0,0 +1,37 @@ +(label) @2 +(label) @begin +(label) @end +(byte*) CIA1_INTERRUPT +(byte*) IRQ_STATUS +(const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 +(void()**) KERNEL_IRQ +(const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024 +(byte) col1 +(byte) col1#0 col1 zp ZP_BYTE:2 2.0 +(byte) col1#1 col1 zp ZP_BYTE:2 20.0 +interrupt(KERNEL_MIN)(void()) irq() +(label) irq::@return +(void()) main() +(byte~) main::$1 reg byte a 20002.0 +(label) main::@10 +(label) main::@13 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@9 +(byte) main::a +(byte) main::a#1 reg byte y 15001.5 +(byte) main::a#2 reg byte y 10001.0 +(byte) main::x +(byte) main::x#1 reg byte x 71.0 +(byte) main::x#6 reg byte x 1123.6666666666665 +(byte) main::y +(byte) main::y#1 y zp ZP_BYTE:2 1501.5 +(byte) main::y#4 y zp ZP_BYTE:2 2000.4999999999998 + +reg byte x [ main::x#6 main::x#1 ] +zp ZP_BYTE:2 [ main::y#4 main::y#1 col1#0 col1#1 ] +reg byte y [ main::a#2 main::a#1 ] +reg byte a [ main::$1 ]