From 6b287741b52cab1fc5437535862473f7140d033c Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 20 Apr 2019 23:52:29 +0200 Subject: [PATCH] Removed unused fragments. --- .../pbuz1=pptc1_derefidx_vbuxx_plus_0.asm | 4 - .../pbuz1=pptc1_derefidx_vbuyy_plus_0.asm | 4 - .../fragment/unused/pbuz1=pbuz2_plus_0.asm | 4 - src/main/fragment/vbuaa=vbuaa_plus_0.asm | 0 .../dk/camelot64/kickc/test/TestPrograms.java | 5 + src/test/kc/pointer-plus-0.kc | 14 + src/test/ref/pointer-plus-0.asm | 34 ++ src/test/ref/pointer-plus-0.cfg | 33 ++ src/test/ref/pointer-plus-0.log | 538 ++++++++++++++++++ src/test/ref/pointer-plus-0.sym | 24 + 10 files changed, 648 insertions(+), 12 deletions(-) delete mode 100644 src/main/fragment/pbuz1=pptc1_derefidx_vbuxx_plus_0.asm delete mode 100644 src/main/fragment/pbuz1=pptc1_derefidx_vbuyy_plus_0.asm delete mode 100644 src/main/fragment/unused/pbuz1=pbuz2_plus_0.asm delete mode 100644 src/main/fragment/vbuaa=vbuaa_plus_0.asm create mode 100644 src/test/kc/pointer-plus-0.kc create mode 100644 src/test/ref/pointer-plus-0.asm create mode 100644 src/test/ref/pointer-plus-0.cfg create mode 100644 src/test/ref/pointer-plus-0.log create mode 100644 src/test/ref/pointer-plus-0.sym diff --git a/src/main/fragment/pbuz1=pptc1_derefidx_vbuxx_plus_0.asm b/src/main/fragment/pbuz1=pptc1_derefidx_vbuxx_plus_0.asm deleted file mode 100644 index 77cdec92f..000000000 --- a/src/main/fragment/pbuz1=pptc1_derefidx_vbuxx_plus_0.asm +++ /dev/null @@ -1,4 +0,0 @@ -lda {c1},x -sta {z1} -lda {c1}+1,x -sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/pbuz1=pptc1_derefidx_vbuyy_plus_0.asm b/src/main/fragment/pbuz1=pptc1_derefidx_vbuyy_plus_0.asm deleted file mode 100644 index 9c735d2d0..000000000 --- a/src/main/fragment/pbuz1=pptc1_derefidx_vbuyy_plus_0.asm +++ /dev/null @@ -1,4 +0,0 @@ -lda {c1},y -sta {z1} -lda {c1}+1,y -sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/unused/pbuz1=pbuz2_plus_0.asm b/src/main/fragment/unused/pbuz1=pbuz2_plus_0.asm deleted file mode 100644 index 5b8ff5c26..000000000 --- a/src/main/fragment/unused/pbuz1=pbuz2_plus_0.asm +++ /dev/null @@ -1,4 +0,0 @@ -lda {z2} -sta {z1} -lda {z2}+1 -sta {z1}+1 diff --git a/src/main/fragment/vbuaa=vbuaa_plus_0.asm b/src/main/fragment/vbuaa=vbuaa_plus_0.asm deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 415bb2879..ccb4bf121 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -37,6 +37,11 @@ public class TestPrograms { // compileAndCompare("pointer-cast-3"); //} + @Test + public void testPointerPlus0() throws IOException, URISyntaxException { + compileAndCompare("pointer-plus-0"); + } + @Test public void testDerefToDerefIdx2() throws IOException, URISyntaxException { compileAndCompare("deref-to-derefidx-2"); diff --git a/src/test/kc/pointer-plus-0.kc b/src/test/kc/pointer-plus-0.kc new file mode 100644 index 000000000..4f61f55f7 --- /dev/null +++ b/src/test/kc/pointer-plus-0.kc @@ -0,0 +1,14 @@ +// Tests pointer plus 0 elimination + +byte[] msg1 = "hello world!"; +byte[] msg2 = "goodbye sky?"; + +void main() { + const byte* SCREEN = $0400; + SCREEN[0] = *(first(msg1)+0); + SCREEN[1] = *(first(msg2)+0); +} + +byte* first(byte* msg) { + return (byte*)(msg+0); +} diff --git a/src/test/ref/pointer-plus-0.asm b/src/test/ref/pointer-plus-0.asm new file mode 100644 index 000000000..3670d3426 --- /dev/null +++ b/src/test/ref/pointer-plus-0.asm @@ -0,0 +1,34 @@ +// Tests pointer plus 0 elimination +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + .label _1 = 2 + .label _3 = 2 + lda #msg1 + sta first.msg+1 + jsr first + ldy #0 + lda (_1),y + sta SCREEN + lda #msg2 + sta first.msg+1 + jsr first + ldy #0 + lda (_3),y + sta SCREEN+1 + rts +} +// first(byte* zeropage(2) msg) +first: { + .label return = 2 + .label msg = 2 + rts +} + msg1: .text "hello world!@" + msg2: .text "goodbye sky?@" diff --git a/src/test/ref/pointer-plus-0.cfg b/src/test/ref/pointer-plus-0.cfg new file mode 100644 index 000000000..59b7662b1 --- /dev/null +++ b/src/test/ref/pointer-plus-0.cfg @@ -0,0 +1,33 @@ +@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] phi() + [5] call first + [6] (byte*) first::return#0 ← (byte*) first::msg#2 + to:main::@1 +main::@1: scope:[main] from main + [7] (byte*~) main::$1 ← (byte*) first::return#0 + [8] *((const byte*) main::SCREEN#0) ← *((byte*~) main::$1) + [9] call first + [10] (byte*) first::return#1 ← (byte*) first::msg#2 + to:main::@2 +main::@2: scope:[main] from main::@1 + [11] (byte*~) main::$3 ← (byte*) first::return#1 + [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) + to:main::@return +main::@return: scope:[main] from main::@2 + [13] return + to:@return +first: scope:[first] from main main::@1 + [14] (byte*) first::msg#2 ← phi( main/(const byte[]) msg1#0 main::@1/(const byte[]) msg2#0 ) + to:first::@return +first::@return: scope:[first] from first + [15] return + to:@return diff --git a/src/test/ref/pointer-plus-0.log b/src/test/ref/pointer-plus-0.log new file mode 100644 index 000000000..a0306cecd --- /dev/null +++ b/src/test/ref/pointer-plus-0.log @@ -0,0 +1,538 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte[]) msg1#0 ← (const string) $0 + (byte[]) msg2#0 ← (const string) $1 + to:@2 +main: scope:[main] from @2 + (byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) $400 + (byte*) first::msg#0 ← (byte[]) msg1#0 + call first + (byte*) first::return#0 ← (byte*) first::return#3 + to:main::@1 +main::@1: scope:[main] from main + (byte*) first::return#4 ← phi( main/(byte*) first::return#0 ) + (byte*~) main::$0 ← (byte*) first::return#4 + (byte*~) main::$1 ← (byte*~) main::$0 + (byte/signed byte/word/signed word/dword/signed dword) 0 + *((byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 0) ← *((byte*~) main::$1) + (byte*) first::msg#1 ← (byte[]) msg2#0 + call first + (byte*) first::return#1 ← (byte*) first::return#3 + to:main::@2 +main::@2: scope:[main] from main::@1 + (byte*) first::return#5 ← phi( main::@1/(byte*) first::return#1 ) + (byte*~) main::$2 ← (byte*) first::return#5 + (byte*~) main::$3 ← (byte*~) main::$2 + (byte/signed byte/word/signed word/dword/signed dword) 0 + *((byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) + to:main::@return +main::@return: scope:[main] from main::@2 + return + to:@return +first: scope:[first] from main main::@1 + (byte*) first::msg#2 ← phi( main/(byte*) first::msg#0 main::@1/(byte*) first::msg#1 ) + (byte*~) first::$0 ← (byte*) first::msg#2 + (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte*~) first::$1 ← ((byte*)) (byte*~) first::$0 + (byte*) first::return#2 ← (byte*~) first::$1 + to:first::@return +first::@return: scope:[first] from first + (byte*) first::return#6 ← phi( first/(byte*) first::return#2 ) + (byte*) first::return#3 ← (byte*) first::return#6 + return + to:@return +@2: scope:[] from @begin + call main + to:@3 +@3: scope:[] from @2 + to:@end +@end: scope:[] from @3 + +SYMBOL TABLE SSA +(const string) $0 = (string) "hello world!@" +(const string) $1 = (string) "goodbye sky?@" +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte*()) first((byte*) first::msg) +(byte*~) first::$0 +(byte*~) first::$1 +(label) first::@return +(byte*) first::msg +(byte*) first::msg#0 +(byte*) first::msg#1 +(byte*) first::msg#2 +(byte*) first::return +(byte*) first::return#0 +(byte*) first::return#1 +(byte*) first::return#2 +(byte*) first::return#3 +(byte*) first::return#4 +(byte*) first::return#5 +(byte*) first::return#6 +(void()) main() +(byte*~) main::$0 +(byte*~) main::$1 +(byte*~) main::$2 +(byte*~) main::$3 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte[]) msg1 +(byte[]) msg1#0 +(byte[]) msg2 +(byte[]) msg2#0 + +Culled Empty Block (label) @3 +Successful SSA optimization Pass2CullEmptyBlocks +Alias (byte*) first::return#0 = (byte*) first::return#4 +Alias (byte*) first::return#1 = (byte*) first::return#5 +Alias (byte*) first::return#2 = (byte*~) first::$1 (byte*) first::return#6 (byte*) first::return#3 +Successful SSA optimization Pass2AliasElimination +Constant (const byte[]) msg1#0 = $0 +Constant (const byte[]) msg2#0 = $1 +Constant (const byte*) main::SCREEN#0 = ((byte*))$400 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte*) first::msg#0 = msg1#0 +Constant (const byte*) first::msg#1 = msg2#0 +Successful SSA optimization Pass2ConstantIdentification +Consolidated array index constant in *(main::SCREEN#0+0) +Consolidated array index constant in *(main::SCREEN#0+1) +Removed zero-constant in assignment main::$1 +Removed zero-constant in assignment main::$3 +Removed zero-constant in assignment first::$0 +Successful SSA optimization Pass2ConstantAdditionElimination +Removing redundant cast (byte*) first::return#2 ← ((byte*)) (byte*~) first::$0 +Successful SSA optimization Pass2EliminateRedundantCasts +Alias (byte*~) main::$1 = (byte*~) main::$0 +Alias (byte*~) main::$3 = (byte*~) main::$2 +Alias (byte*) first::msg#2 = (byte*~) first::$0 (byte*) first::return#2 +Successful SSA optimization Pass2AliasElimination +Inlining constant with var siblings (const byte*) first::msg#0 +Inlining constant with var siblings (const byte*) first::msg#1 +Constant inlined $0 = (const byte[]) msg1#0 +Constant inlined $1 = (const byte[]) msg2#0 +Constant inlined first::msg#0 = (const byte[]) msg1#0 +Constant inlined first::msg#1 = (const byte[]) msg2#0 +Successful SSA optimization Pass2ConstantInlining +Simplifying constant plus zero main::SCREEN#0+0 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +CALL GRAPH +Calls in [] to main:2 +Calls in [main] to first:5 first:9 + +Created 1 initial phi equivalence classes +Coalesced down to 1 phi equivalence classes +Renumbering block @2 to @1 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main + +FINAL CONTROL FLOW GRAPH +@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] phi() + [5] call first + [6] (byte*) first::return#0 ← (byte*) first::msg#2 + to:main::@1 +main::@1: scope:[main] from main + [7] (byte*~) main::$1 ← (byte*) first::return#0 + [8] *((const byte*) main::SCREEN#0) ← *((byte*~) main::$1) + [9] call first + [10] (byte*) first::return#1 ← (byte*) first::msg#2 + to:main::@2 +main::@2: scope:[main] from main::@1 + [11] (byte*~) main::$3 ← (byte*) first::return#1 + [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) + to:main::@return +main::@return: scope:[main] from main::@2 + [13] return + to:@return +first: scope:[first] from main main::@1 + [14] (byte*) first::msg#2 ← phi( main/(const byte[]) msg1#0 main::@1/(const byte[]) msg2#0 ) + to:first::@return +first::@return: scope:[first] from first + [15] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte*()) first((byte*) first::msg) +(byte*) first::msg +(byte*) first::msg#2 1.0 +(byte*) first::return +(byte*) first::return#0 4.0 +(byte*) first::return#1 4.0 +(void()) main() +(byte*~) main::$1 4.0 +(byte*~) main::$3 4.0 +(byte*) main::SCREEN +(byte[]) msg1 +(byte[]) msg2 + +Initial phi equivalence classes +[ first::msg#2 ] +Added variable first::return#0 to zero page equivalence class [ first::return#0 ] +Added variable main::$1 to zero page equivalence class [ main::$1 ] +Added variable first::return#1 to zero page equivalence class [ first::return#1 ] +Added variable main::$3 to zero page equivalence class [ main::$3 ] +Complete equivalence classes +[ first::msg#2 ] +[ first::return#0 ] +[ main::$1 ] +[ first::return#1 ] +[ main::$3 ] +Allocated zp ZP_WORD:2 [ first::msg#2 ] +Allocated zp ZP_WORD:4 [ first::return#0 ] +Allocated zp ZP_WORD:6 [ main::$1 ] +Allocated zp ZP_WORD:8 [ first::return#1 ] +Allocated zp ZP_WORD:10 [ main::$3 ] + +INITIAL ASM +//SEG0 File Comments +// Tests pointer plus 0 elimination +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label SCREEN = $400 + .label _1 = 6 + .label _3 = $a + //SEG11 [5] call first + //SEG12 [14] phi from main to first [phi:main->first] + first_from_main: + //SEG13 [14] phi (byte*) first::msg#2 = (const byte[]) msg1#0 [phi:main->first#0] -- pbuz1=pbuc1 + lda #msg1 + sta first.msg+1 + jsr first + //SEG14 [6] (byte*) first::return#0 ← (byte*) first::msg#2 -- pbuz1=pbuz2 + lda first.msg + sta first.return + lda first.msg+1 + sta first.return+1 + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [7] (byte*~) main::$1 ← (byte*) first::return#0 -- pbuz1=pbuz2 + lda first.return + sta _1 + lda first.return+1 + sta _1+1 + //SEG17 [8] *((const byte*) main::SCREEN#0) ← *((byte*~) main::$1) -- _deref_pbuc1=_deref_pbuz1 + ldy #0 + lda (_1),y + sta SCREEN + //SEG18 [9] call first + //SEG19 [14] phi from main::@1 to first [phi:main::@1->first] + first_from_b1: + //SEG20 [14] phi (byte*) first::msg#2 = (const byte[]) msg2#0 [phi:main::@1->first#0] -- pbuz1=pbuc1 + lda #msg2 + sta first.msg+1 + jsr first + //SEG21 [10] (byte*) first::return#1 ← (byte*) first::msg#2 -- pbuz1=pbuz2 + lda first.msg + sta first.return_1 + lda first.msg+1 + sta first.return_1+1 + jmp b2 + //SEG22 main::@2 + b2: + //SEG23 [11] (byte*~) main::$3 ← (byte*) first::return#1 -- pbuz1=pbuz2 + lda first.return_1 + sta _3 + lda first.return_1+1 + sta _3+1 + //SEG24 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) -- _deref_pbuc1=_deref_pbuz1 + ldy #0 + lda (_3),y + sta SCREEN+1 + jmp breturn + //SEG25 main::@return + breturn: + //SEG26 [13] return + rts +} +//SEG27 first +// first(byte* zeropage(2) msg) +first: { + .label return = 4 + .label return_1 = 8 + .label msg = 2 + jmp breturn + //SEG28 first::@return + breturn: + //SEG29 [15] return + rts +} + msg1: .text "hello world!@" + msg2: .text "goodbye sky?@" + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [6] (byte*) first::return#0 ← (byte*) first::msg#2 [ first::return#0 ] ( main:2 [ first::return#0 ] ) always clobbers reg byte a +Statement [7] (byte*~) main::$1 ← (byte*) first::return#0 [ main::$1 ] ( main:2 [ main::$1 ] ) always clobbers reg byte a +Statement [8] *((const byte*) main::SCREEN#0) ← *((byte*~) main::$1) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [10] (byte*) first::return#1 ← (byte*) first::msg#2 [ first::return#1 ] ( main:2 [ first::return#1 ] ) always clobbers reg byte a +Statement [11] (byte*~) main::$3 ← (byte*) first::return#1 [ main::$3 ] ( main:2 [ main::$3 ] ) always clobbers reg byte a +Statement [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Potential registers zp ZP_WORD:2 [ first::msg#2 ] : zp ZP_WORD:2 , +Potential registers zp ZP_WORD:4 [ first::return#0 ] : zp ZP_WORD:4 , +Potential registers zp ZP_WORD:6 [ main::$1 ] : zp ZP_WORD:6 , +Potential registers zp ZP_WORD:8 [ first::return#1 ] : zp ZP_WORD:8 , +Potential registers zp ZP_WORD:10 [ main::$3 ] : zp ZP_WORD:10 , + +REGISTER UPLIFT SCOPES +Uplift Scope [first] 4: zp ZP_WORD:4 [ first::return#0 ] 4: zp ZP_WORD:8 [ first::return#1 ] 1: zp ZP_WORD:2 [ first::msg#2 ] +Uplift Scope [main] 4: zp ZP_WORD:6 [ main::$1 ] 4: zp ZP_WORD:10 [ main::$3 ] +Uplift Scope [] + +Uplifting [first] best 165 combination zp ZP_WORD:4 [ first::return#0 ] zp ZP_WORD:8 [ first::return#1 ] zp ZP_WORD:2 [ first::msg#2 ] +Uplifting [main] best 165 combination zp ZP_WORD:6 [ main::$1 ] zp ZP_WORD:10 [ main::$3 ] +Uplifting [] best 165 combination +Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ first::msg#2 ] ] with [ zp ZP_WORD:4 [ first::return#0 ] ] - score: 1 +Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ first::msg#2 first::return#0 ] ] with [ zp ZP_WORD:8 [ first::return#1 ] ] - score: 1 +Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ first::msg#2 first::return#0 first::return#1 ] ] with [ zp ZP_WORD:6 [ main::$1 ] ] - score: 1 +Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ first::msg#2 first::return#0 first::return#1 main::$1 ] ] with [ zp ZP_WORD:10 [ main::$3 ] ] - score: 1 + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests pointer plus 0 elimination +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label SCREEN = $400 + .label _1 = 2 + .label _3 = 2 + //SEG11 [5] call first + //SEG12 [14] phi from main to first [phi:main->first] + first_from_main: + //SEG13 [14] phi (byte*) first::msg#2 = (const byte[]) msg1#0 [phi:main->first#0] -- pbuz1=pbuc1 + lda #msg1 + sta first.msg+1 + jsr first + //SEG14 [6] (byte*) first::return#0 ← (byte*) first::msg#2 + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [7] (byte*~) main::$1 ← (byte*) first::return#0 + //SEG17 [8] *((const byte*) main::SCREEN#0) ← *((byte*~) main::$1) -- _deref_pbuc1=_deref_pbuz1 + ldy #0 + lda (_1),y + sta SCREEN + //SEG18 [9] call first + //SEG19 [14] phi from main::@1 to first [phi:main::@1->first] + first_from_b1: + //SEG20 [14] phi (byte*) first::msg#2 = (const byte[]) msg2#0 [phi:main::@1->first#0] -- pbuz1=pbuc1 + lda #msg2 + sta first.msg+1 + jsr first + //SEG21 [10] (byte*) first::return#1 ← (byte*) first::msg#2 + jmp b2 + //SEG22 main::@2 + b2: + //SEG23 [11] (byte*~) main::$3 ← (byte*) first::return#1 + //SEG24 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) -- _deref_pbuc1=_deref_pbuz1 + ldy #0 + lda (_3),y + sta SCREEN+1 + jmp breturn + //SEG25 main::@return + breturn: + //SEG26 [13] return + rts +} +//SEG27 first +// first(byte* zeropage(2) msg) +first: { + .label return = 2 + .label msg = 2 + jmp breturn + //SEG28 first::@return + breturn: + //SEG29 [15] return + rts +} + msg1: .text "hello world!@" + msg2: .text "goodbye sky?@" + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp breturn +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction first_from_main: +Removing instruction b1: +Removing instruction first_from_b1: +Removing instruction b2: +Removing instruction breturn: +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 +(byte*()) first((byte*) first::msg) +(label) first::@return +(byte*) first::msg +(byte*) first::msg#2 msg zp ZP_WORD:2 1.0 +(byte*) first::return +(byte*) first::return#0 return zp ZP_WORD:2 4.0 +(byte*) first::return#1 return zp ZP_WORD:2 4.0 +(void()) main() +(byte*~) main::$1 $1 zp ZP_WORD:2 4.0 +(byte*~) main::$3 $3 zp ZP_WORD:2 4.0 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400 +(byte[]) msg1 +(const byte[]) msg1#0 msg1 = (string) "hello world!@" +(byte[]) msg2 +(const byte[]) msg2#0 msg2 = (string) "goodbye sky?@" + +zp ZP_WORD:2 [ first::msg#2 first::return#0 first::return#1 main::$1 main::$3 ] + + +FINAL ASSEMBLER +Score: 66 + +//SEG0 File Comments +// Tests pointer plus 0 elimination +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .label SCREEN = $400 + .label _1 = 2 + .label _3 = 2 + //SEG11 [5] call first + //SEG12 [14] phi from main to first [phi:main->first] + //SEG13 [14] phi (byte*) first::msg#2 = (const byte[]) msg1#0 [phi:main->first#0] -- pbuz1=pbuc1 + lda #msg1 + sta first.msg+1 + jsr first + //SEG14 [6] (byte*) first::return#0 ← (byte*) first::msg#2 + //SEG15 main::@1 + //SEG16 [7] (byte*~) main::$1 ← (byte*) first::return#0 + //SEG17 [8] *((const byte*) main::SCREEN#0) ← *((byte*~) main::$1) -- _deref_pbuc1=_deref_pbuz1 + ldy #0 + lda (_1),y + sta SCREEN + //SEG18 [9] call first + //SEG19 [14] phi from main::@1 to first [phi:main::@1->first] + //SEG20 [14] phi (byte*) first::msg#2 = (const byte[]) msg2#0 [phi:main::@1->first#0] -- pbuz1=pbuc1 + lda #msg2 + sta first.msg+1 + jsr first + //SEG21 [10] (byte*) first::return#1 ← (byte*) first::msg#2 + //SEG22 main::@2 + //SEG23 [11] (byte*~) main::$3 ← (byte*) first::return#1 + //SEG24 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1) ← *((byte*~) main::$3) -- _deref_pbuc1=_deref_pbuz1 + ldy #0 + lda (_3),y + sta SCREEN+1 + //SEG25 main::@return + //SEG26 [13] return + rts +} +//SEG27 first +// first(byte* zeropage(2) msg) +first: { + .label return = 2 + .label msg = 2 + //SEG28 first::@return + //SEG29 [15] return + rts +} + msg1: .text "hello world!@" + msg2: .text "goodbye sky?@" + diff --git a/src/test/ref/pointer-plus-0.sym b/src/test/ref/pointer-plus-0.sym new file mode 100644 index 000000000..31c94f8c6 --- /dev/null +++ b/src/test/ref/pointer-plus-0.sym @@ -0,0 +1,24 @@ +(label) @1 +(label) @begin +(label) @end +(byte*()) first((byte*) first::msg) +(label) first::@return +(byte*) first::msg +(byte*) first::msg#2 msg zp ZP_WORD:2 1.0 +(byte*) first::return +(byte*) first::return#0 return zp ZP_WORD:2 4.0 +(byte*) first::return#1 return zp ZP_WORD:2 4.0 +(void()) main() +(byte*~) main::$1 $1 zp ZP_WORD:2 4.0 +(byte*~) main::$3 $3 zp ZP_WORD:2 4.0 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400 +(byte[]) msg1 +(const byte[]) msg1#0 msg1 = (string) "hello world!@" +(byte[]) msg2 +(const byte[]) msg2#0 msg2 = (string) "goodbye sky?@" + +zp ZP_WORD:2 [ first::msg#2 first::return#0 first::return#1 main::$1 main::$3 ]