diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java index 8fb8c1cd7..99556aa2e 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java @@ -29,6 +29,9 @@ public class OperatorPlus extends OperatorBinary { } else if(left instanceof ConstantPointer && right instanceof ConstantInteger) { long location = ((ConstantPointer) left).getLocation() + ((ConstantInteger) right).getInteger(); return new ConstantPointer(location, ((ConstantPointer) left).getElementType()); + } else if(left instanceof ConstantInteger && right instanceof ConstantPointer) { + long location = ((ConstantPointer) right).getLocation() + ((ConstantInteger) left).getInteger(); + return new ConstantPointer(location, ((ConstantPointer) right).getElementType()); } throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 29997ea12..ee4e7639a 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -54,6 +54,11 @@ public class TestPrograms { compileAndCompare("complex/tetris/tetris"); } + @Test + public void testConsolidateConstantProblem() throws IOException, URISyntaxException { + compileAndCompare("consolidate-constant-problem"); + } + @Test public void testConsolidateArrayIndexProblem() throws IOException, URISyntaxException { compileAndCompare("consolidate-array-index-problem"); diff --git a/src/test/kc/consolidate-constant-problem.kc b/src/test/kc/consolidate-constant-problem.kc new file mode 100644 index 000000000..26e94d31d --- /dev/null +++ b/src/test/kc/consolidate-constant-problem.kc @@ -0,0 +1,8 @@ +const byte* screen = $400; + +void main() { + inline for( byte j: 0..1) { + *(screen+40*j+39) = 0; + screen[40*j+38] = 0; + } +} \ No newline at end of file diff --git a/src/test/ref/consolidate-constant-problem.asm b/src/test/ref/consolidate-constant-problem.asm new file mode 100644 index 000000000..f8146c526 --- /dev/null +++ b/src/test/ref/consolidate-constant-problem.asm @@ -0,0 +1,12 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label screen = $400 +main: { + lda #0 + sta screen+$27 + sta screen+$26 + sta $28*1+screen+$27 + sta screen+$26+$28*1 + rts +} diff --git a/src/test/ref/consolidate-constant-problem.cfg b/src/test/ref/consolidate-constant-problem.cfg new file mode 100644 index 000000000..a377f2fbf --- /dev/null +++ b/src/test/ref/consolidate-constant-problem.cfg @@ -0,0 +1,23 @@ +@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() + to:main::@1 +main::@1: scope:[main] from main + [5] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + [6] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@1_1 +main::@1_1: scope:[main] from main::@1 + [7] *((byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + [8] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38+(byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@return +main::@return: scope:[main] from main::@1_1 + [9] return + to:@return diff --git a/src/test/ref/consolidate-constant-problem.log b/src/test/ref/consolidate-constant-problem.log new file mode 100644 index 000000000..839cce721 --- /dev/null +++ b/src/test/ref/consolidate-constant-problem.log @@ -0,0 +1,360 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) screen#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024 + to:@1 +main: scope:[main] from @1 + (byte) main::j#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@1 +main::@1: scope:[main] from main main::@1 + (byte) main::j#2 ← phi( main/(byte) main::j#0 main::@1/(byte) main::j#1 ) + (byte/signed word/word/dword/signed dword~) main::$0 ← (byte/signed byte/word/signed word/dword/signed dword) 40 * (byte) main::j#2 + (byte*~) main::$1 ← (byte*) screen#0 + (byte/signed word/word/dword/signed dword~) main::$0 + (byte*~) main::$2 ← (byte*~) main::$1 + (byte/signed byte/word/signed word/dword/signed dword) 39 + *((byte*~) main::$2) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte/signed word/word/dword/signed dword~) main::$3 ← (byte/signed byte/word/signed word/dword/signed dword) 40 * (byte) main::j#2 + (byte/signed word/word/dword/signed dword~) main::$4 ← (byte/signed word/word/dword/signed dword~) main::$3 + (byte/signed byte/word/signed word/dword/signed dword) 38 + *((byte*) screen#0 + (byte/signed word/word/dword/signed dword~) main::$4) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte) main::j#1 ← (byte) main::j#2 + rangenext(0,1) + (bool~) main::$5 ← (byte) main::j#1 != rangelast(0,1) + unroll if((bool~) main::$5) goto main::@1 + to:main::@return +main::@return: scope:[main] from main::@1 + 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() +(byte/signed word/word/dword/signed dword~) main::$0 +(byte*~) main::$1 +(byte*~) main::$2 +(byte/signed word/word/dword/signed dword~) main::$3 +(byte/signed word/word/dword/signed dword~) main::$4 +(bool~) main::$5 +(label) main::@1 +(label) main::@return +(byte) main::j +(byte) main::j#0 +(byte) main::j#1 +(byte) main::j#2 +(byte*) screen +(byte*) screen#0 + +Culled Empty Block (label) @2 +Successful SSA optimization Pass2CullEmptyBlocks +Simple Condition (bool~) main::$5 [12] unroll if((byte) main::j#1!=rangelast(0,1)) goto main::@1 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant (const byte*) screen#0 = ((byte*))1024 +Constant (const byte) main::j#0 = 0 +Successful SSA optimization Pass2ConstantIdentification +Consolidated constant in assignment main::$2 +Consolidated array index constant in assignment *(screen#0+38 + main::$4) +Successful SSA optimization Pass2ConstantAdditionElimination +Inferred type updated to byte/signed word/word/dword/signed dword in [2] (byte*~) main::$1 ← (byte/signed word/word/dword/signed dword~) main::$0 +Resolved ranged next value main::j#1 ← ++ main::j#2 to ++ +Resolved ranged comparison value unroll if(main::j#1!=rangelast(0,1)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 2 +Alias (byte/signed word/word/dword/signed dword~) main::$1 = (byte/signed word/word/dword/signed dword~) main::$0 +Alias (byte/signed word/word/dword/signed dword~) main::$4 = (byte/signed word/word/dword/signed dword~) main::$3 +Successful SSA optimization Pass2AliasElimination +Unrolling loop Loop head: main::@1 tails: main::@1 blocks: main::@1 +Successful SSA optimization Pass2LoopUnroll +Redundant Phi (byte) main::j#2 (const byte) main::j#0 +Successful SSA optimization Pass2RedundantPhiElimination +Constant (const byte/signed word/word/dword/signed dword) main::$1 = 40*main::j#0 +Constant (const byte/signed word/word/dword/signed dword) main::$4 = 40*main::j#0 +Constant (const byte) main::j#1 = ++main::j#0 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte*) main::$2 = main::$1+screen#0+39 +Successful SSA optimization Pass2ConstantIdentification +Consolidated array index constant in *(screen#0+38+main::$4) +Successful SSA optimization Pass2ConstantAdditionElimination +if() condition always true - replacing block destination [2] if((const byte) main::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 2) goto main::@1_1 +Successful SSA optimization Pass2ConstantIfs +Unrolling loop Loop head: main::@1_1 tails: main::@1_1 blocks: main::@1_1 +Successful SSA optimization Pass2LoopUnroll +Redundant Phi (byte) main::j#3 (const byte) main::j#1 +Successful SSA optimization Pass2RedundantPhiElimination +Constant (const byte/signed word/word/dword/signed dword) main::$6 = 40*main::j#1 +Constant (const byte/signed word/word/dword/signed dword) main::$8 = 40*main::j#1 +Constant (const byte) main::j#4 = ++main::j#1 +Successful SSA optimization Pass2ConstantIdentification +Constant (const byte*) main::$7 = main::$6+screen#0+39 +Successful SSA optimization Pass2ConstantIdentification +Consolidated array index constant in *(screen#0+38+main::$8) +Successful SSA optimization Pass2ConstantAdditionElimination +Removing PHI-reference to removed block (main::@1_1) in block main::@1_2 +if() condition always false - eliminating [5] if((const byte) main::j#4!=(byte/signed byte/word/signed word/dword/signed dword) 2) goto main::@1_2 +Successful SSA optimization Pass2ConstantIfs +Successful SSA optimization PassNEliminateUnusedVars +Eliminating variable (byte) main::j#5 from unused block main::@1_2 +Eliminating variable (byte/signed word/word/dword/signed dword~) main::$9 from unused block main::@1_2 +Eliminating variable (byte*~) main::$10 from unused block main::@1_2 +Eliminating variable (byte/signed word/word/dword/signed dword~) main::$11 from unused block main::@1_2 +Eliminating variable (byte) main::j#6 from unused block main::@1_2 +Removing unused block main::@1_2 +Successful SSA optimization Pass2EliminateUnusedBlocks +Inlining constant with different constant siblings (const byte) main::j#0 +Inlining constant with different constant siblings (const byte) main::j#1 +Constant inlined main::$1 = (byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::$2 = (byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 0+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39 +Constant inlined main::$6 = (byte/signed byte/word/signed word/dword/signed dword) 40*++(byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::j#1 = ++(byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::$4 = (byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::j#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::$7 = (byte/signed byte/word/signed word/dword/signed dword) 40*++(byte/signed byte/word/signed word/dword/signed dword) 0+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39 +Constant inlined main::$8 = (byte/signed byte/word/signed word/dword/signed dword) 40*++(byte/signed byte/word/signed word/dword/signed dword) 0 +Successful SSA optimization Pass2ConstantInlining +Simplifying constant multiply by zero 40*0 +Simplifying constant multiply by zero 40*0 +Simplifying constant integer increment ++0 +Simplifying constant integer increment ++0 +Successful SSA optimization Pass2ConstantSimplification +Simplifying constant plus zero 0+screen#0+39 +Simplifying constant plus zero screen#0+38+0 +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 +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @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() + to:main::@1 +main::@1: scope:[main] from main + [5] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + [6] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@1_1 +main::@1_1: scope:[main] from main::@1 + [7] *((byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + [8] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38+(byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte/signed byte/word/signed word/dword/signed dword) 0 + to:main::@return +main::@return: scope:[main] from main::@1_1 + [9] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte) main::j +(byte*) screen + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label screen = $400 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG4 @1 +b1: +//SEG5 [2] call main +//SEG6 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + jmp b1 + //SEG10 main::@1 + b1: + //SEG11 [5] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$27 + //SEG12 [6] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$26 + jmp b1_1 + //SEG13 main::@1_1 + b1_1: + //SEG14 [7] *((byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta $28*1+screen+$27 + //SEG15 [8] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38+(byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$26+$28*1 + jmp breturn + //SEG16 main::@return + breturn: + //SEG17 [9] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [6] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [7] *((byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a +Statement [8] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38+(byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 78 combination +Uplifting [] best 78 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label screen = $400 +//SEG2 @begin +bbegin: +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG4 @1 +b1: +//SEG5 [2] call main +//SEG6 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG8 @end +bend: +//SEG9 main +main: { + jmp b1 + //SEG10 main::@1 + b1: + //SEG11 [5] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$27 + //SEG12 [6] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$26 + jmp b1_1 + //SEG13 main::@1_1 + b1_1: + //SEG14 [7] *((byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta $28*1+screen+$27 + //SEG15 [8] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38+(byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$26+$28*1 + jmp breturn + //SEG16 main::@return + breturn: + //SEG17 [9] return + rts +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b1_1 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction lda #0 +Removing instruction lda #0 +Succesful ASM optimization Pass5UnnecesaryLoadElimination +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 b1: +Removing instruction b1_1: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction lda #0 +Succesful ASM optimization Pass5UnnecesaryLoadElimination +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@1 +(label) main::@1_1 +(label) main::@return +(byte) main::j +(byte*) screen +(const byte*) screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1024 + + + +FINAL ASSEMBLER +Score: 24 + +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .label screen = $400 +//SEG2 @begin +//SEG3 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG4 @1 +//SEG5 [2] call main +//SEG6 [4] phi from @1 to main [phi:@1->main] +//SEG7 [3] phi from @1 to @end [phi:@1->@end] +//SEG8 @end +//SEG9 main +main: { + //SEG10 main::@1 + //SEG11 [5] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + lda #0 + sta screen+$27 + //SEG12 [6] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + sta screen+$26 + //SEG13 main::@1_1 + //SEG14 [7] *((byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1+(const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 39) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + sta $28*1+screen+$27 + //SEG15 [8] *((const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 38+(byte/signed byte/word/signed word/dword/signed dword) 40*(byte/signed byte/word/signed word/dword/signed dword) 1) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 + sta screen+$26+$28*1 + //SEG16 main::@return + //SEG17 [9] return + rts +} + diff --git a/src/test/ref/consolidate-constant-problem.sym b/src/test/ref/consolidate-constant-problem.sym new file mode 100644 index 000000000..0e109074e --- /dev/null +++ b/src/test/ref/consolidate-constant-problem.sym @@ -0,0 +1,11 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@1 +(label) main::@1_1 +(label) main::@return +(byte) main::j +(byte*) screen +(const byte*) screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1024 +