1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Improved tests showcasing problems with volatiles.

This commit is contained in:
jespergravgaard 2018-12-24 14:14:29 +01:00
parent b92ea8415b
commit 85c6f09590
16 changed files with 1011 additions and 941 deletions

View File

@ -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 {

View File

@ -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++;
}

View File

@ -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++;
}

View File

@ -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++;
}

View File

@ -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
lda #>irq
sta KERNEL_IRQ+1
rts
}
irq: {
lda $dc0d
lda col1
sta BGCOL
inc col1
lda col2
sta BORDERCOL
inc col2
jmp $ea81
}

View File

@ -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

View File

@ -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
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
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
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
}

View File

@ -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 ]

View File

@ -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
lda #>irq
sta KERNEL_IRQ+1
rts
}
irq: {
lda col1
sta SCREEN+$28
inc col1
lda col2
sta SCREEN+$29
inc col2
jmp $ea81
}

View File

@ -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

Binary file not shown.

View File

@ -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

View File

@ -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
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
}

View File

@ -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

View File

@ -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
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
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
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
}

View File

@ -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 ]