From 291c87621e459aa68e5ac0cb0e98eca653882eae Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Wed, 19 Jun 2019 01:45:07 +0200 Subject: [PATCH] Added enum tests. Fixed inline enums inside structs. --- .../Pass0GenerateStatementSequence.java | 4 +- .../dk/camelot64/kickc/test/TestPrograms.java | 25 ++ src/test/kc/enum-4.kc | 8 + src/test/kc/enum-5.kc | 14 + src/test/kc/enum-6.kc | 10 + src/test/kc/enum-7.kc | 16 + src/test/kc/enum-8.kc | 14 + src/test/ref/enum-4.asm | 11 + src/test/ref/enum-4.cfg | 15 + src/test/ref/enum-4.log | 224 ++++++++++++ src/test/ref/enum-4.sym | 10 + src/test/ref/enum-5.asm | 19 ++ src/test/ref/enum-5.cfg | 22 ++ src/test/ref/enum-5.log | 319 ++++++++++++++++++ src/test/ref/enum-5.sym | 16 + src/test/ref/enum-6.asm | 14 + src/test/ref/enum-6.cfg | 16 + src/test/ref/enum-6.log | 256 ++++++++++++++ src/test/ref/enum-6.sym | 11 + src/test/ref/enum-7.asm | 14 + src/test/ref/enum-7.cfg | 16 + src/test/ref/enum-7.log | 284 ++++++++++++++++ src/test/ref/enum-7.sym | 16 + src/test/ref/enum-8.asm | 14 + src/test/ref/enum-8.cfg | 16 + src/test/ref/enum-8.log | 284 ++++++++++++++++ src/test/ref/enum-8.sym | 14 + 27 files changed, 1681 insertions(+), 1 deletion(-) create mode 100644 src/test/kc/enum-4.kc create mode 100644 src/test/kc/enum-5.kc create mode 100644 src/test/kc/enum-6.kc create mode 100644 src/test/kc/enum-7.kc create mode 100644 src/test/kc/enum-8.kc create mode 100644 src/test/ref/enum-4.asm create mode 100644 src/test/ref/enum-4.cfg create mode 100644 src/test/ref/enum-4.log create mode 100644 src/test/ref/enum-4.sym create mode 100644 src/test/ref/enum-5.asm create mode 100644 src/test/ref/enum-5.cfg create mode 100644 src/test/ref/enum-5.log create mode 100644 src/test/ref/enum-5.sym create mode 100644 src/test/ref/enum-6.asm create mode 100644 src/test/ref/enum-6.cfg create mode 100644 src/test/ref/enum-6.log create mode 100644 src/test/ref/enum-6.sym create mode 100644 src/test/ref/enum-7.asm create mode 100644 src/test/ref/enum-7.cfg create mode 100644 src/test/ref/enum-7.log create mode 100644 src/test/ref/enum-7.sym create mode 100644 src/test/ref/enum-8.asm create mode 100644 src/test/ref/enum-8.cfg create mode 100644 src/test/ref/enum-8.log create mode 100644 src/test/ref/enum-8.sym diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 5c7d8bc14..fc64eaf53 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -1221,8 +1221,10 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { scopeStack.pop(); this.currentEnum = null; // Copy all members to upper-level scope + Scope parentScope = getCurrentScope(); + while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope(); for(ConstantVar member : enumDefinition.getAllConstants(false)) { - getCurrentScope().add(new ConstantVar(member.getLocalName(), getCurrentScope(), SymbolType.BYTE, member.getValue())); + parentScope.add(new ConstantVar(member.getLocalName(), parentScope, SymbolType.BYTE, member.getValue())); } return SymbolType.BYTE; } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 37a1f6071..1eaa6b5f7 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -35,6 +35,31 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testEnum8() throws IOException, URISyntaxException { + compileAndCompare("enum-8"); + } + + @Test + public void testEnum7() throws IOException, URISyntaxException { + compileAndCompare("enum-7"); + } + + @Test + public void testEnum6() throws IOException, URISyntaxException { + compileAndCompare("enum-6"); + } + + @Test + public void testEnum5() throws IOException, URISyntaxException { + compileAndCompare("enum-5"); + } + + @Test + public void testEnum4() throws IOException, URISyntaxException { + compileAndCompare("enum-4"); + } + @Test public void testEnum3() throws IOException, URISyntaxException { compileAndCompare("enum-3"); diff --git a/src/test/kc/enum-4.kc b/src/test/kc/enum-4.kc new file mode 100644 index 000000000..bad6fa08e --- /dev/null +++ b/src/test/kc/enum-4.kc @@ -0,0 +1,8 @@ +// Test of simple enum - inline enum definitions + +void main() { + enum State { OFF, ON } state = ON; + const byte* SCREEN = 0x0400; + *SCREEN = state; +} + diff --git a/src/test/kc/enum-5.kc b/src/test/kc/enum-5.kc new file mode 100644 index 000000000..7301da020 --- /dev/null +++ b/src/test/kc/enum-5.kc @@ -0,0 +1,14 @@ +// Test of simple enum - multiple inline enum definitions + +void main() { + enum State { OFF, ON } state = ON; + const byte* SCREEN = 0x0400; + *SCREEN = state; + test(); +} + +void test() { + enum State { OFF=7, ON } state = ON; + const byte* SCREEN = 0x0428; + *SCREEN = state; +} diff --git a/src/test/kc/enum-6.kc b/src/test/kc/enum-6.kc new file mode 100644 index 000000000..8c619db71 --- /dev/null +++ b/src/test/kc/enum-6.kc @@ -0,0 +1,10 @@ +// Test of simple enum - anonymous enum definition + +void main() { + enum { OFF, ON } state = ON; + const byte* SCREEN = 0x0400; + SCREEN[0] = state; + state = OFF; + SCREEN[1] = state; +} + diff --git a/src/test/kc/enum-7.kc b/src/test/kc/enum-7.kc new file mode 100644 index 000000000..16fcf4c15 --- /dev/null +++ b/src/test/kc/enum-7.kc @@ -0,0 +1,16 @@ +// Test of simple enum - struct with enum + +enum Color { RED, GREEN}; + +struct Button { + enum Color color; + byte size; +}; + +void main() { + struct Button button = { RED, 24}; + const byte* SCREEN = 0x0400; + SCREEN[0] = button.color; + SCREEN[1] = button.size; +} + diff --git a/src/test/kc/enum-8.kc b/src/test/kc/enum-8.kc new file mode 100644 index 000000000..cf8871a83 --- /dev/null +++ b/src/test/kc/enum-8.kc @@ -0,0 +1,14 @@ +// Test of simple enum - struct with inline anonymous enum + +struct Button { + enum { RED=2, GREEN=5 } color; + byte size; +}; + +void main() { + struct Button button = { RED, 24 }; + const byte* SCREEN = 0x0400; + SCREEN[0] = button.color; + SCREEN[1] = button.size; +} + diff --git a/src/test/ref/enum-4.asm b/src/test/ref/enum-4.asm new file mode 100644 index 000000000..124db5c09 --- /dev/null +++ b/src/test/ref/enum-4.asm @@ -0,0 +1,11 @@ +// Test of simple enum - inline enum definitions +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .const ON = 1 + .label SCREEN = $400 + lda #ON + sta SCREEN + rts +} diff --git a/src/test/ref/enum-4.cfg b/src/test/ref/enum-4.cfg new file mode 100644 index 000000000..0ad160dc6 --- /dev/null +++ b/src/test/ref/enum-4.cfg @@ -0,0 +1,15 @@ +@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] *((const byte*) main::SCREEN#0) ← (const byte) main::ON + to:main::@return +main::@return: scope:[main] from main + [5] return + to:@return diff --git a/src/test/ref/enum-4.log b/src/test/ref/enum-4.log new file mode 100644 index 000000000..0703580ee --- /dev/null +++ b/src/test/ref/enum-4.log @@ -0,0 +1,224 @@ +Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400 +Identified constant variable (byte) main::state + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (byte) main::state#0 ← (const byte) main::ON + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + *((byte*) main::SCREEN#0) ← (byte) main::state#0 + 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() +(label) main::@return +(const byte) main::ON = (byte) 1 +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::state +(byte) main::state#0 + +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 1024 +Successful SSA optimization PassNCastSimplification +Constant (const byte) main::state#0 = main::ON +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Successful SSA optimization Pass2ConstantIdentification +Constant inlined main::state#0 = (const byte) main::ON +Successful SSA optimization Pass2ConstantInlining +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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] *((const byte*) main::SCREEN#0) ← (const byte) main::ON + to:main::@return +main::@return: scope:[main] from main + [5] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte*) main::SCREEN +(byte) main::state + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 File Comments +// Test of simple enum - inline enum definitions +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + jmp breturn + //SEG11 main::@return + breturn: + //SEG12 [5] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 27 combination +Uplifting [] best 27 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Test of simple enum - inline enum definitions +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + jmp breturn + //SEG11 main::@return + breturn: + //SEG12 [5] return + rts +} + +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 +(const byte) main::ON ON = (byte) 1 +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::state + + + +FINAL ASSEMBLER +Score: 12 + +//SEG0 File Comments +// Test of simple enum - inline enum definitions +//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 [3] phi from @1 to @end [phi:@1->@end] +//SEG8 @end +//SEG9 main +main: { + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 main::@return + //SEG12 [5] return + rts +} + diff --git a/src/test/ref/enum-4.sym b/src/test/ref/enum-4.sym new file mode 100644 index 000000000..9c2ea1152 --- /dev/null +++ b/src/test/ref/enum-4.sym @@ -0,0 +1,10 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@return +(const byte) main::ON ON = (byte) 1 +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::state + diff --git a/src/test/ref/enum-5.asm b/src/test/ref/enum-5.asm new file mode 100644 index 000000000..e8c3ea5aa --- /dev/null +++ b/src/test/ref/enum-5.asm @@ -0,0 +1,19 @@ +// Test of simple enum - multiple inline enum definitions +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .const ON = 1 + .label SCREEN = $400 + lda #ON + sta SCREEN + jsr test + rts +} +test: { + .const ON = 8 + .label SCREEN = $428 + lda #ON + sta SCREEN + rts +} diff --git a/src/test/ref/enum-5.cfg b/src/test/ref/enum-5.cfg new file mode 100644 index 000000000..a599ba244 --- /dev/null +++ b/src/test/ref/enum-5.cfg @@ -0,0 +1,22 @@ +@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] *((const byte*) main::SCREEN#0) ← (const byte) main::ON + [5] call test + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return +test: scope:[test] from main + [7] *((const byte*) test::SCREEN#0) ← (const byte) test::ON + to:test::@return +test::@return: scope:[test] from test + [8] return + to:@return diff --git a/src/test/ref/enum-5.log b/src/test/ref/enum-5.log new file mode 100644 index 000000000..9be05a1b7 --- /dev/null +++ b/src/test/ref/enum-5.log @@ -0,0 +1,319 @@ +Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400 +Adding pointer type conversion cast (byte*) test::SCREEN in (byte*) test::SCREEN ← (number) $428 +Identified constant variable (byte) main::state +Identified constant variable (byte) test::state +Culled Empty Block (label) @1 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@2 +main: scope:[main] from @2 + (byte) main::state#0 ← (const byte) main::ON + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + *((byte*) main::SCREEN#0) ← (byte) main::state#0 + call test + to:main::@1 +main::@1: scope:[main] from main + to:main::@return +main::@return: scope:[main] from main::@1 + return + to:@return +test: scope:[test] from main + (byte) test::state#0 ← (const byte) test::ON + (byte*) test::SCREEN#0 ← ((byte*)) (number) $428 + *((byte*) test::SCREEN#0) ← (byte) test::state#0 + to:test::@return +test::@return: scope:[test] from test + 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 +(void()) main() +(label) main::@1 +(label) main::@return +(const byte) main::ON = (byte) 1 +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::state +(byte) main::state#0 +(void()) test() +(label) test::@return +(const byte) test::ON = (byte) 8 +(byte*) test::SCREEN +(byte*) test::SCREEN#0 +(byte) test::state +(byte) test::state#0 + +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Inlining cast (byte*) test::SCREEN#0 ← (byte*)(number) $428 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant pointer cast (byte*) 1064 +Successful SSA optimization PassNCastSimplification +Constant (const byte) main::state#0 = main::ON +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Constant (const byte) test::state#0 = test::ON +Constant (const byte*) test::SCREEN#0 = (byte*) 1064 +Successful SSA optimization Pass2ConstantIdentification +Constant inlined test::state#0 = (const byte) test::ON +Constant inlined main::state#0 = (const byte) main::ON +Successful SSA optimization Pass2ConstantInlining +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main::@1 +CALL GRAPH +Calls in [] to main:2 +Calls in [main] to test:6 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @3 +Culled Empty Block (label) main::@1 +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 + +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] *((const byte*) main::SCREEN#0) ← (const byte) main::ON + [5] call test + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return +test: scope:[test] from main + [7] *((const byte*) test::SCREEN#0) ← (const byte) test::ON + to:test::@return +test::@return: scope:[test] from test + [8] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte*) main::SCREEN +(byte) main::state +(void()) test() +(byte*) test::SCREEN +(byte) test::state + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 File Comments +// Test of simple enum - multiple inline enum definitions +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 [5] call test + jsr test + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} +//SEG14 test +test: { + .const ON = 8 + .label SCREEN = $428 + //SEG15 [7] *((const byte*) test::SCREEN#0) ← (const byte) test::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + jmp breturn + //SEG16 test::@return + breturn: + //SEG17 [8] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [7] *((const byte*) test::SCREEN#0) ← (const byte) test::ON [ ] ( main:2::test:5 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [test] +Uplift Scope [] + +Uplifting [main] best 48 combination +Uplifting [test] best 48 combination +Uplifting [] best 48 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Test of simple enum - multiple inline enum definitions +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 [5] call test + jsr test + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} +//SEG14 test +test: { + .const ON = 8 + .label SCREEN = $428 + //SEG15 [7] *((const byte*) test::SCREEN#0) ← (const byte) test::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + jmp breturn + //SEG16 test::@return + breturn: + //SEG17 [8] return + rts +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp breturn +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: +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 +(const byte) main::ON ON = (byte) 1 +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::state +(void()) test() +(label) test::@return +(const byte) test::ON ON = (byte) 8 +(byte*) test::SCREEN +(const byte*) test::SCREEN#0 SCREEN = (byte*) 1064 +(byte) test::state + + + +FINAL ASSEMBLER +Score: 30 + +//SEG0 File Comments +// Test of simple enum - multiple inline enum definitions +//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 [3] phi from @1 to @end [phi:@1->@end] +//SEG8 @end +//SEG9 main +main: { + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 [5] call test + jsr test + //SEG12 main::@return + //SEG13 [6] return + rts +} +//SEG14 test +test: { + .const ON = 8 + .label SCREEN = $428 + //SEG15 [7] *((const byte*) test::SCREEN#0) ← (const byte) test::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG16 test::@return + //SEG17 [8] return + rts +} + diff --git a/src/test/ref/enum-5.sym b/src/test/ref/enum-5.sym new file mode 100644 index 000000000..846060ee1 --- /dev/null +++ b/src/test/ref/enum-5.sym @@ -0,0 +1,16 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@return +(const byte) main::ON ON = (byte) 1 +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::state +(void()) test() +(label) test::@return +(const byte) test::ON ON = (byte) 8 +(byte*) test::SCREEN +(const byte*) test::SCREEN#0 SCREEN = (byte*) 1064 +(byte) test::state + diff --git a/src/test/ref/enum-6.asm b/src/test/ref/enum-6.asm new file mode 100644 index 000000000..657d28311 --- /dev/null +++ b/src/test/ref/enum-6.asm @@ -0,0 +1,14 @@ +// Test of simple enum - anonymous enum definition +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .const OFF = 0 + .const ON = 1 + .label SCREEN = $400 + lda #ON + sta SCREEN + lda #OFF + sta SCREEN+1 + rts +} diff --git a/src/test/ref/enum-6.cfg b/src/test/ref/enum-6.cfg new file mode 100644 index 000000000..e2a95e3e0 --- /dev/null +++ b/src/test/ref/enum-6.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] *((const byte*) main::SCREEN#0) ← (const byte) main::ON + [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::OFF + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/enum-6.log b/src/test/ref/enum-6.log new file mode 100644 index 000000000..0d5cec9e2 --- /dev/null +++ b/src/test/ref/enum-6.log @@ -0,0 +1,256 @@ +Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (byte) main::state#0 ← (const byte) main::ON + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::state#0 + (byte) main::state#1 ← (const byte) main::OFF + *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::state#1 + 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() +(label) main::@return +(const byte) main::OFF = (byte) 0 +(const byte) main::ON = (byte) 1 +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::state +(byte) main::state#0 +(byte) main::state#1 + +Adding number conversion cast (unumber) 0 in *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::state#0 +Adding number conversion cast (unumber) 1 in *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::state#1 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant (const byte) main::state#0 = main::ON +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Constant (const byte) main::state#1 = main::OFF +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero main::SCREEN#0 in [2] *((const byte*) main::SCREEN#0 + (byte) 0) ← (const byte) main::state#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Constant inlined main::state#1 = (const byte) main::OFF +Constant inlined main::state#0 = (const byte) main::ON +Successful SSA optimization Pass2ConstantInlining +Consolidated array index constant in *(main::SCREEN#0+1) +Successful SSA optimization Pass2ConstantAdditionElimination +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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] *((const byte*) main::SCREEN#0) ← (const byte) main::ON + [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::OFF + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte*) main::SCREEN +(byte) main::state + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 File Comments +// Test of simple enum - anonymous enum definition +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const OFF = 0 + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::OFF -- _deref_pbuc1=vbuc2 + lda #OFF + sta SCREEN+1 + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::OFF [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 33 combination +Uplifting [] best 33 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Test of simple enum - anonymous enum definition +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const OFF = 0 + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::OFF -- _deref_pbuc1=vbuc2 + lda #OFF + sta SCREEN+1 + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} + +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 +(const byte) main::OFF OFF = (byte) 0 +(const byte) main::ON ON = (byte) 1 +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::state + + + +FINAL ASSEMBLER +Score: 18 + +//SEG0 File Comments +// Test of simple enum - anonymous enum definition +//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 [3] phi from @1 to @end [phi:@1->@end] +//SEG8 @end +//SEG9 main +main: { + .const OFF = 0 + .const ON = 1 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) main::ON -- _deref_pbuc1=vbuc2 + lda #ON + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::OFF -- _deref_pbuc1=vbuc2 + lda #OFF + sta SCREEN+1 + //SEG12 main::@return + //SEG13 [6] return + rts +} + diff --git a/src/test/ref/enum-6.sym b/src/test/ref/enum-6.sym new file mode 100644 index 000000000..060ffc7cd --- /dev/null +++ b/src/test/ref/enum-6.sym @@ -0,0 +1,11 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@return +(const byte) main::OFF OFF = (byte) 0 +(const byte) main::ON ON = (byte) 1 +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::state + diff --git a/src/test/ref/enum-7.asm b/src/test/ref/enum-7.asm new file mode 100644 index 000000000..5d4eed762 --- /dev/null +++ b/src/test/ref/enum-7.asm @@ -0,0 +1,14 @@ +// Test of simple enum - struct with enum +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const RED = 0 +main: { + .const button_size = $18 + .label SCREEN = $400 + lda #RED + sta SCREEN + lda #button_size + sta SCREEN+1 + rts +} diff --git a/src/test/ref/enum-7.cfg b/src/test/ref/enum-7.cfg new file mode 100644 index 000000000..ee2bf5042 --- /dev/null +++ b/src/test/ref/enum-7.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] *((const byte*) main::SCREEN#0) ← (const byte) RED + [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/enum-7.log b/src/test/ref/enum-7.log new file mode 100644 index 000000000..4d5acbc0d --- /dev/null +++ b/src/test/ref/enum-7.log @@ -0,0 +1,284 @@ +Created struct value member variable (byte) main::button_color +Created struct value member variable (byte) main::button_size +Converted struct value to member variables (struct Button) main::button +Adding struct value list initializer (byte) main::button_color ← (const byte) RED +Adding struct value list initializer (byte) main::button_size ← (number) $18 +Replacing struct member reference (struct Button) main::button.color with member variable reference (byte) main::button_color +Replacing struct member reference (struct Button) main::button.size with member variable reference (byte) main::button_size +Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400 +Identified constant variable (byte) main::button_color +Identified constant variable (byte) main::button_size + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (byte) main::button_color#0 ← (const byte) RED + (byte) main::button_size#0 ← (number) $18 + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::button_color#0 + *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::button_size#0 + 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 +(byte) Button::color +(byte) Button::size +(const byte) Color::GREEN = (byte) 1 +(const byte) Color::RED = (byte) 0 +(const byte) RED = (byte) 0 +(void()) main() +(label) main::@return +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::button_color +(byte) main::button_color#0 +(byte) main::button_size +(byte) main::button_size#0 + +Adding number conversion cast (unumber) $18 in (byte) main::button_size#0 ← (number) $18 +Adding number conversion cast (unumber) 0 in *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::button_color#0 +Adding number conversion cast (unumber) 1 in *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::button_size#0 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (byte) main::button_size#0 ← (unumber)(number) $18 +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Successful SSA optimization Pass2InlineCast +Simplifying constant integer cast $18 +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) $18 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant (const byte) main::button_color#0 = RED +Constant (const byte) main::button_size#0 = $18 +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero main::SCREEN#0 in [3] *((const byte*) main::SCREEN#0 + (byte) 0) ← (const byte) main::button_color#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Constant inlined main::button_color#0 = (const byte) RED +Successful SSA optimization Pass2ConstantInlining +Consolidated array index constant in *(main::SCREEN#0+1) +Successful SSA optimization Pass2ConstantAdditionElimination +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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] *((const byte*) main::SCREEN#0) ← (const byte) RED + [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) Button::color +(byte) Button::size +(void()) main() +(byte*) main::SCREEN +(byte) main::button_color +(byte) main::button_size + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 File Comments +// Test of simple enum - struct with enum +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const RED = 0 +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const button_size = $18 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) RED -- _deref_pbuc1=vbuc2 + lda #RED + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 -- _deref_pbuc1=vbuc2 + lda #button_size + sta SCREEN+1 + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) RED [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [Color] +Uplift Scope [Button] +Uplift Scope [main] +Uplift Scope [] + +Uplifting [Color] best 33 combination +Uplifting [Button] best 33 combination +Uplifting [main] best 33 combination +Uplifting [] best 33 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Test of simple enum - struct with enum +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const RED = 0 +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const button_size = $18 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) RED -- _deref_pbuc1=vbuc2 + lda #RED + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 -- _deref_pbuc1=vbuc2 + lda #button_size + sta SCREEN+1 + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} + +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 +(byte) Button::color +(byte) Button::size +(const byte) Color::GREEN GREEN = (byte) 1 +(const byte) Color::RED RED = (byte) 0 +(const byte) RED RED = (byte) 0 +(void()) main() +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::button_color +(byte) main::button_size +(const byte) main::button_size#0 button_size = (byte) $18 + + + +FINAL ASSEMBLER +Score: 18 + +//SEG0 File Comments +// Test of simple enum - struct with enum +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const RED = 0 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +//SEG8 @end +//SEG9 main +main: { + .const button_size = $18 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) RED -- _deref_pbuc1=vbuc2 + lda #RED + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 -- _deref_pbuc1=vbuc2 + lda #button_size + sta SCREEN+1 + //SEG12 main::@return + //SEG13 [6] return + rts +} + diff --git a/src/test/ref/enum-7.sym b/src/test/ref/enum-7.sym new file mode 100644 index 000000000..9900d36b9 --- /dev/null +++ b/src/test/ref/enum-7.sym @@ -0,0 +1,16 @@ +(label) @1 +(label) @begin +(label) @end +(byte) Button::color +(byte) Button::size +(const byte) Color::GREEN GREEN = (byte) 1 +(const byte) Color::RED RED = (byte) 0 +(const byte) RED RED = (byte) 0 +(void()) main() +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::button_color +(byte) main::button_size +(const byte) main::button_size#0 button_size = (byte) $18 + diff --git a/src/test/ref/enum-8.asm b/src/test/ref/enum-8.asm new file mode 100644 index 000000000..6819a436a --- /dev/null +++ b/src/test/ref/enum-8.asm @@ -0,0 +1,14 @@ +// Test of simple enum - struct with inline anonymous enum +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const RED = 2 +main: { + .const button_size = $18 + .label SCREEN = $400 + lda #RED + sta SCREEN + lda #button_size + sta SCREEN+1 + rts +} diff --git a/src/test/ref/enum-8.cfg b/src/test/ref/enum-8.cfg new file mode 100644 index 000000000..ee2bf5042 --- /dev/null +++ b/src/test/ref/enum-8.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] *((const byte*) main::SCREEN#0) ← (const byte) RED + [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/enum-8.log b/src/test/ref/enum-8.log new file mode 100644 index 000000000..126adcfd5 --- /dev/null +++ b/src/test/ref/enum-8.log @@ -0,0 +1,284 @@ +Created struct value member variable (byte) main::button_color +Created struct value member variable (byte) main::button_size +Converted struct value to member variables (struct Button) main::button +Adding struct value list initializer (byte) main::button_color ← (const byte) RED +Adding struct value list initializer (byte) main::button_size ← (number) $18 +Replacing struct member reference (struct Button) main::button.color with member variable reference (byte) main::button_color +Replacing struct member reference (struct Button) main::button.size with member variable reference (byte) main::button_size +Adding pointer type conversion cast (byte*) main::SCREEN in (byte*) main::SCREEN ← (number) $400 +Identified constant variable (byte) main::button_color +Identified constant variable (byte) main::button_size + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (byte) main::button_color#0 ← (const byte) RED + (byte) main::button_size#0 ← (number) $18 + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::button_color#0 + *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::button_size#0 + 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 +(const byte) Button::$0::GREEN = (number) 5 +(const byte) Button::$0::RED = (number) 2 +(byte) Button::color +(byte) Button::size +(const byte) RED = (number) 2 +(void()) main() +(label) main::@return +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::button_color +(byte) main::button_color#0 +(byte) main::button_size +(byte) main::button_size#0 + +Adding number conversion cast (unumber) $18 in (byte) main::button_size#0 ← (number) $18 +Adding number conversion cast (unumber) 0 in *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::button_color#0 +Adding number conversion cast (unumber) 1 in *((byte*) main::SCREEN#0 + (number) 1) ← (byte) main::button_size#0 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (byte) main::button_size#0 ← (unumber)(number) $18 +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Successful SSA optimization Pass2InlineCast +Simplifying constant integer cast $18 +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) $18 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant (const byte) main::button_color#0 = RED +Constant (const byte) main::button_size#0 = $18 +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero main::SCREEN#0 in [3] *((const byte*) main::SCREEN#0 + (byte) 0) ← (const byte) main::button_color#0 +Successful SSA optimization PassNSimplifyExpressionWithZero +Constant inlined Button::$0::RED = (number) 2 +Constant inlined main::button_color#0 = (const byte) RED +Constant inlined Button::$0::GREEN = (number) 5 +Successful SSA optimization Pass2ConstantInlining +Consolidated array index constant in *(main::SCREEN#0+1) +Successful SSA optimization Pass2ConstantAdditionElimination +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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] *((const byte*) main::SCREEN#0) ← (const byte) RED + [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) Button::color +(byte) Button::size +(void()) main() +(byte*) main::SCREEN +(byte) main::button_color +(byte) main::button_size + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 File Comments +// Test of simple enum - struct with inline anonymous enum +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const RED = 2 +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const button_size = $18 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) RED -- _deref_pbuc1=vbuc2 + lda #RED + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 -- _deref_pbuc1=vbuc2 + lda #button_size + sta SCREEN+1 + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const byte*) main::SCREEN#0) ← (const byte) RED [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [Button] +Uplift Scope [Button::$0] +Uplift Scope [main] +Uplift Scope [] + +Uplifting [Button] best 33 combination +Uplifting [Button::$0] best 33 combination +Uplifting [main] best 33 combination +Uplifting [] best 33 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Test of simple enum - struct with inline anonymous enum +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const RED = 2 +//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 + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + .const button_size = $18 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) RED -- _deref_pbuc1=vbuc2 + lda #RED + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 -- _deref_pbuc1=vbuc2 + lda #button_size + sta SCREEN+1 + jmp breturn + //SEG12 main::@return + breturn: + //SEG13 [6] return + rts +} + +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 +(byte) Button::color +(byte) Button::size +(const byte) RED RED = (number) 2 +(void()) main() +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::button_color +(byte) main::button_size +(const byte) main::button_size#0 button_size = (byte) $18 + + + +FINAL ASSEMBLER +Score: 18 + +//SEG0 File Comments +// Test of simple enum - struct with inline anonymous enum +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const RED = 2 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +//SEG8 @end +//SEG9 main +main: { + .const button_size = $18 + .label SCREEN = $400 + //SEG10 [4] *((const byte*) main::SCREEN#0) ← (const byte) RED -- _deref_pbuc1=vbuc2 + lda #RED + sta SCREEN + //SEG11 [5] *((const byte*) main::SCREEN#0+(byte) 1) ← (const byte) main::button_size#0 -- _deref_pbuc1=vbuc2 + lda #button_size + sta SCREEN+1 + //SEG12 main::@return + //SEG13 [6] return + rts +} + diff --git a/src/test/ref/enum-8.sym b/src/test/ref/enum-8.sym new file mode 100644 index 000000000..b37420dd2 --- /dev/null +++ b/src/test/ref/enum-8.sym @@ -0,0 +1,14 @@ +(label) @1 +(label) @begin +(label) @end +(byte) Button::color +(byte) Button::size +(const byte) RED RED = (number) 2 +(void()) main() +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::button_color +(byte) main::button_size +(const byte) main::button_size#0 button_size = (byte) $18 +