From 88b2cd86c23b03f33aea5d4ccf572a0b476dff5a Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sun, 5 Apr 2020 22:54:00 +0200 Subject: [PATCH] Added test for #define containing inline ASM/KickAsm. Fixed problem with ASM. #169 --- .../kickc/model/statements/StatementAsm.java | 17 +- .../Pass0GenerateStatementSequence.java | 20 +- .../kickc/passes/Pass1ProcedureInline.java | 2 +- .../kickc/preprocessor/CPreprocessor.java | 7 +- .../dk/camelot64/kickc/test/TestPrograms.java | 10 + src/test/kc/preprocessor-7.kc | 14 + src/test/kc/preprocessor-8.kc | 14 + src/test/ref/preprocessor-7.asm | 17 ++ src/test/ref/preprocessor-7.cfg | 19 ++ src/test/ref/preprocessor-7.log | 267 ++++++++++++++++++ src/test/ref/preprocessor-7.sym | 8 + src/test/ref/preprocessor-8.asm | 17 ++ src/test/ref/preprocessor-8.cfg | 19 ++ src/test/ref/preprocessor-8.log | 267 ++++++++++++++++++ src/test/ref/preprocessor-8.sym | 8 + 15 files changed, 669 insertions(+), 37 deletions(-) create mode 100644 src/test/kc/preprocessor-7.kc create mode 100644 src/test/kc/preprocessor-8.kc create mode 100644 src/test/ref/preprocessor-7.asm create mode 100644 src/test/ref/preprocessor-7.cfg create mode 100644 src/test/ref/preprocessor-7.log create mode 100644 src/test/ref/preprocessor-7.sym create mode 100644 src/test/ref/preprocessor-8.asm create mode 100644 src/test/ref/preprocessor-8.cfg create mode 100644 src/test/ref/preprocessor-8.log create mode 100644 src/test/ref/preprocessor-8.sym diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java index 7a1c92891..b338224e8 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementAsm.java @@ -1,6 +1,5 @@ package dk.camelot64.kickc.model.statements; -import dk.camelot64.kickc.parser.AsmParser; import dk.camelot64.kickc.asm.AsmClobber; import dk.camelot64.kickc.model.Comment; import dk.camelot64.kickc.model.Program; @@ -13,11 +12,8 @@ import java.util.Map; /** Inline ASM code */ public class StatementAsm extends StatementBase { - /** ASM code. */ - private String asmBody; - /** Cached parsed ASM code. */ - private transient KickCParser.AsmLinesContext asmLines; + private KickCParser.AsmLinesContext asmLines; /** All variables/constants referenced in the inline assembler. */ private Map referenced; @@ -25,9 +21,9 @@ public class StatementAsm extends StatementBase { /** Declared clobber for the inline ASM. */ private AsmClobber declaredClobber; - public StatementAsm(String asmBody, Map referenced, AsmClobber declaredClobber, StatementSource source, List comments) { + public StatementAsm(KickCParser.AsmLinesContext asmBody, Map referenced, AsmClobber declaredClobber, StatementSource source, List comments) { super(source, comments); - this.asmBody = asmBody; + this.asmLines = asmBody; this.referenced = referenced; this.declaredClobber = declaredClobber; } @@ -43,14 +39,7 @@ public class StatementAsm extends StatementBase { return txt.toString(); } - public String getAsmBody() { - return asmBody; - } - public KickCParser.AsmLinesContext getAsmLines() { - if(asmLines==null) { - this.asmLines = AsmParser.parseAsm(asmBody, getSource()); - } return asmLines; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 99047353c..dbff89f4e 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -1531,29 +1531,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor(procAsm.getReferenced()), procAsm.getDeclaredClobber(), procAsm.getSource(), Comment.NO_COMMENTS); + StatementAsm inlinedAsm = new StatementAsm(procAsm.getAsmLines(), new LinkedHashMap<>(procAsm.getReferenced()), procAsm.getDeclaredClobber(), procAsm.getSource(), Comment.NO_COMMENTS); inlinedStatement = inlinedAsm; } else if(procStatement instanceof StatementConditionalJump) { StatementConditionalJump procConditional = (StatementConditionalJump) procStatement; diff --git a/src/main/java/dk/camelot64/kickc/preprocessor/CPreprocessor.java b/src/main/java/dk/camelot64/kickc/preprocessor/CPreprocessor.java index c847857b9..b82623bda 100644 --- a/src/main/java/dk/camelot64/kickc/preprocessor/CPreprocessor.java +++ b/src/main/java/dk/camelot64/kickc/preprocessor/CPreprocessor.java @@ -106,8 +106,9 @@ public class CPreprocessor implements TokenSource { // Skip #endif - they have already been handled by #if / #else return true; } else if(inputToken.getType() == tokenTypes.identifier) { - final boolean expanded = expandMacro(inputToken, cTokenSource); - if(expanded) return true; + final boolean expanded = expand(inputToken, cTokenSource); + if(expanded) + return true; } return false; } @@ -119,7 +120,7 @@ public class CPreprocessor implements TokenSource { * @param cTokenSource The token source usable for getting more tokens (eg. parameter values) - and for pushing the expanded body to the front for further processing. * @return true if a macro was expanded. False if not. */ - private boolean expandMacro(Token inputToken, CTokenSource cTokenSource) { + private boolean expand(Token inputToken, CTokenSource cTokenSource) { final String macroName = inputToken.getText(); List macroBody = defines.get(macroName); if(macroBody != null) { diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 355cb5fb5..a0c7c6cca 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -37,6 +37,16 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testPreprocessor8() throws IOException, URISyntaxException { + compileAndCompare("preprocessor-8"); + } + + @Test + public void testPreprocessor7() throws IOException, URISyntaxException { + compileAndCompare("preprocessor-7"); + } + @Test public void testPreprocessor6() throws IOException, URISyntaxException { compileAndCompare("preprocessor-6"); diff --git a/src/test/kc/preprocessor-7.kc b/src/test/kc/preprocessor-7.kc new file mode 100644 index 000000000..483c453c1 --- /dev/null +++ b/src/test/kc/preprocessor-7.kc @@ -0,0 +1,14 @@ +// Test the preprocessor +// Macro generating inline ASM + +#define SEI asm { sei } +#define CLI asm { cli } + +char * SCREEN = 0x0400; +char idx = 0; + +void main() { + SEI + SCREEN[idx++] = 'x'; + CLI +} \ No newline at end of file diff --git a/src/test/kc/preprocessor-8.kc b/src/test/kc/preprocessor-8.kc new file mode 100644 index 000000000..f87f41cac --- /dev/null +++ b/src/test/kc/preprocessor-8.kc @@ -0,0 +1,14 @@ +// Test the preprocessor +// Macro generating inline kickasm + +#define SEI kickasm {{ sei }} +#define CLI kickasm {{ cli }} + +char * SCREEN = 0x0400; +char idx = 0; + +void main() { + SEI + SCREEN[idx++] = 'x'; + CLI +} \ No newline at end of file diff --git a/src/test/ref/preprocessor-7.asm b/src/test/ref/preprocessor-7.asm new file mode 100644 index 000000000..36486b6b8 --- /dev/null +++ b/src/test/ref/preprocessor-7.asm @@ -0,0 +1,17 @@ +// Test the preprocessor +// Macro generating inline ASM +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 +main: { + // SEI + sei + // SCREEN[idx++] = 'x' + lda #'x' + sta SCREEN + // CLI + cli + // } + rts +} diff --git a/src/test/ref/preprocessor-7.cfg b/src/test/ref/preprocessor-7.cfg new file mode 100644 index 000000000..27171532a --- /dev/null +++ b/src/test/ref/preprocessor-7.cfg @@ -0,0 +1,19 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + asm { sei } + [5] *((const byte*) SCREEN) ← (byte) 'x' + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [7] return + to:@return diff --git a/src/test/ref/preprocessor-7.log b/src/test/ref/preprocessor-7.log new file mode 100644 index 000000000..84d24731d --- /dev/null +++ b/src/test/ref/preprocessor-7.log @@ -0,0 +1,267 @@ +Identified constant variable (byte*) SCREEN + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte) idx#0 ← (byte) 0 + to:@1 + +(void()) main() +main: scope:[main] from @1 + (byte) idx#4 ← phi( @1/(byte) idx#7 ) + asm { sei } + *((const byte*) SCREEN + (byte) idx#4) ← (byte) 'x' + (byte) idx#1 ← ++ (byte) idx#4 + asm { cli } + to:main::@return +main::@return: scope:[main] from main + (byte) idx#5 ← phi( main/(byte) idx#1 ) + (byte) idx#2 ← (byte) idx#5 + return + to:@return +@1: scope:[] from @begin + (byte) idx#7 ← phi( @begin/(byte) idx#0 ) + call main + to:@2 +@2: scope:[] from @1 + (byte) idx#6 ← phi( @1/(byte) idx#2 ) + (byte) idx#3 ← (byte) idx#6 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(const byte*) SCREEN = (byte*)(number) $400 +(byte) idx +(byte) idx#0 +(byte) idx#1 +(byte) idx#2 +(byte) idx#3 +(byte) idx#4 +(byte) idx#5 +(byte) idx#6 +(byte) idx#7 +(void()) main() +(label) main::@return + +Simplifying constant pointer cast (byte*) 1024 +Successful SSA optimization PassNCastSimplification +Alias idx#1 = idx#5 idx#2 +Alias idx#0 = idx#7 +Alias idx#3 = idx#6 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) idx#4 (byte) idx#0 +Identical Phi Values (byte) idx#3 (byte) idx#1 +Successful SSA optimization Pass2IdenticalPhiElimination +Constant (const byte) idx#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (const byte) idx#0) ← (byte) 'x' +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused variable (byte) idx#1 and assignment [2] (byte) idx#1 ← ++ (const byte) idx#0 +Successful SSA optimization PassNEliminateUnusedVars +Eliminating unused constant (const byte) idx#0 +Successful SSA optimization PassNEliminateUnusedVars +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() + +(void()) main() +main: scope:[main] from @1 + asm { sei } + [5] *((const byte*) SCREEN) ← (byte) 'x' + asm { cli } + to:main::@return +main::@return: scope:[main] from main + [7] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) idx +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Test the preprocessor +// Macro generating inline ASM + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @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: { + // asm { sei } + sei + // [5] *((const byte*) SCREEN) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN + // asm { cli } + cli + jmp __breturn + // main::@return + __breturn: + // [7] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((const byte*) SCREEN) ← (byte) 'x' [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 31 combination +Uplifting [] best 31 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Test the preprocessor +// Macro generating inline ASM + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @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: { + // asm { sei } + sei + // [5] *((const byte*) SCREEN) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN + // asm { cli } + cli + jmp __breturn + // main::@return + __breturn: + // [7] 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 +(const byte*) SCREEN = (byte*) 1024 +(byte) idx +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 16 + + // File Comments +// Test the preprocessor +// Macro generating inline ASM + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @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: { + // SEI + // asm { sei } + sei + // SCREEN[idx++] = 'x' + // [5] *((const byte*) SCREEN) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN + // CLI + // asm { cli } + cli + // main::@return + // } + // [7] return + rts +} + // File Data + diff --git a/src/test/ref/preprocessor-7.sym b/src/test/ref/preprocessor-7.sym new file mode 100644 index 000000000..1a817b3c6 --- /dev/null +++ b/src/test/ref/preprocessor-7.sym @@ -0,0 +1,8 @@ +(label) @1 +(label) @begin +(label) @end +(const byte*) SCREEN = (byte*) 1024 +(byte) idx +(void()) main() +(label) main::@return + diff --git a/src/test/ref/preprocessor-8.asm b/src/test/ref/preprocessor-8.asm new file mode 100644 index 000000000..f8e5b4c76 --- /dev/null +++ b/src/test/ref/preprocessor-8.asm @@ -0,0 +1,17 @@ +// Test the preprocessor +// Macro generating inline kickasm +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 +main: { + // SEI + sei + // SCREEN[idx++] = 'x' + lda #'x' + sta SCREEN + // CLI + cli + // } + rts +} diff --git a/src/test/ref/preprocessor-8.cfg b/src/test/ref/preprocessor-8.cfg new file mode 100644 index 000000000..62a45824d --- /dev/null +++ b/src/test/ref/preprocessor-8.cfg @@ -0,0 +1,19 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + kickasm() {{ sei }} + [5] *((const byte*) SCREEN) ← (byte) 'x' + kickasm() {{ cli }} + to:main::@return +main::@return: scope:[main] from main + [7] return + to:@return diff --git a/src/test/ref/preprocessor-8.log b/src/test/ref/preprocessor-8.log new file mode 100644 index 000000000..cd5915ef7 --- /dev/null +++ b/src/test/ref/preprocessor-8.log @@ -0,0 +1,267 @@ +Identified constant variable (byte*) SCREEN + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte) idx#0 ← (byte) 0 + to:@1 + +(void()) main() +main: scope:[main] from @1 + (byte) idx#4 ← phi( @1/(byte) idx#7 ) + kickasm() {{ sei }} + *((const byte*) SCREEN + (byte) idx#4) ← (byte) 'x' + (byte) idx#1 ← ++ (byte) idx#4 + kickasm() {{ cli }} + to:main::@return +main::@return: scope:[main] from main + (byte) idx#5 ← phi( main/(byte) idx#1 ) + (byte) idx#2 ← (byte) idx#5 + return + to:@return +@1: scope:[] from @begin + (byte) idx#7 ← phi( @begin/(byte) idx#0 ) + call main + to:@2 +@2: scope:[] from @1 + (byte) idx#6 ← phi( @1/(byte) idx#2 ) + (byte) idx#3 ← (byte) idx#6 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(const byte*) SCREEN = (byte*)(number) $400 +(byte) idx +(byte) idx#0 +(byte) idx#1 +(byte) idx#2 +(byte) idx#3 +(byte) idx#4 +(byte) idx#5 +(byte) idx#6 +(byte) idx#7 +(void()) main() +(label) main::@return + +Simplifying constant pointer cast (byte*) 1024 +Successful SSA optimization PassNCastSimplification +Alias idx#1 = idx#5 idx#2 +Alias idx#0 = idx#7 +Alias idx#3 = idx#6 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) idx#4 (byte) idx#0 +Identical Phi Values (byte) idx#3 (byte) idx#1 +Successful SSA optimization Pass2IdenticalPhiElimination +Constant (const byte) idx#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (const byte) idx#0) ← (byte) 'x' +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused variable (byte) idx#1 and assignment [2] (byte) idx#1 ← ++ (const byte) idx#0 +Successful SSA optimization PassNEliminateUnusedVars +Eliminating unused constant (const byte) idx#0 +Successful SSA optimization PassNEliminateUnusedVars +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() + +(void()) main() +main: scope:[main] from @1 + kickasm() {{ sei }} + [5] *((const byte*) SCREEN) ← (byte) 'x' + kickasm() {{ cli }} + to:main::@return +main::@return: scope:[main] from main + [7] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) idx +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Test the preprocessor +// Macro generating inline kickasm + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @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: { + // kickasm() {{ sei }} + sei + // [5] *((const byte*) SCREEN) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN + // kickasm() {{ cli }} + cli + jmp __breturn + // main::@return + __breturn: + // [7] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((const byte*) SCREEN) ← (byte) 'x' [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 539 combination +Uplifting [] best 539 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Test the preprocessor +// Macro generating inline kickasm + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @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: { + // kickasm() {{ sei }} + sei + // [5] *((const byte*) SCREEN) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN + // kickasm() {{ cli }} + cli + jmp __breturn + // main::@return + __breturn: + // [7] 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 +(const byte*) SCREEN = (byte*) 1024 +(byte) idx +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 524 + + // File Comments +// Test the preprocessor +// Macro generating inline kickasm + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @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: { + // SEI + // kickasm() {{ sei }} + sei + // SCREEN[idx++] = 'x' + // [5] *((const byte*) SCREEN) ← (byte) 'x' -- _deref_pbuc1=vbuc2 + lda #'x' + sta SCREEN + // CLI + // kickasm() {{ cli }} + cli + // main::@return + // } + // [7] return + rts +} + // File Data + diff --git a/src/test/ref/preprocessor-8.sym b/src/test/ref/preprocessor-8.sym new file mode 100644 index 000000000..1a817b3c6 --- /dev/null +++ b/src/test/ref/preprocessor-8.sym @@ -0,0 +1,8 @@ +(label) @1 +(label) @begin +(label) @end +(const byte*) SCREEN = (byte*) 1024 +(byte) idx +(void()) main() +(label) main::@return +