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

Added 2 Raster IRQ tests.

This commit is contained in:
jespergravgaard 2018-08-06 00:37:40 +02:00
parent 238cd2a531
commit 044282e523
11 changed files with 1849 additions and 0 deletions

View File

@ -46,6 +46,16 @@ public class TestPrograms {
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
}
@Test
public void testIrqHyperscreen() throws IOException, URISyntaxException {
compileAndCompare("irq-hyperscreen");
}
@Test
public void testIrqRaster() throws IOException, URISyntaxException {
compileAndCompare("irq-raster");
}
@Test
public void testInterruptVolatile() throws IOException, URISyntaxException {
compileAndCompare("test-interrupt-volatile");

View File

@ -0,0 +1,60 @@
// A raster IRQ that opens the top/bottom border.
const void()** KERNEL_IRQ = $0314;
const byte* RASTER = $d012;
const byte* VIC_CONTROL = $d011;
const byte VIC_RSEL = $8;
const byte* IRQ_STATUS = $d019;
const byte* IRQ_ENABLE = $d01a;
const byte IRQ_RASTER = %00000001;
const byte IRQ_COLLISION_BG = %00000010;
const byte IRQ_COLLISION_SPRITE = %00000100;
const byte IRQ_LIGHTPEN = %00001000;
const byte* BGCOL = $d020;
const byte* FGCOL = $d021;
const byte WHITE = 1;
const byte RED = 2;
const byte* CIA1_INTERRUPT = $dc0d;
const byte CIA_INTERRUPT_CLEAR = $7f;
const byte* GHOST_BYTE = $3fff;
void main() {
*GHOST_BYTE = 0;
asm { sei }
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line to $100
*VIC_CONTROL &=$7f;
*RASTER = $fa;
// Enable Raster Interrupt
*IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*KERNEL_IRQ = &irq_bottom_1;
asm { cli }
}
// Interrupt Routine 1
interrupt void irq_bottom_1() {
*FGCOL = WHITE;
*VIC_CONTROL &= ($ff^VIC_RSEL);
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
// Trigger IRQ 2 at line $fd
*RASTER = $fd;
*KERNEL_IRQ = &irq_bottom_2;
*FGCOL = RED;
}
// Interrupt Routine 2
interrupt void irq_bottom_2() {
*FGCOL = WHITE;
*VIC_CONTROL |= VIC_RSEL;
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
// Trigger IRQ 1 at line $fa
*RASTER = $fa;
*KERNEL_IRQ = &irq_bottom_1;
*FGCOL = RED;
}

View File

@ -0,0 +1,39 @@
// A minimal working raster IRQ
const void()** KERNEL_IRQ = $0314;
const byte* RASTER = $d012;
const byte* VIC_CONTROL = $d011;
const byte* IRQ_STATUS = $d019;
const byte* IRQ_ENABLE = $d01a;
const byte IRQ_RASTER = %00000001;
const byte IRQ_COLLISION_BG = %00000010;
const byte IRQ_COLLISION_SPRITE = %00000100;
const byte IRQ_LIGHTPEN = %00001000;
const byte* BGCOL = $d020;
const byte WHITE = 1;
const byte BLACK = 0;
const byte* CIA1_INTERRUPT = $dc0d;
const byte CIA_INTERRUPT_CLEAR = $7f;
void main() {
asm { sei }
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line to $100
*VIC_CONTROL |=$80;
*RASTER = $00;
// Enable Raster Interrupt
*IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*KERNEL_IRQ = &irq;
asm { cli }
}
// Interrupt Routine
interrupt void irq() {
*BGCOL = WHITE;
*BGCOL = BLACK;
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
}

View File

@ -0,0 +1,73 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label FGCOL = $d021
.const WHITE = 1
.const RED = 2
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
.label GHOST_BYTE = $3fff
jsr main
main: {
lda #0
sta GHOST_BYTE
sei
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
lda #$fa
sta RASTER
lda #IRQ_RASTER
sta IRQ_ENABLE
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
cli
rts
}
irq_bottom_2: {
lda #WHITE
sta FGCOL
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
lda #IRQ_RASTER
sta IRQ_STATUS
lda #$fa
sta RASTER
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
lda #RED
sta FGCOL
jmp $ea81
}
irq_bottom_1: {
lda #WHITE
sta FGCOL
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
lda #IRQ_RASTER
sta IRQ_STATUS
lda #$fd
sta RASTER
lda #<irq_bottom_2
sta KERNEL_IRQ
lda #>irq_bottom_2
sta KERNEL_IRQ+1
lda #RED
sta FGCOL
jmp $ea81
}

View File

@ -0,0 +1,44 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@3
@3: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main [ ] ( )
to:@end
@end: scope:[] from @3
[3] phi() [ ] ( )
main: scope:[main] from @3
[4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] )
asm { sei }
[6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] )
[7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] )
[8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] )
[9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] )
[10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] )
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[12] return [ ] ( main:2 [ ] )
to:@return
irq_bottom_2: scope:[irq_bottom_2] from
[13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( )
[14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( )
[15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( )
[16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( )
[17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( )
[18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( )
to:irq_bottom_2::@return
irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2
[19] return [ ] ( )
to:@return
irq_bottom_1: scope:[irq_bottom_1] from
[20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( )
[21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( )
[22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( )
[23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( )
[24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( )
[25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( )
to:irq_bottom_1::@return
irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1
[26] return [ ] ( )
to:@return

View File

@ -0,0 +1,882 @@
PARSING src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc
// A raster IRQ that opens the top/bottom border.
const void()** KERNEL_IRQ = $0314;
const byte* RASTER = $d012;
const byte* VIC_CONTROL = $d011;
const byte VIC_RSEL = $8;
const byte* IRQ_STATUS = $d019;
const byte* IRQ_ENABLE = $d01a;
const byte IRQ_RASTER = %00000001;
const byte IRQ_COLLISION_BG = %00000010;
const byte IRQ_COLLISION_SPRITE = %00000100;
const byte IRQ_LIGHTPEN = %00001000;
const byte* BGCOL = $d020;
const byte* FGCOL = $d021;
const byte WHITE = 1;
const byte RED = 2;
const byte* CIA1_INTERRUPT = $dc0d;
const byte CIA_INTERRUPT_CLEAR = $7f;
const byte* GHOST_BYTE = $3fff;
void main() {
*GHOST_BYTE = 0;
asm { sei }
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line to $100
*VIC_CONTROL &=$7f;
*RASTER = $fa;
// Enable Raster Interrupt
*IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*KERNEL_IRQ = &irq_bottom_1;
asm { cli }
}
// Interrupt Routine 1
interrupt void irq_bottom_1() {
*FGCOL = WHITE;
*VIC_CONTROL &= ($ff^VIC_RSEL);
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
// Trigger IRQ 2 at line $fd
*RASTER = $fd;
*KERNEL_IRQ = &irq_bottom_2;
*FGCOL = RED;
}
// Interrupt Routine 2
interrupt void irq_bottom_2() {
*FGCOL = WHITE;
*VIC_CONTROL |= VIC_RSEL;
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
// Trigger IRQ 1 at line $fa
*RASTER = $fa;
*KERNEL_IRQ = &irq_bottom_1;
*FGCOL = RED;
}
Resolved forward reference irq_bottom_1 to interrupt(KERNEL)(void()) irq_bottom_1()
Resolved forward reference irq_bottom_2 to interrupt(KERNEL)(void()) irq_bottom_2()
SYMBOLS
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) CIA1_INTERRUPT
(byte) CIA_INTERRUPT_CLEAR
(byte*) FGCOL
(byte*) GHOST_BYTE
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(byte) IRQ_LIGHTPEN
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) RASTER
(byte) RED
(byte*) VIC_CONTROL
(byte) VIC_RSEL
(byte) WHITE
interrupt(KERNEL)(void()) irq_bottom_1()
(byte/word/dword~) irq_bottom_1::$0
(void()*~) irq_bottom_1::$1
(label) irq_bottom_1::@return
interrupt(KERNEL)(void()) irq_bottom_2()
(void()*~) irq_bottom_2::$0
(label) irq_bottom_2::@return
(void()) main()
(void()*~) main::$0
(label) main::@return
Promoting word/signed word/dword/signed dword to void()** in KERNEL_IRQ ← ((void()**)) 788
Promoting word/dword/signed dword to byte* in RASTER ← ((byte*)) 53266
Promoting word/dword/signed dword to byte* in VIC_CONTROL ← ((byte*)) 53265
Promoting word/dword/signed dword to byte* in IRQ_STATUS ← ((byte*)) 53273
Promoting word/dword/signed dword to byte* in IRQ_ENABLE ← ((byte*)) 53274
Promoting word/dword/signed dword to byte* in BGCOL ← ((byte*)) 53280
Promoting word/dword/signed dword to byte* in FGCOL ← ((byte*)) 53281
Promoting word/dword/signed dword to byte* in CIA1_INTERRUPT ← ((byte*)) 56333
Promoting word/signed word/dword/signed dword to byte* in GHOST_BYTE ← ((byte*)) 16383
INITIAL CONTROL FLOW GRAPH
@begin: scope:[] from
(void()**) KERNEL_IRQ ← ((void()**)) (word/signed word/dword/signed dword) 788
(byte*) RASTER ← ((byte*)) (word/dword/signed dword) 53266
(byte*) VIC_CONTROL ← ((byte*)) (word/dword/signed dword) 53265
(byte) VIC_RSEL ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) IRQ_STATUS ← ((byte*)) (word/dword/signed dword) 53273
(byte*) IRQ_ENABLE ← ((byte*)) (word/dword/signed dword) 53274
(byte) IRQ_RASTER ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2
(byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) BGCOL ← ((byte*)) (word/dword/signed dword) 53280
(byte*) FGCOL ← ((byte*)) (word/dword/signed dword) 53281
(byte) WHITE ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) RED ← (byte/signed byte/word/signed word/dword/signed dword) 2
(byte*) CIA1_INTERRUPT ← ((byte*)) (word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR ← (byte/signed byte/word/signed word/dword/signed dword) 127
(byte*) GHOST_BYTE ← ((byte*)) (word/signed word/dword/signed dword) 16383
to:@1
main: scope:[main] from
*((byte*) GHOST_BYTE) ← (byte/signed byte/word/signed word/dword/signed dword) 0
asm { sei }
*((byte*) CIA1_INTERRUPT) ← (byte) CIA_INTERRUPT_CLEAR
*((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) & (byte/signed byte/word/signed word/dword/signed dword) 127
*((byte*) RASTER) ← (byte/word/signed word/dword/signed dword) 250
*((byte*) IRQ_ENABLE) ← (byte) IRQ_RASTER
(void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1()
*((void()**) KERNEL_IRQ) ← (void()*~) main::$0
asm { cli }
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
to:@2
irq_bottom_1: scope:[irq_bottom_1] from
*((byte*) FGCOL) ← (byte) WHITE
(byte/word/dword~) irq_bottom_1::$0 ← (byte/word/signed word/dword/signed dword) 255 ^ (byte) VIC_RSEL
*((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) & (byte/word/dword~) irq_bottom_1::$0
*((byte*) IRQ_STATUS) ← (byte) IRQ_RASTER
*((byte*) RASTER) ← (byte/word/signed word/dword/signed dword) 253
(void()*~) irq_bottom_1::$1 ← & interrupt(KERNEL)(void()) irq_bottom_2()
*((void()**) KERNEL_IRQ) ← (void()*~) irq_bottom_1::$1
*((byte*) FGCOL) ← (byte) RED
to:irq_bottom_1::@return
irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1
return
to:@return
@2: scope:[] from @1
to:@3
irq_bottom_2: scope:[irq_bottom_2] from
*((byte*) FGCOL) ← (byte) WHITE
*((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) | (byte) VIC_RSEL
*((byte*) IRQ_STATUS) ← (byte) IRQ_RASTER
*((byte*) RASTER) ← (byte/word/signed word/dword/signed dword) 250
(void()*~) irq_bottom_2::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1()
*((void()**) KERNEL_IRQ) ← (void()*~) irq_bottom_2::$0
*((byte*) FGCOL) ← (byte) RED
to:irq_bottom_2::@return
irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2
return
to:@return
@3: scope:[] from @2
call main
to:@end
@end: scope:[] from @3
Eliminating unused variable (byte) IRQ_COLLISION_BG and assignment [7] (byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2
Eliminating unused variable (byte) IRQ_COLLISION_SPRITE and assignment [8] (byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4
Eliminating unused variable (byte) IRQ_LIGHTPEN and assignment [9] (byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8
Eliminating unused variable (byte*) BGCOL and assignment [10] (byte*) BGCOL ← ((byte*)) (word/dword/signed dword) 53280
Removing empty block @1
Removing empty block @2
PROCEDURE MODIFY VARIABLE ANALYSIS
Completing Phi functions...
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
@begin: scope:[] from
(void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788
(byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266
(byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265
(byte) VIC_RSEL#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273
(byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274
(byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte*) FGCOL#0 ← ((byte*)) (word/dword/signed dword) 53281
(byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) RED#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2
(byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127
(byte*) GHOST_BYTE#0 ← ((byte*)) (word/signed word/dword/signed dword) 16383
to:@3
main: scope:[main] from @3
*((byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
asm { sei }
*((byte*) CIA1_INTERRUPT#0) ← (byte) CIA_INTERRUPT_CLEAR#0
*((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127
*((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250
*((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0
(void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1()
*((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0
asm { cli }
to:main::@return
main::@return: scope:[main] from main
return
to:@return
irq_bottom_1: scope:[irq_bottom_1] from
*((byte*) FGCOL#0) ← (byte) WHITE#0
(byte/word/dword~) irq_bottom_1::$0 ← (byte/word/signed word/dword/signed dword) 255 ^ (byte) VIC_RSEL#0
*((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) & (byte/word/dword~) irq_bottom_1::$0
*((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0
*((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253
(void()*~) irq_bottom_1::$1 ← & interrupt(KERNEL)(void()) irq_bottom_2()
*((void()**) KERNEL_IRQ#0) ← (void()*~) irq_bottom_1::$1
*((byte*) FGCOL#0) ← (byte) RED#0
to:irq_bottom_1::@return
irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1
return
to:@return
irq_bottom_2: scope:[irq_bottom_2] from
*((byte*) FGCOL#0) ← (byte) WHITE#0
*((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (byte) VIC_RSEL#0
*((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0
*((byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250
(void()*~) irq_bottom_2::$0 ← & interrupt(KERNEL)(void()) irq_bottom_1()
*((void()**) KERNEL_IRQ#0) ← (void()*~) irq_bottom_2::$0
*((byte*) FGCOL#0) ← (byte) RED#0
to:irq_bottom_2::@return
irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2
return
to:@return
@3: scope:[] from @begin
call main
to:@4
@4: scope:[] from @3
to:@end
@end: scope:[] from @4
SYMBOL TABLE SSA
(label) @3
(label) @4
(label) @begin
(label) @end
(byte*) CIA1_INTERRUPT
(byte*) CIA1_INTERRUPT#0
(byte) CIA_INTERRUPT_CLEAR
(byte) CIA_INTERRUPT_CLEAR#0
(byte*) FGCOL
(byte*) FGCOL#0
(byte*) GHOST_BYTE
(byte*) GHOST_BYTE#0
(byte*) IRQ_ENABLE
(byte*) IRQ_ENABLE#0
(byte) IRQ_RASTER
(byte) IRQ_RASTER#0
(byte*) IRQ_STATUS
(byte*) IRQ_STATUS#0
(void()**) KERNEL_IRQ
(void()**) KERNEL_IRQ#0
(byte*) RASTER
(byte*) RASTER#0
(byte) RED
(byte) RED#0
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL#0
(byte) VIC_RSEL
(byte) VIC_RSEL#0
(byte) WHITE
(byte) WHITE#0
interrupt(KERNEL)(void()) irq_bottom_1()
(byte/word/dword~) irq_bottom_1::$0
(void()*~) irq_bottom_1::$1
(label) irq_bottom_1::@return
interrupt(KERNEL)(void()) irq_bottom_2()
(void()*~) irq_bottom_2::$0
(label) irq_bottom_2::@return
(void()) main()
(void()*~) main::$0
(label) main::@return
OPTIMIZING CONTROL FLOW GRAPH
Culled Empty Block (label) @4
Succesful SSA optimization Pass2CullEmptyBlocks
Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788
Constant (const byte*) RASTER#0 = ((byte*))53266
Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265
Constant (const byte) VIC_RSEL#0 = 8
Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273
Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274
Constant (const byte) IRQ_RASTER#0 = 1
Constant (const byte*) FGCOL#0 = ((byte*))53281
Constant (const byte) WHITE#0 = 1
Constant (const byte) RED#0 = 2
Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333
Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127
Constant (const byte*) GHOST_BYTE#0 = ((byte*))16383
Constant (const void()*) main::$0 = &irq_bottom_1
Constant (const void()*) irq_bottom_1::$1 = &irq_bottom_2
Constant (const void()*) irq_bottom_2::$0 = &irq_bottom_1
Succesful SSA optimization Pass2ConstantIdentification
Constant (const byte/word/dword) irq_bottom_1::$0 = 255^VIC_RSEL#0
Succesful SSA optimization Pass2ConstantIdentification
OPTIMIZING CONTROL FLOW GRAPH
Constant inlined irq_bottom_2::$0 = &interrupt(KERNEL)(void()) irq_bottom_1()
Constant inlined irq_bottom_1::$0 = (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0
Constant inlined main::$0 = &interrupt(KERNEL)(void()) irq_bottom_1()
Constant inlined irq_bottom_1::$1 = &interrupt(KERNEL)(void()) irq_bottom_2()
Succesful SSA optimization Pass2ConstantInlining
Block Sequence Planned @begin @3 @end main main::@return irq_bottom_2 irq_bottom_2::@return irq_bottom_1 irq_bottom_1::@return
Block Sequence Planned @begin @3 @end main main::@return irq_bottom_2 irq_bottom_2::@return irq_bottom_1 irq_bottom_1::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Propagating live ranges...
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Block Sequence Planned @begin @3 @end main main::@return irq_bottom_2 irq_bottom_2::@return irq_bottom_1 irq_bottom_1::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @3
Adding NOP phi() at start of @end
Propagating live ranges...
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi() [ ] ( )
to:@3
@3: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main [ ] ( )
to:@end
@end: scope:[] from @3
[3] phi() [ ] ( )
main: scope:[main] from @3
[4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] )
asm { sei }
[6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] )
[7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] )
[8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] )
[9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] )
[10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] )
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[12] return [ ] ( main:2 [ ] )
to:@return
irq_bottom_2: scope:[irq_bottom_2] from
[13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( )
[14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( )
[15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( )
[16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( )
[17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( )
[18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( )
to:irq_bottom_2::@return
irq_bottom_2::@return: scope:[irq_bottom_2] from irq_bottom_2
[19] return [ ] ( )
to:@return
irq_bottom_1: scope:[irq_bottom_1] from
[20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( )
[21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( )
[22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( )
[23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( )
[24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( )
[25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( )
to:irq_bottom_1::@return
irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1
[26] return [ ] ( )
to:@return
DOMINATORS
@begin dominated by @begin
@3 dominated by @begin @3
@end dominated by @begin @3 @end
main dominated by @begin @3 main
main::@return dominated by main::@return @begin @3 main
irq_bottom_2 dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main
irq_bottom_2::@return dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main
irq_bottom_1 dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main
irq_bottom_1::@return dominated by main::@return irq_bottom_1 irq_bottom_2 @begin @3 @end irq_bottom_1::@return irq_bottom_2::@return main
NATURAL LOOPS
Found back edge: Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: null
Found back edge: Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: null
Populated: Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2
Populated: Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1
Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2
Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1
NATURAL LOOPS WITH DEPTH
Found 1 loops in scope [irq_bottom_2]
Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2
Found 1 loops in scope [irq_bottom_1]
Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1
Found 0 loops in scope []
Found 0 loops in scope [main]
Loop head: irq_bottom_2::@return tails: irq_bottom_2 blocks: irq_bottom_2 depth: 1
Loop head: irq_bottom_1::@return tails: irq_bottom_1 blocks: irq_bottom_1 depth: 1
VARIABLE REGISTER WEIGHTS
(byte*) CIA1_INTERRUPT
(byte) CIA_INTERRUPT_CLEAR
(byte*) FGCOL
(byte*) GHOST_BYTE
(byte*) IRQ_ENABLE
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) RASTER
(byte) RED
(byte*) VIC_CONTROL
(byte) VIC_RSEL
(byte) WHITE
interrupt(KERNEL)(void()) irq_bottom_1()
interrupt(KERNEL)(void()) irq_bottom_2()
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label FGCOL = $d021
.const WHITE = 1
.const RED = 2
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
.label GHOST_BYTE = $3fff
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @3 [phi:@begin->@3]
b3_from_bbegin:
jmp b3
//SEG4 @3
b3:
//SEG5 [2] call main [ ] ( )
jsr main
//SEG6 [3] phi from @3 to @end [phi:@3->@end]
bend_from_b3:
jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
//SEG9 [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #0
sta GHOST_BYTE
//SEG10 asm { sei }
sei
//SEG11 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG12 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
//SEG13 [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #$fa
sta RASTER
//SEG14 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG15 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
//SEG16 asm { cli }
cli
jmp breturn
//SEG17 main::@return
breturn:
//SEG18 [12] return [ ] ( main:2 [ ] )
rts
}
//SEG19 irq_bottom_2
irq_bottom_2: {
//SEG20 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta FGCOL
//SEG21 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
//SEG22 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG23 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #$fa
sta RASTER
//SEG24 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) -- _deref_pptc1=pprc2
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
//SEG25 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #RED
sta FGCOL
jmp breturn
//SEG26 irq_bottom_2::@return
breturn:
//SEG27 [19] return [ ] ( )
jmp $ea81
}
//SEG28 irq_bottom_1
irq_bottom_1: {
//SEG29 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta FGCOL
//SEG30 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
//SEG31 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG32 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #$fd
sta RASTER
//SEG33 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) -- _deref_pptc1=pprc2
lda #<irq_bottom_2
sta KERNEL_IRQ
lda #>irq_bottom_2
sta KERNEL_IRQ+1
//SEG34 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #RED
sta FGCOL
jmp breturn
//SEG35 irq_bottom_1::@return
breturn:
//SEG36 [26] return [ ] ( )
jmp $ea81
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) always clobbers reg byte a
Statement [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) always clobbers reg byte a
Statement [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) always clobbers reg byte a
Statement [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) always clobbers reg byte a
Statement [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) always clobbers reg byte a
Statement [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a
Statement [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) always clobbers reg byte a
Statement [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) always clobbers reg byte a
Statement [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) always clobbers reg byte a
Statement [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) always clobbers reg byte a
Statement [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) always clobbers reg byte a
Statement [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [irq_bottom_1]
Uplift Scope [irq_bottom_2]
Uplift Scope []
Uplifting [main] best 1057 combination
Uplifting [irq_bottom_1] best 1057 combination
Uplifting [irq_bottom_2] best 1057 combination
Uplifting [] best 1057 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label FGCOL = $d021
.const WHITE = 1
.const RED = 2
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
.label GHOST_BYTE = $3fff
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @3 [phi:@begin->@3]
b3_from_bbegin:
jmp b3
//SEG4 @3
b3:
//SEG5 [2] call main [ ] ( )
jsr main
//SEG6 [3] phi from @3 to @end [phi:@3->@end]
bend_from_b3:
jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
//SEG9 [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #0
sta GHOST_BYTE
//SEG10 asm { sei }
sei
//SEG11 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG12 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
//SEG13 [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #$fa
sta RASTER
//SEG14 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG15 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
//SEG16 asm { cli }
cli
jmp breturn
//SEG17 main::@return
breturn:
//SEG18 [12] return [ ] ( main:2 [ ] )
rts
}
//SEG19 irq_bottom_2
irq_bottom_2: {
//SEG20 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta FGCOL
//SEG21 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
//SEG22 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG23 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #$fa
sta RASTER
//SEG24 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) -- _deref_pptc1=pprc2
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
//SEG25 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #RED
sta FGCOL
jmp breturn
//SEG26 irq_bottom_2::@return
breturn:
//SEG27 [19] return [ ] ( )
jmp $ea81
}
//SEG28 irq_bottom_1
irq_bottom_1: {
//SEG29 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta FGCOL
//SEG30 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
//SEG31 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG32 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #$fd
sta RASTER
//SEG33 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) -- _deref_pptc1=pprc2
lda #<irq_bottom_2
sta KERNEL_IRQ
lda #>irq_bottom_2
sta KERNEL_IRQ+1
//SEG34 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #RED
sta FGCOL
jmp breturn
//SEG35 irq_bottom_1::@return
breturn:
//SEG36 [26] return [ ] ( )
jmp $ea81
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b3
Removing instruction jmp bend
Removing instruction jmp breturn
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction bbegin:
Removing instruction b3_from_bbegin:
Removing instruction bend_from_b3:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b3:
Removing instruction bend:
Removing instruction breturn:
Removing instruction breturn:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @3
(label) @begin
(label) @end
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127
(byte*) FGCOL
(const byte*) FGCOL#0 FGCOL = ((byte*))(word/dword/signed dword) 53281
(byte*) GHOST_BYTE
(const byte*) GHOST_BYTE#0 GHOST_BYTE = ((byte*))(word/signed word/dword/signed dword) 16383
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274
(byte) IRQ_RASTER
(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1
(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*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
(byte) RED
(const byte) RED#0 RED = (byte/signed byte/word/signed word/dword/signed dword) 2
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265
(byte) VIC_RSEL
(const byte) VIC_RSEL#0 VIC_RSEL = (byte/signed byte/word/signed word/dword/signed dword) 8
(byte) WHITE
(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1
interrupt(KERNEL)(void()) irq_bottom_1()
(label) irq_bottom_1::@return
interrupt(KERNEL)(void()) irq_bottom_2()
(label) irq_bottom_2::@return
(void()) main()
(label) main::@return
FINAL ASSEMBLER
Score: 988
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.const VIC_RSEL = 8
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label FGCOL = $d021
.const WHITE = 1
.const RED = 2
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
.label GHOST_BYTE = $3fff
//SEG2 @begin
//SEG3 [1] phi from @begin to @3 [phi:@begin->@3]
//SEG4 @3
//SEG5 [2] call main [ ] ( )
jsr main
//SEG6 [3] phi from @3 to @end [phi:@3->@end]
//SEG7 @end
//SEG8 main
main: {
//SEG9 [4] *((const byte*) GHOST_BYTE#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #0
sta GHOST_BYTE
//SEG10 asm { sei }
sei
//SEG11 [6] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG12 [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/signed byte/word/signed word/dword/signed dword) 127 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
lda VIC_CONTROL
and #$7f
sta VIC_CONTROL
//SEG13 [8] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #$fa
sta RASTER
//SEG14 [9] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG15 [10] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
//SEG16 asm { cli }
cli
//SEG17 main::@return
//SEG18 [12] return [ ] ( main:2 [ ] )
rts
}
//SEG19 irq_bottom_2
irq_bottom_2: {
//SEG20 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta FGCOL
//SEG21 [14] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
lda VIC_CONTROL
ora #VIC_RSEL
sta VIC_CONTROL
//SEG22 [15] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG23 [16] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 250 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #$fa
sta RASTER
//SEG24 [17] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_1() [ ] ( ) -- _deref_pptc1=pprc2
lda #<irq_bottom_1
sta KERNEL_IRQ
lda #>irq_bottom_1
sta KERNEL_IRQ+1
//SEG25 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #RED
sta FGCOL
//SEG26 irq_bottom_2::@return
//SEG27 [19] return [ ] ( )
jmp $ea81
}
//SEG28 irq_bottom_1
irq_bottom_1: {
//SEG29 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta FGCOL
//SEG30 [21] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) & (byte/word/signed word/dword/signed dword) 255^(const byte) VIC_RSEL#0 [ ] ( ) -- _deref_pbuc1=_deref_pbuc1_band_vbuc2
lda VIC_CONTROL
and #$ff^VIC_RSEL
sta VIC_CONTROL
//SEG31 [22] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG32 [23] *((const byte*) RASTER#0) ← (byte/word/signed word/dword/signed dword) 253 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #$fd
sta RASTER
//SEG33 [24] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq_bottom_2() [ ] ( ) -- _deref_pptc1=pprc2
lda #<irq_bottom_2
sta KERNEL_IRQ
lda #>irq_bottom_2
sta KERNEL_IRQ+1
//SEG34 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #RED
sta FGCOL
//SEG35 irq_bottom_1::@return
//SEG36 [26] return [ ] ( )
jmp $ea81
}

View File

@ -0,0 +1,36 @@
(label) @3
(label) @begin
(label) @end
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127
(byte*) FGCOL
(const byte*) FGCOL#0 FGCOL = ((byte*))(word/dword/signed dword) 53281
(byte*) GHOST_BYTE
(const byte*) GHOST_BYTE#0 GHOST_BYTE = ((byte*))(word/signed word/dword/signed dword) 16383
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274
(byte) IRQ_RASTER
(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1
(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*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
(byte) RED
(const byte) RED#0 RED = (byte/signed byte/word/signed word/dword/signed dword) 2
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265
(byte) VIC_RSEL
(const byte) VIC_RSEL#0 VIC_RSEL = (byte/signed byte/word/signed word/dword/signed dword) 8
(byte) WHITE
(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1
interrupt(KERNEL)(void()) irq_bottom_1()
(label) irq_bottom_1::@return
interrupt(KERNEL)(void()) irq_bottom_2()
(label) irq_bottom_2::@return
(void()) main()
(label) main::@return

View File

@ -0,0 +1,42 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label BGCOL = $d020
.const WHITE = 1
.const BLACK = 0
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
jsr main
main: {
sei
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
lda VIC_CONTROL
ora #$80
sta VIC_CONTROL
lda #0
sta RASTER
lda #IRQ_RASTER
sta IRQ_ENABLE
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
cli
rts
}
irq: {
lda #WHITE
sta BGCOL
lda #BLACK
sta BGCOL
lda #IRQ_RASTER
sta IRQ_STATUS
jmp $ea81
}

View File

@ -0,0 +1,29 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@2
@2: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main [ ] ( )
to:@end
@end: scope:[] from @2
[3] phi() [ ] ( )
main: scope:[main] from @2
asm { sei }
[5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] )
[6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] )
[7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] )
[8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] )
[9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] )
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[11] return [ ] ( main:2 [ ] )
to:@return
irq: scope:[irq] from
[12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( )
[13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( )
[14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( )
to:irq::@return
irq::@return: scope:[irq] from irq
[15] return [ ] ( )
to:@return

View File

@ -0,0 +1,604 @@
PARSING src/test/java/dk/camelot64/kickc/test/kc/irq-raster.kc
// A minimal working raster IRQ
const void()** KERNEL_IRQ = $0314;
const byte* RASTER = $d012;
const byte* VIC_CONTROL = $d011;
const byte* IRQ_STATUS = $d019;
const byte* IRQ_ENABLE = $d01a;
const byte IRQ_RASTER = %00000001;
const byte IRQ_COLLISION_BG = %00000010;
const byte IRQ_COLLISION_SPRITE = %00000100;
const byte IRQ_LIGHTPEN = %00001000;
const byte* BGCOL = $d020;
const byte WHITE = 1;
const byte BLACK = 0;
const byte* CIA1_INTERRUPT = $dc0d;
const byte CIA_INTERRUPT_CLEAR = $7f;
void main() {
asm { sei }
// Disable CIA 1 Timer IRQ
*CIA1_INTERRUPT = CIA_INTERRUPT_CLEAR;
// Set raster line to $100
*VIC_CONTROL |=$80;
*RASTER = $00;
// Enable Raster Interrupt
*IRQ_ENABLE = IRQ_RASTER;
// Set the IRQ routine
*KERNEL_IRQ = &irq;
asm { cli }
}
// Interrupt Routine
interrupt void irq() {
*BGCOL = WHITE;
*BGCOL = BLACK;
// Acknowledge the IRQ
*IRQ_STATUS = IRQ_RASTER;
}
Resolved forward reference irq to interrupt(KERNEL)(void()) irq()
SYMBOLS
(label) @1
(label) @2
(label) @begin
(label) @end
(byte*) BGCOL
(byte) BLACK
(byte*) CIA1_INTERRUPT
(byte) CIA_INTERRUPT_CLEAR
(byte) IRQ_COLLISION_BG
(byte) IRQ_COLLISION_SPRITE
(byte*) IRQ_ENABLE
(byte) IRQ_LIGHTPEN
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) RASTER
(byte*) VIC_CONTROL
(byte) WHITE
interrupt(KERNEL)(void()) irq()
(label) irq::@return
(void()) main()
(void()*~) main::$0
(label) main::@return
Promoting word/signed word/dword/signed dword to void()** in KERNEL_IRQ ← ((void()**)) 788
Promoting word/dword/signed dword to byte* in RASTER ← ((byte*)) 53266
Promoting word/dword/signed dword to byte* in VIC_CONTROL ← ((byte*)) 53265
Promoting word/dword/signed dword to byte* in IRQ_STATUS ← ((byte*)) 53273
Promoting word/dword/signed dword to byte* in IRQ_ENABLE ← ((byte*)) 53274
Promoting word/dword/signed dword to byte* in BGCOL ← ((byte*)) 53280
Promoting word/dword/signed dword to byte* in CIA1_INTERRUPT ← ((byte*)) 56333
INITIAL CONTROL FLOW GRAPH
@begin: scope:[] from
(void()**) KERNEL_IRQ ← ((void()**)) (word/signed word/dword/signed dword) 788
(byte*) RASTER ← ((byte*)) (word/dword/signed dword) 53266
(byte*) VIC_CONTROL ← ((byte*)) (word/dword/signed dword) 53265
(byte*) IRQ_STATUS ← ((byte*)) (word/dword/signed dword) 53273
(byte*) IRQ_ENABLE ← ((byte*)) (word/dword/signed dword) 53274
(byte) IRQ_RASTER ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2
(byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4
(byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8
(byte*) BGCOL ← ((byte*)) (word/dword/signed dword) 53280
(byte) WHITE ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) BLACK ← (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) CIA1_INTERRUPT ← ((byte*)) (word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR ← (byte/signed byte/word/signed word/dword/signed dword) 127
to:@1
main: scope:[main] from
asm { sei }
*((byte*) CIA1_INTERRUPT) ← (byte) CIA_INTERRUPT_CLEAR
*((byte*) VIC_CONTROL) ← *((byte*) VIC_CONTROL) | (byte/word/signed word/dword/signed dword) 128
*((byte*) RASTER) ← (byte/signed byte/word/signed word/dword/signed dword) 0
*((byte*) IRQ_ENABLE) ← (byte) IRQ_RASTER
(void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq()
*((void()**) KERNEL_IRQ) ← (void()*~) main::$0
asm { cli }
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
to:@2
irq: scope:[irq] from
*((byte*) BGCOL) ← (byte) WHITE
*((byte*) BGCOL) ← (byte) BLACK
*((byte*) IRQ_STATUS) ← (byte) IRQ_RASTER
to:irq::@return
irq::@return: scope:[irq] from irq
return
to:@return
@2: scope:[] from @1
call main
to:@end
@end: scope:[] from @2
Eliminating unused variable (byte) IRQ_COLLISION_BG and assignment [6] (byte) IRQ_COLLISION_BG ← (byte/signed byte/word/signed word/dword/signed dword) 2
Eliminating unused variable (byte) IRQ_COLLISION_SPRITE and assignment [7] (byte) IRQ_COLLISION_SPRITE ← (byte/signed byte/word/signed word/dword/signed dword) 4
Eliminating unused variable (byte) IRQ_LIGHTPEN and assignment [8] (byte) IRQ_LIGHTPEN ← (byte/signed byte/word/signed word/dword/signed dword) 8
Removing empty block @1
PROCEDURE MODIFY VARIABLE ANALYSIS
Completing Phi functions...
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
@begin: scope:[] from
(void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788
(byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266
(byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265
(byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273
(byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274
(byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53280
(byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1
(byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127
to:@2
main: scope:[main] from @2
asm { sei }
*((byte*) CIA1_INTERRUPT#0) ← (byte) CIA_INTERRUPT_CLEAR#0
*((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128
*((byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0
*((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0
(void()*~) main::$0 ← & interrupt(KERNEL)(void()) irq()
*((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0
asm { cli }
to:main::@return
main::@return: scope:[main] from main
return
to:@return
irq: scope:[irq] from
*((byte*) BGCOL#0) ← (byte) WHITE#0
*((byte*) BGCOL#0) ← (byte) BLACK#0
*((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0
to:irq::@return
irq::@return: scope:[irq] from irq
return
to:@return
@2: scope:[] from @begin
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) BLACK
(byte) BLACK#0
(byte*) CIA1_INTERRUPT
(byte*) CIA1_INTERRUPT#0
(byte) CIA_INTERRUPT_CLEAR
(byte) CIA_INTERRUPT_CLEAR#0
(byte*) IRQ_ENABLE
(byte*) IRQ_ENABLE#0
(byte) IRQ_RASTER
(byte) IRQ_RASTER#0
(byte*) IRQ_STATUS
(byte*) IRQ_STATUS#0
(void()**) KERNEL_IRQ
(void()**) KERNEL_IRQ#0
(byte*) RASTER
(byte*) RASTER#0
(byte*) VIC_CONTROL
(byte*) VIC_CONTROL#0
(byte) WHITE
(byte) WHITE#0
interrupt(KERNEL)(void()) irq()
(label) irq::@return
(void()) main()
(void()*~) main::$0
(label) main::@return
OPTIMIZING CONTROL FLOW GRAPH
Culled Empty Block (label) @3
Succesful SSA optimization Pass2CullEmptyBlocks
Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788
Constant (const byte*) RASTER#0 = ((byte*))53266
Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265
Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273
Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274
Constant (const byte) IRQ_RASTER#0 = 1
Constant (const byte*) BGCOL#0 = ((byte*))53280
Constant (const byte) WHITE#0 = 1
Constant (const byte) BLACK#0 = 0
Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333
Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127
Constant (const void()*) main::$0 = &irq
Succesful SSA optimization Pass2ConstantIdentification
OPTIMIZING CONTROL FLOW GRAPH
Constant inlined main::$0 = &interrupt(KERNEL)(void()) irq()
Succesful SSA optimization Pass2ConstantInlining
Block Sequence Planned @begin @2 @end main main::@return irq irq::@return
Block Sequence Planned @begin @2 @end main main::@return irq irq::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Propagating live ranges...
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Block Sequence Planned @begin @2 @end main main::@return irq irq::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Propagating live ranges...
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi() [ ] ( )
to:@2
@2: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main [ ] ( )
to:@end
@end: scope:[] from @2
[3] phi() [ ] ( )
main: scope:[main] from @2
asm { sei }
[5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] )
[6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] )
[7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] )
[8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] )
[9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] )
asm { cli }
to:main::@return
main::@return: scope:[main] from main
[11] return [ ] ( main:2 [ ] )
to:@return
irq: scope:[irq] from
[12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( )
[13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( )
[14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( )
to:irq::@return
irq::@return: scope:[irq] from irq
[15] return [ ] ( )
to:@return
DOMINATORS
@begin dominated by @begin
@2 dominated by @2 @begin
@end dominated by @2 @begin @end
main dominated by @2 @begin main
main::@return dominated by main::@return @2 @begin main
irq dominated by main::@return @2 @begin @end irq irq::@return main
irq::@return dominated by main::@return @2 @begin @end irq irq::@return main
NATURAL LOOPS
Found back edge: Loop head: irq::@return tails: irq blocks: null
Populated: Loop head: irq::@return tails: irq blocks: irq
Loop head: irq::@return tails: irq blocks: irq
NATURAL LOOPS WITH DEPTH
Found 1 loops in scope [irq]
Loop head: irq::@return tails: irq blocks: irq
Found 0 loops in scope []
Found 0 loops in scope [main]
Loop head: irq::@return tails: irq blocks: irq depth: 1
VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte) BLACK
(byte*) CIA1_INTERRUPT
(byte) CIA_INTERRUPT_CLEAR
(byte*) IRQ_ENABLE
(byte) IRQ_RASTER
(byte*) IRQ_STATUS
(void()**) KERNEL_IRQ
(byte*) RASTER
(byte*) VIC_CONTROL
(byte) WHITE
interrupt(KERNEL)(void()) irq()
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label BGCOL = $d020
.const WHITE = 1
.const BLACK = 0
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
jmp b2
//SEG4 @2
b2:
//SEG5 [2] call main [ ] ( )
jsr main
//SEG6 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
//SEG9 asm { sei }
sei
//SEG10 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG11 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
lda VIC_CONTROL
ora #$80
sta VIC_CONTROL
//SEG12 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #0
sta RASTER
//SEG13 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG14 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
//SEG15 asm { cli }
cli
jmp breturn
//SEG16 main::@return
breturn:
//SEG17 [11] return [ ] ( main:2 [ ] )
rts
}
//SEG18 irq
irq: {
//SEG19 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta BGCOL
//SEG20 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #BLACK
sta BGCOL
//SEG21 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
jmp breturn
//SEG22 irq::@return
breturn:
//SEG23 [15] return [ ] ( )
jmp $ea81
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) always clobbers reg byte a
Statement [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) always clobbers reg byte a
Statement [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope [irq]
Uplift Scope []
Uplifting [main] best 278 combination
Uplifting [irq] best 278 combination
Uplifting [] best 278 combination
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label BGCOL = $d020
.const WHITE = 1
.const BLACK = 0
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
jmp b2
//SEG4 @2
b2:
//SEG5 [2] call main [ ] ( )
jsr main
//SEG6 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
//SEG9 asm { sei }
sei
//SEG10 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG11 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
lda VIC_CONTROL
ora #$80
sta VIC_CONTROL
//SEG12 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #0
sta RASTER
//SEG13 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG14 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
//SEG15 asm { cli }
cli
jmp breturn
//SEG16 main::@return
breturn:
//SEG17 [11] return [ ] ( main:2 [ ] )
rts
}
//SEG18 irq
irq: {
//SEG19 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta BGCOL
//SEG20 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #BLACK
sta BGCOL
//SEG21 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
jmp breturn
//SEG22 irq::@return
breturn:
//SEG23 [15] return [ ] ( )
jmp $ea81
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b2
Removing instruction jmp bend
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction bbegin:
Removing instruction b2_from_bbegin:
Removing instruction bend_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b2:
Removing instruction bend:
Removing instruction breturn:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274
(byte) IRQ_RASTER
(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1
(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*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265
(byte) WHITE
(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1
interrupt(KERNEL)(void()) irq()
(label) irq::@return
(void()) main()
(label) main::@return
FINAL ASSEMBLER
Score: 239
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
.label KERNEL_IRQ = $314
.label RASTER = $d012
.label VIC_CONTROL = $d011
.label IRQ_STATUS = $d019
.label IRQ_ENABLE = $d01a
.const IRQ_RASTER = 1
.label BGCOL = $d020
.const WHITE = 1
.const BLACK = 0
.label CIA1_INTERRUPT = $dc0d
.const CIA_INTERRUPT_CLEAR = $7f
//SEG2 @begin
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
//SEG4 @2
//SEG5 [2] call main [ ] ( )
jsr main
//SEG6 [3] phi from @2 to @end [phi:@2->@end]
//SEG7 @end
//SEG8 main
main: {
//SEG9 asm { sei }
sei
//SEG10 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #CIA_INTERRUPT_CLEAR
sta CIA1_INTERRUPT
//SEG11 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2
lda VIC_CONTROL
ora #$80
sta VIC_CONTROL
//SEG12 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #0
sta RASTER
//SEG13 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_ENABLE
//SEG14 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL)(void()) irq() [ ] ( main:2 [ ] ) -- _deref_pptc1=pprc2
lda #<irq
sta KERNEL_IRQ
lda #>irq
sta KERNEL_IRQ+1
//SEG15 asm { cli }
cli
//SEG16 main::@return
//SEG17 [11] return [ ] ( main:2 [ ] )
rts
}
//SEG18 irq
irq: {
//SEG19 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #WHITE
sta BGCOL
//SEG20 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #BLACK
sta BGCOL
//SEG21 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( ) -- _deref_pbuc1=vbuc2
lda #IRQ_RASTER
sta IRQ_STATUS
//SEG22 irq::@return
//SEG23 [15] return [ ] ( )
jmp $ea81
}

View File

@ -0,0 +1,30 @@
(label) @2
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0
(byte*) CIA1_INTERRUPT
(const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333
(byte) CIA_INTERRUPT_CLEAR
(const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127
(byte*) IRQ_ENABLE
(const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274
(byte) IRQ_RASTER
(const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1
(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*) RASTER
(const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266
(byte*) VIC_CONTROL
(const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265
(byte) WHITE
(const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1
interrupt(KERNEL)(void()) irq()
(label) irq::@return
(void()) main()
(label) main::@return