diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 2480f8ea6..a6e064b5f 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -37,6 +37,19 @@ public class TestPrograms { } + // TODO: Fix cast of constant pointer https://gitlab.com/camelot/kickc/issues/288 + /* + @Test + public void testLongPointer1() throws IOException, URISyntaxException { + compileAndCompare("long-pointer-1"); + } + */ + + @Test + public void testLongPointer0() throws IOException, URISyntaxException { + compileAndCompare("long-pointer-0"); + } + @Test public void testForcedZeropage() throws IOException, URISyntaxException { compileAndCompare("forced-zeropage"); diff --git a/src/test/kc/long-pointer-0.kc b/src/test/kc/long-pointer-0.kc new file mode 100644 index 000000000..f44f382ed --- /dev/null +++ b/src/test/kc/long-pointer-0.kc @@ -0,0 +1,10 @@ +// Tests creating a long (32bit) pointer on zeropage for 45GS02 flat memory access +void main() { + unsigned long long_ptr = 0x12345678; + char long_ptr_zp = <&long_ptr; + asm { + nop + lda (long_ptr_zp),y + sta $ff + } +} \ No newline at end of file diff --git a/src/test/kc/long-pointer-1.kc b/src/test/kc/long-pointer-1.kc new file mode 100644 index 000000000..97d3c0ece --- /dev/null +++ b/src/test/kc/long-pointer-1.kc @@ -0,0 +1,10 @@ +// Tests creating a long (32bit) pointer on zeropage for 45GS02 flat memory access +void main() { + unsigned long long_ptr = 0x12345678; + char long_ptr_zp = (char)&long_ptr; + asm { + nop + lda (long_ptr_zp),y + sta $ff + } +} \ No newline at end of file diff --git a/src/test/ref/long-pointer-0.asm b/src/test/ref/long-pointer-0.asm new file mode 100644 index 000000000..ff0e7a273 --- /dev/null +++ b/src/test/ref/long-pointer-0.asm @@ -0,0 +1,20 @@ +// Tests creating a long (32bit) pointer on zeropage for 45GS02 flat memory access +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .const long_ptr_zp = $12345678 + sta.z long_ptr+1 + lda #<$12345678>>$10 + sta.z long_ptr+2 + lda #>$12345678>>$10 + sta.z long_ptr+3 + nop + lda (long_ptr_zp),y + sta.z $ff + rts +} diff --git a/src/test/ref/long-pointer-0.cfg b/src/test/ref/long-pointer-0.cfg new file mode 100644 index 000000000..713ba2f99 --- /dev/null +++ b/src/test/ref/long-pointer-0.cfg @@ -0,0 +1,16 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] (dword) main::long_ptr#0 ← (dword) $12345678 + asm { nop lda(long_ptr_zp),y sta$ff } + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/long-pointer-0.log b/src/test/ref/long-pointer-0.log new file mode 100644 index 000000000..ba97331a6 --- /dev/null +++ b/src/test/ref/long-pointer-0.log @@ -0,0 +1,281 @@ +Setting inferred volatile on symbol affected by address-of (dword*~) main::$0 ← & (dword) main::long_ptr + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (dword) main::long_ptr#0 ← (number) $12345678 + (dword*~) main::$0 ← & (dword) main::long_ptr#0 + (byte~) main::$1 ← < (dword*~) main::$0 + (byte) main::long_ptr_zp#0 ← (byte~) main::$1 + asm { nop lda(long_ptr_zp),y sta$ff } + to:main::@return +main::@return: scope:[main] from main + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(void()) main() +(dword*~) main::$0 +(byte~) main::$1 +(label) main::@return +(dword) main::long_ptr +(dword) main::long_ptr#0 +(byte) main::long_ptr_zp +(byte) main::long_ptr_zp#0 + +Adding number conversion cast (unumber) $12345678 in (dword) main::long_ptr#0 ← (number) $12345678 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (dword) main::long_ptr#0 ← (unumber)(number) $12345678 +Successful SSA optimization Pass2InlineCast +Simplifying constant integer cast $12345678 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (dword) $12345678 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Alias (byte) main::long_ptr_zp#0 = (byte~) main::$1 +Successful SSA optimization Pass2AliasElimination +Constant right-side identified [1] (dword*~) main::$0 ← & (dword) main::long_ptr#0 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const dword*) main::$0 = &main::long_ptr#0 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [1] (byte) main::long_ptr_zp#0 ← < (const dword*) main::$0 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) main::long_ptr_zp#0 = @1] +b1_from_bbegin: + jmp b1 + // @1 +b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend + // @end +bend: + // main +main: { + .const long_ptr_zp = $12345678 + sta.z long_ptr+1 + lda #<$12345678>>$10 + sta.z long_ptr+2 + lda #>$12345678>>$10 + sta.z long_ptr+3 + // asm { nop lda(long_ptr_zp),y sta$ff } + nop + lda (long_ptr_zp),y + sta.z $ff + jmp breturn + // main::@return + breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] (dword) main::long_ptr#0 ← (dword) $12345678 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement asm { nop lda(long_ptr_zp),y sta$ff } always clobbers reg byte a +Potential registers zp ZP_DWORD:2 [ main::long_ptr#0 ] : zp ZP_DWORD:2 , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 20: zp ZP_DWORD:2 [ main::long_ptr#0 ] +Uplift Scope [] + +Uplifting [main] best 51 combination zp ZP_DWORD:2 [ main::long_ptr#0 ] +Uplifting [] best 51 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Tests creating a long (32bit) pointer on zeropage for 45GS02 flat memory access + // Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" + // Global Constants & labels + // @begin +bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 + // @1 +b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend + // @end +bend: + // main +main: { + .const long_ptr_zp = $12345678 + sta.z long_ptr+1 + lda #<$12345678>>$10 + sta.z long_ptr+2 + lda #>$12345678>>$10 + sta.z long_ptr+3 + // asm { nop lda(long_ptr_zp),y sta$ff } + nop + lda (long_ptr_zp),y + sta.z $ff + jmp breturn + // main::@return + breturn: + // [6] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction bend_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@return +(dword) main::long_ptr +(dword) main::long_ptr#0 long_ptr zp ZP_DWORD:2 20.0 +(byte) main::long_ptr_zp +(const byte) main::long_ptr_zp#0 long_ptr_zp = <&(dword) main::long_ptr#0 + +zp ZP_DWORD:2 [ main::long_ptr#0 ] + + +FINAL ASSEMBLER +Score: 36 + + // File Comments +// Tests creating a long (32bit) pointer on zeropage for 45GS02 flat memory access + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + // @begin + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + .const long_ptr_zp = $12345678 + sta.z long_ptr+1 + lda #<$12345678>>$10 + sta.z long_ptr+2 + lda #>$12345678>>$10 + sta.z long_ptr+3 + // asm + // asm { nop lda(long_ptr_zp),y sta$ff } + nop + lda (long_ptr_zp),y + sta.z $ff + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/long-pointer-0.sym b/src/test/ref/long-pointer-0.sym new file mode 100644 index 000000000..d6d42adaa --- /dev/null +++ b/src/test/ref/long-pointer-0.sym @@ -0,0 +1,11 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@return +(dword) main::long_ptr +(dword) main::long_ptr#0 long_ptr zp ZP_DWORD:2 20.0 +(byte) main::long_ptr_zp +(const byte) main::long_ptr_zp#0 long_ptr_zp = <&(dword) main::long_ptr#0 + +zp ZP_DWORD:2 [ main::long_ptr#0 ]