diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 434fd7297..64501b0d4 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -347,7 +347,6 @@ public class Compiler { getLog().append("\nFINAL CONTROL FLOW GRAPH"); getLog().append(program.getGraph().toString(program)); - } private void pass4RegisterAllocation() { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2LoopUnroll.java b/src/main/java/dk/camelot64/kickc/passes/Pass2LoopUnroll.java index 80de7d4d5..a80104581 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2LoopUnroll.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2LoopUnroll.java @@ -54,6 +54,8 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization { newBlock.addStatement(newStatement); if(newStatement instanceof StatementConditionalJump) { newBlock.setConditionalSuccessor(((StatementConditionalJump) newStatement).getDestination()); + } else if(newStatement instanceof StatementCall) { + newBlock.setCallSuccessor(block.getCallSuccessor()); } } newBlock.setDefaultSuccessor(unrollLabel(block.getDefaultSuccessor(), blockToNewBlock)); @@ -106,7 +108,7 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization { for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) { for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { if(unrollLoop.getBlocks().contains(phiRValue.getPredecessor())) { - // Found a phi variable with values from the poriginal loop in a loop successor block + // Found a phi variable with values from the original loop in a loop successor block // Add another value when entering from the unrolled loop phiVariable.setrValue(unrollLabel(phiRValue.getPredecessor(), blockToNewBlock), unrollValue(phiRValue.getrValue(), definedToNewVar)); break; @@ -190,8 +192,13 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization { unrollLabel(labelRef, blockToNewBlock), conditional.getSource() ); - newConditional.setDeclaredUnroll(conditional.isDeclaredUnroll()); + newConditional.setDeclaredUnroll(conditional.isDeclaredUnroll()); return newConditional; + } else if(statement instanceof StatementCall) { + StatementCall call = (StatementCall) statement; + StatementCall newCall = new StatementCall(null, call.getProcedureName(), null, call.getSource()); + newCall.setProcedure(call.getProcedure()); + return newCall; } else { throw new RuntimeException("Statement not handled by unroll " + statement); } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index d6da2a410..c313543e1 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -46,6 +46,11 @@ public class TestPrograms { AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false); } + //@Test + //public void testUnrollCall() throws IOException, URISyntaxException { + // compileAndCompare("unroll-call"); + //} + @Test public void testUnrollInfinite() throws IOException, URISyntaxException { assertError("unroll-infinite", "Loop cannot be unrolled."); diff --git a/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc b/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc index 50a3f5371..b7cd9de66 100644 --- a/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc +++ b/src/test/java/dk/camelot64/kickc/test/kc/irq-hyperscreen.kc @@ -1,22 +1,5 @@ // 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; +import "c64.kc" const byte* GHOST_BYTE = $3fff; @@ -37,7 +20,7 @@ void main() { // Interrupt Routine 1 interrupt(kernel_min) void irq_bottom_1() { - *FGCOL = WHITE; + *BORDERCOL = WHITE; // Set screen height to 24 lines - this is done after the border should have started drawing - so it wont start *VIC_CONTROL &= ($ff^VIC_RSEL); // Acknowledge the IRQ @@ -45,12 +28,12 @@ interrupt(kernel_min) void irq_bottom_1() { // Trigger IRQ 2 at line $fd *RASTER = $fd; *KERNEL_IRQ = &irq_bottom_2; - *FGCOL = RED; + *BORDERCOL = RED; } // Interrupt Routine 2 interrupt(kernel_keyboard) void irq_bottom_2() { - *FGCOL = WHITE; + *BORDERCOL = WHITE; // Set screen height back to 25 lines (preparing for the next screen) *VIC_CONTROL |= VIC_RSEL; // Acknowledge the IRQ @@ -58,5 +41,5 @@ interrupt(kernel_keyboard) void irq_bottom_2() { // Trigger IRQ 1 at line $fa *RASTER = $fa; *KERNEL_IRQ = &irq_bottom_1; - *FGCOL = RED; + *BORDERCOL = RED; } \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/kc/unroll-call.kc b/src/test/java/dk/camelot64/kickc/test/kc/unroll-call.kc new file mode 100644 index 000000000..6da24b305 --- /dev/null +++ b/src/test/java/dk/camelot64/kickc/test/kc/unroll-call.kc @@ -0,0 +1,15 @@ +// Unrolling a loop containing an inner call + +void main() { + byte* SCREEN = $400; + byte a=$10; + inline for(byte i: 0..2) { + a = plus(a, i); + SCREEN[i] = a; + } + +} + +byte plus(byte a, byte b) { + return a+b; +} \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm index 19760107d..604bd080d 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.asm @@ -1,18 +1,18 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .label KERNEL_IRQ = $314 .label RASTER = $d012 + .label BORDERCOL = $d020 .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 KERNEL_IRQ = $314 + .const WHITE = 1 + .const RED = 2 .label GHOST_BYTE = $3fff jsr main main: { @@ -37,7 +37,7 @@ main: { } irq_bottom_2: { lda #WHITE - sta FGCOL + sta BORDERCOL lda VIC_CONTROL ora #VIC_RSEL sta VIC_CONTROL @@ -50,12 +50,12 @@ irq_bottom_2: { lda #>irq_bottom_1 sta KERNEL_IRQ+1 lda #RED - sta FGCOL + sta BORDERCOL jmp $ea31 } irq_bottom_1: { lda #WHITE - sta FGCOL + sta BORDERCOL lda VIC_CONTROL and #$ff^VIC_RSEL sta VIC_CONTROL @@ -68,6 +68,6 @@ irq_bottom_1: { lda #>irq_bottom_2 sta KERNEL_IRQ+1 lda #RED - sta FGCOL + sta BORDERCOL jmp $ea81 } diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg index c30580638..5d0560d8b 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.cfg @@ -1,13 +1,13 @@ @begin: scope:[] from [0] phi() [ ] ( ) - to:@3 -@3: scope:[] from @begin + to:@6 +@6: scope:[] from @begin [1] phi() [ ] ( ) [2] call main [ ] ( ) to:@end -@end: scope:[] from @3 +@end: scope:[] from @6 [3] phi() [ ] ( ) -main: scope:[main] from @3 +main: scope:[main] from @6 [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 [ ] ) @@ -21,23 +21,23 @@ 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 [ ] ( ) + [13] *((const byte*) BORDERCOL#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_MIN)(void()) irq_bottom_1() [ ] ( ) - [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + [18] *((const byte*) BORDERCOL#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 [ ] ( ) + [20] *((const byte*) BORDERCOL#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_KEYBOARD)(void()) irq_bottom_2() [ ] ( ) - [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + [25] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) to:irq_bottom_1::@return irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 [26] return [ ] ( ) diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log index c28ddf2c6..870a346c2 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.log @@ -1,23 +1,26 @@ Resolved forward reference irq_bottom_1 to interrupt(KERNEL_MIN)(void()) irq_bottom_1() Resolved forward reference irq_bottom_2 to interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2() +Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx CONTROL FLOW GRAPH SSA @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*) BORDERCOL#0 ← ((byte*)) (word/dword/signed dword) 53280 (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 + (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 + (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 to:@3 -main: scope:[main] from @3 +@3: scope:[] from @begin + (byte*) GHOST_BYTE#0 ← ((byte*)) (word/signed word/dword/signed dword) 16383 + to:@6 +main: scope:[main] from @6 *((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 @@ -32,48 +35,49 @@ main::@return: scope:[main] from main return to:@return irq_bottom_1: scope:[irq_bottom_1] from - *((byte*) FGCOL#0) ← (byte) WHITE#0 + *((byte*) BORDERCOL#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_KEYBOARD)(void()) irq_bottom_2() *((void()**) KERNEL_IRQ#0) ← (void()*~) irq_bottom_1::$1 - *((byte*) FGCOL#0) ← (byte) RED#0 + *((byte*) BORDERCOL#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*) BORDERCOL#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_MIN)(void()) irq_bottom_1() *((void()**) KERNEL_IRQ#0) ← (void()*~) irq_bottom_2::$0 - *((byte*) FGCOL#0) ← (byte) RED#0 + *((byte*) BORDERCOL#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 +@6: scope:[] from @3 call main - to:@4 -@4: scope:[] from @3 + to:@7 +@7: scope:[] from @6 to:@end -@end: scope:[] from @4 +@end: scope:[] from @7 SYMBOL TABLE SSA (label) @3 -(label) @4 +(label) @6 +(label) @7 (label) @begin (label) @end +(byte*) BORDERCOL +(byte*) BORDERCOL#0 (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 @@ -105,20 +109,20 @@ interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2() (void()*~) main::$0 (label) main::@return -Culled Empty Block (label) @4 +Culled Empty Block (label) @7 Successful SSA optimization Pass2CullEmptyBlocks -Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 Constant (const byte*) RASTER#0 = ((byte*))53266 +Constant (const byte*) BORDERCOL#0 = ((byte*))53280 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 void()**) KERNEL_IRQ#0 = ((void()**))788 +Constant (const byte) WHITE#0 = 1 +Constant (const byte) RED#0 = 2 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 @@ -126,13 +130,15 @@ Constant (const void()*) irq_bottom_2::$0 = &irq_bottom_1 Successful SSA optimization Pass2ConstantIdentification Constant (const byte/word/dword) irq_bottom_1::$0 = 255^VIC_RSEL#0 Successful SSA optimization Pass2ConstantIdentification +Culled Empty Block (label) @3 +Successful SSA optimization Pass2CullEmptyBlocks Constant inlined irq_bottom_2::$0 = &interrupt(KERNEL_MIN)(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_MIN)(void()) irq_bottom_1() Constant inlined irq_bottom_1::$1 = &interrupt(KERNEL_KEYBOARD)(void()) irq_bottom_2() Successful SSA optimization Pass2ConstantInlining Adding NOP phi() at start of @begin -Adding NOP phi() at start of @3 +Adding NOP phi() at start of @6 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 @@ -140,20 +146,20 @@ Calls in [] to main:2 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Adding NOP phi() at start of @begin -Adding NOP phi() at start of @3 +Adding NOP phi() at start of @6 Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @begin: scope:[] from [0] phi() [ ] ( ) - to:@3 -@3: scope:[] from @begin + to:@6 +@6: scope:[] from @begin [1] phi() [ ] ( ) [2] call main [ ] ( ) to:@end -@end: scope:[] from @3 +@end: scope:[] from @6 [3] phi() [ ] ( ) -main: scope:[main] from @3 +main: scope:[main] from @6 [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 [ ] ) @@ -167,23 +173,23 @@ 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 [ ] ( ) + [13] *((const byte*) BORDERCOL#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_MIN)(void()) irq_bottom_1() [ ] ( ) - [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + [18] *((const byte*) BORDERCOL#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 [ ] ( ) + [20] *((const byte*) BORDERCOL#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_KEYBOARD)(void()) irq_bottom_2() [ ] ( ) - [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) + [25] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) to:irq_bottom_1::@return irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 [26] return [ ] ( ) @@ -191,9 +197,9 @@ irq_bottom_1::@return: scope:[irq_bottom_1] from irq_bottom_1 VARIABLE REGISTER WEIGHTS +(byte*) BORDERCOL (byte*) CIA1_INTERRUPT (byte) CIA_INTERRUPT_CLEAR -(byte*) FGCOL (byte*) GHOST_BYTE (byte*) IRQ_ENABLE (byte) IRQ_RASTER @@ -217,30 +223,30 @@ INITIAL ASM :BasicUpstart(main) .pc = $80d "Program" //SEG1 Global Constants & labels - .label KERNEL_IRQ = $314 .label RASTER = $d012 + .label BORDERCOL = $d020 .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 KERNEL_IRQ = $314 + .const WHITE = 1 + .const RED = 2 .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: +//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] +b6_from_bbegin: + jmp b6 +//SEG4 @6 +b6: //SEG5 [2] call main [ ] ( ) jsr main -//SEG6 [3] phi from @3 to @end [phi:@3->@end] -bend_from_b3: +//SEG6 [3] phi from @6 to @end [phi:@6->@end] +bend_from_b6: jmp bend //SEG7 @end bend: @@ -280,9 +286,9 @@ main: { //SEG19 irq_bottom_2 irq_bottom_2: { //SEG20 entry interrupt(KERNEL_KEYBOARD) - //SEG21 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG21 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #WHITE - sta FGCOL + sta BORDERCOL //SEG22 [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 @@ -298,9 +304,9 @@ irq_bottom_2: { sta KERNEL_IRQ lda #>irq_bottom_1 sta KERNEL_IRQ+1 - //SEG26 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG26 [18] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #RED - sta FGCOL + sta BORDERCOL jmp breturn //SEG27 irq_bottom_2::@return breturn: @@ -310,9 +316,9 @@ irq_bottom_2: { //SEG29 irq_bottom_1 irq_bottom_1: { //SEG30 entry interrupt(KERNEL_MIN) - //SEG31 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG31 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #WHITE - sta FGCOL + sta BORDERCOL //SEG32 [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 @@ -328,9 +334,9 @@ irq_bottom_1: { sta KERNEL_IRQ lda #>irq_bottom_2 sta KERNEL_IRQ+1 - //SEG36 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG36 [25] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #RED - sta FGCOL + sta BORDERCOL jmp breturn //SEG37 irq_bottom_1::@return breturn: @@ -345,18 +351,18 @@ Statement [7] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) 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_MIN)(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 [13] *((const byte*) BORDERCOL#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_MIN)(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 [18] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a +Statement [20] *((const byte*) BORDERCOL#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_KEYBOARD)(void()) irq_bottom_2() [ ] ( ) always clobbers reg byte a -Statement [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a +Statement [25] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [main] @@ -375,30 +381,30 @@ ASSEMBLER BEFORE OPTIMIZATION :BasicUpstart(main) .pc = $80d "Program" //SEG1 Global Constants & labels - .label KERNEL_IRQ = $314 .label RASTER = $d012 + .label BORDERCOL = $d020 .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 KERNEL_IRQ = $314 + .const WHITE = 1 + .const RED = 2 .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: +//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] +b6_from_bbegin: + jmp b6 +//SEG4 @6 +b6: //SEG5 [2] call main [ ] ( ) jsr main -//SEG6 [3] phi from @3 to @end [phi:@3->@end] -bend_from_b3: +//SEG6 [3] phi from @6 to @end [phi:@6->@end] +bend_from_b6: jmp bend //SEG7 @end bend: @@ -438,9 +444,9 @@ main: { //SEG19 irq_bottom_2 irq_bottom_2: { //SEG20 entry interrupt(KERNEL_KEYBOARD) - //SEG21 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG21 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #WHITE - sta FGCOL + sta BORDERCOL //SEG22 [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 @@ -456,9 +462,9 @@ irq_bottom_2: { sta KERNEL_IRQ lda #>irq_bottom_1 sta KERNEL_IRQ+1 - //SEG26 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG26 [18] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #RED - sta FGCOL + sta BORDERCOL jmp breturn //SEG27 irq_bottom_2::@return breturn: @@ -468,9 +474,9 @@ irq_bottom_2: { //SEG29 irq_bottom_1 irq_bottom_1: { //SEG30 entry interrupt(KERNEL_MIN) - //SEG31 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG31 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #WHITE - sta FGCOL + sta BORDERCOL //SEG32 [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 @@ -486,9 +492,9 @@ irq_bottom_1: { sta KERNEL_IRQ lda #>irq_bottom_2 sta KERNEL_IRQ+1 - //SEG36 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG36 [25] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #RED - sta FGCOL + sta BORDERCOL jmp breturn //SEG37 irq_bottom_1::@return breturn: @@ -497,17 +503,17 @@ irq_bottom_1: { } ASSEMBLER OPTIMIZATIONS -Removing instruction jmp b3 +Removing instruction jmp b6 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: +Removing instruction b6_from_bbegin: +Removing instruction bend_from_b6: Succesful ASM optimization Pass5RedundantLabelElimination -Removing instruction b3: +Removing instruction b6: Removing instruction bend: Removing instruction breturn: Removing instruction breturn: @@ -515,15 +521,15 @@ Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE -(label) @3 +(label) @6 (label) @begin (label) @end +(byte*) BORDERCOL +(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53280 (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 @@ -561,25 +567,25 @@ Score: 160 :BasicUpstart(main) .pc = $80d "Program" //SEG1 Global Constants & labels - .label KERNEL_IRQ = $314 .label RASTER = $d012 + .label BORDERCOL = $d020 .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 KERNEL_IRQ = $314 + .const WHITE = 1 + .const RED = 2 .label GHOST_BYTE = $3fff //SEG2 @begin -//SEG3 [1] phi from @begin to @3 [phi:@begin->@3] -//SEG4 @3 +//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] +//SEG4 @6 //SEG5 [2] call main [ ] ( ) jsr main -//SEG6 [3] phi from @3 to @end [phi:@3->@end] +//SEG6 [3] phi from @6 to @end [phi:@6->@end] //SEG7 @end //SEG8 main main: { @@ -615,9 +621,9 @@ main: { //SEG19 irq_bottom_2 irq_bottom_2: { //SEG20 entry interrupt(KERNEL_KEYBOARD) - //SEG21 [13] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG21 [13] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #WHITE - sta FGCOL + sta BORDERCOL //SEG22 [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 @@ -633,9 +639,9 @@ irq_bottom_2: { sta KERNEL_IRQ lda #>irq_bottom_1 sta KERNEL_IRQ+1 - //SEG26 [18] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG26 [18] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #RED - sta FGCOL + sta BORDERCOL //SEG27 irq_bottom_2::@return //SEG28 [19] return [ ] ( ) - exit interrupt(KERNEL_KEYBOARD) jmp $ea31 @@ -643,9 +649,9 @@ irq_bottom_2: { //SEG29 irq_bottom_1 irq_bottom_1: { //SEG30 entry interrupt(KERNEL_MIN) - //SEG31 [20] *((const byte*) FGCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG31 [20] *((const byte*) BORDERCOL#0) ← (const byte) WHITE#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #WHITE - sta FGCOL + sta BORDERCOL //SEG32 [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 @@ -661,9 +667,9 @@ irq_bottom_1: { sta KERNEL_IRQ lda #>irq_bottom_2 sta KERNEL_IRQ+1 - //SEG36 [25] *((const byte*) FGCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 + //SEG36 [25] *((const byte*) BORDERCOL#0) ← (const byte) RED#0 [ ] ( ) -- _deref_pbuc1=vbuc2 lda #RED - sta FGCOL + sta BORDERCOL //SEG37 irq_bottom_1::@return //SEG38 [26] return [ ] ( ) - exit interrupt(KERNEL_MIN) jmp $ea81 diff --git a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym index 51f883e08..3f3261555 100644 --- a/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym +++ b/src/test/java/dk/camelot64/kickc/test/ref/irq-hyperscreen.sym @@ -1,12 +1,12 @@ -(label) @3 +(label) @6 (label) @begin (label) @end +(byte*) BORDERCOL +(const byte*) BORDERCOL#0 BORDERCOL = ((byte*))(word/dword/signed dword) 53280 (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