1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-26 18:29:54 +00:00

Fixes optimization problem with post-increment/decrement of calculated pointers. Closes #428

This commit is contained in:
jespergravgaard 2020-04-28 20:13:29 +02:00
parent eed25ff1cd
commit 013159c16d
7 changed files with 623 additions and 0 deletions

View File

@ -6,6 +6,8 @@ import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypeInference;
import java.util.Objects;
/** A constant defined by a binary operator applied to two constants */ /** A constant defined by a binary operator applied to two constants */
public class ConstantBinary implements ConstantValue { public class ConstantBinary implements ConstantValue {
@ -74,4 +76,18 @@ public class ConstantBinary implements ConstantValue {
return toString(null); return toString(null);
} }
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
ConstantBinary that = (ConstantBinary) o;
return left.equals(that.left) &&
operator.equals(that.operator) &&
right.equals(that.right);
}
@Override
public int hashCode() {
return Objects.hash(left, operator, right);
}
} }

View File

@ -165,6 +165,11 @@ public class TestPrograms {
compileAndCompare("examples/conio/nacht-screen.c"); compileAndCompare("examples/conio/nacht-screen.c");
} }
@Test
public void testPostIncrementProblem2() throws IOException, URISyntaxException {
compileAndCompare("post-increment-problem-2.c");
}
@Test @Test
public void testPostIncrementProblem() throws IOException, URISyntaxException { public void testPostIncrementProblem() throws IOException, URISyntaxException {
compileAndCompare("post-increment-problem.c"); compileAndCompare("post-increment-problem.c");

View File

@ -0,0 +1,14 @@
const byte *screen=$0400;
void main() {
word offset=40*10;
for (char x=0;x<254;x++)
incscreen(offset);
}
void incscreen(word ptr) {
--(*(screen+ptr));
(*(screen+ptr+1))--;
++(*(screen+ptr));
(*(screen+ptr+1))++;
}

View File

@ -0,0 +1,32 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label screen = $400
main: {
.label offset = $28*$a
ldx #0
__b1:
// for (char x=0;x<254;x++)
cpx #$fe
bcc __b2
// }
rts
__b2:
// incscreen(offset)
jsr incscreen
// for (char x=0;x<254;x++)
inx
jmp __b1
}
incscreen: {
// --(*(screen+ptr));
dec screen+main.offset
// (*(screen+ptr+1))--;
dec screen+main.offset+1
// ++(*(screen+ptr));
inc screen+main.offset
// (*(screen+ptr+1))++;
inc screen+main.offset+1
// }
rts
}

View File

@ -0,0 +1,39 @@
@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
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::x#2 ← phi( main/(byte) 0 main::@3/(byte) main::x#1 )
[6] if((byte) main::x#2<(byte) $fe) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[7] return
to:@return
main::@2: scope:[main] from main::@1
[8] phi()
[9] call incscreen
to:main::@3
main::@3: scope:[main] from main::@2
[10] (byte) main::x#1 ← ++ (byte) main::x#2
to:main::@1
(void()) incscreen((word) incscreen::ptr)
incscreen: scope:[incscreen] from main::@2
[11] *((const to_nomodify byte*) screen+(const word) main::offset) ← -- *((const to_nomodify byte*) screen+(const word) main::offset)
[12] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← -- *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1)
[13] *((const to_nomodify byte*) screen+(const word) main::offset) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset)
[14] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1)
to:incscreen::@return
incscreen::@return: scope:[incscreen] from incscreen
[15] return
to:@return

View File

@ -0,0 +1,499 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) main()
main: scope:[main] from @1
(byte) main::x#0 ← (byte) 0
to:main::@1
main::@1: scope:[main] from main main::@3
(byte) main::x#2 ← phi( main/(byte) main::x#0 main::@3/(byte) main::x#1 )
(bool~) main::$0 ← (byte) main::x#2 < (number) $fe
if((bool~) main::$0) goto main::@2
to:main::@return
main::@2: scope:[main] from main::@1
(byte) main::x#4 ← phi( main::@1/(byte) main::x#2 )
(word) incscreen::ptr#0 ← (const word) main::offset
call incscreen
to:main::@3
main::@3: scope:[main] from main::@2
(byte) main::x#3 ← phi( main::@2/(byte) main::x#4 )
(byte) main::x#1 ← ++ (byte) main::x#3
to:main::@1
main::@return: scope:[main] from main::@1
return
to:@return
(void()) incscreen((word) incscreen::ptr)
incscreen: scope:[incscreen] from main::@2
(word) incscreen::ptr#1 ← phi( main::@2/(word) incscreen::ptr#0 )
(byte*~) incscreen::$0 ← (const to_nomodify byte*) screen + (word) incscreen::ptr#1
*((byte*~) incscreen::$0) ← -- *((byte*~) incscreen::$0)
(byte*~) incscreen::$9 ← (const to_nomodify byte*) screen + (word) incscreen::ptr#1
(byte*~) incscreen::$10 ← (byte*~) incscreen::$9 + (number) 1
*((byte*~) incscreen::$10) ← -- *((byte*~) incscreen::$10)
(byte*~) incscreen::$11 ← (const to_nomodify byte*) screen + (word) incscreen::ptr#1
*((byte*~) incscreen::$11) ← ++ *((byte*~) incscreen::$11)
(byte*~) incscreen::$20 ← (const to_nomodify byte*) screen + (word) incscreen::ptr#1
(byte*~) incscreen::$21 ← (byte*~) incscreen::$20 + (number) 1
*((byte*~) incscreen::$21) ← ++ *((byte*~) incscreen::$21)
to:incscreen::@return
incscreen::@return: scope:[incscreen] from incscreen
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()) incscreen((word) incscreen::ptr)
(byte*~) incscreen::$0
(byte*~) incscreen::$10
(byte*~) incscreen::$11
(byte*~) incscreen::$20
(byte*~) incscreen::$21
(byte*~) incscreen::$9
(label) incscreen::@return
(word) incscreen::ptr
(word) incscreen::ptr#0
(word) incscreen::ptr#1
(void()) main()
(bool~) main::$0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(const word) main::offset = (word)(number) $28*(number) $a
(byte) main::x
(byte) main::x#0
(byte) main::x#1
(byte) main::x#2
(byte) main::x#3
(byte) main::x#4
(const to_nomodify byte*) screen = (byte*)(number) $400
Adding number conversion cast (unumber) $fe in (bool~) main::$0 ← (byte) main::x#2 < (number) $fe
Adding number conversion cast (unumber) 1 in (byte*~) incscreen::$10 ← (byte*~) incscreen::$9 + (number) 1
Adding number conversion cast (unumber) 1 in (byte*~) incscreen::$21 ← (byte*~) incscreen::$20 + (number) 1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $fe
Simplifying constant integer cast 1
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $fe
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias main::x#2 = main::x#4 main::x#3
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (word) incscreen::ptr#1 (word) incscreen::ptr#0
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) main::$0 [3] if((byte) main::x#2<(byte) $fe) goto main::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::x#0 = 0
Constant (const word) incscreen::ptr#0 = main::offset
Successful SSA optimization Pass2ConstantIdentification
Converting *(pointer+n) to pointer[n] [13] *((byte*~) incscreen::$10) ← -- *((byte*~) incscreen::$10) -- *(incscreen::$9 + 1)
Converting *(pointer+n) to pointer[n] [13] *((byte*~) incscreen::$10) ← -- *((byte*~) incscreen::$9 + (byte) 1) -- *(incscreen::$9 + 1)
Converting *(pointer+n) to pointer[n] [18] *((byte*~) incscreen::$21) ← ++ *((byte*~) incscreen::$21) -- *(incscreen::$20 + 1)
Converting *(pointer+n) to pointer[n] [18] *((byte*~) incscreen::$21) ← ++ *((byte*~) incscreen::$20 + (byte) 1) -- *(incscreen::$20 + 1)
Successful SSA optimization Pass2InlineDerefIdx
Eliminating unused variable (byte*~) incscreen::$10 and assignment [8] (byte*~) incscreen::$10 ← (byte*~) incscreen::$9 + (byte) 1
Eliminating unused variable (byte*~) incscreen::$21 and assignment [13] (byte*~) incscreen::$21 ← (byte*~) incscreen::$20 + (byte) 1
Successful SSA optimization PassNEliminateUnusedVars
Constant right-side identified [5] (byte*~) incscreen::$0 ← (const to_nomodify byte*) screen + (const word) incscreen::ptr#0
Constant right-side identified [7] (byte*~) incscreen::$9 ← (const to_nomodify byte*) screen + (const word) incscreen::ptr#0
Constant right-side identified [9] (byte*~) incscreen::$11 ← (const to_nomodify byte*) screen + (const word) incscreen::ptr#0
Constant right-side identified [11] (byte*~) incscreen::$20 ← (const to_nomodify byte*) screen + (const word) incscreen::ptr#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) incscreen::$0 = screen+incscreen::ptr#0
Constant (const byte*) incscreen::$9 = screen+incscreen::ptr#0
Constant (const byte*) incscreen::$11 = screen+incscreen::ptr#0
Constant (const byte*) incscreen::$20 = screen+incscreen::ptr#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings (const byte) main::x#0
Constant inlined incscreen::$0 = (const to_nomodify byte*) screen+(const word) main::offset
Constant inlined incscreen::$9 = (const to_nomodify byte*) screen+(const word) main::offset
Constant inlined incscreen::$20 = (const to_nomodify byte*) screen+(const word) main::offset
Constant inlined main::x#0 = (byte) 0
Constant inlined incscreen::$11 = (const to_nomodify byte*) screen+(const word) main::offset
Constant inlined incscreen::ptr#0 = (const word) main::offset
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(screen+main::offset+1)
Consolidated array index constant in *(screen+main::offset+1)
Consolidated array index constant in *(screen+main::offset+1)
Consolidated array index constant in *(screen+main::offset+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
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [] to main:2
Calls in [main] to incscreen:10
Created 1 initial phi equivalence classes
Coalesced [12] main::x#5 ← main::x#1
Coalesced down to 1 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
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
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
[4] phi()
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::x#2 ← phi( main/(byte) 0 main::@3/(byte) main::x#1 )
[6] if((byte) main::x#2<(byte) $fe) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[7] return
to:@return
main::@2: scope:[main] from main::@1
[8] phi()
[9] call incscreen
to:main::@3
main::@3: scope:[main] from main::@2
[10] (byte) main::x#1 ← ++ (byte) main::x#2
to:main::@1
(void()) incscreen((word) incscreen::ptr)
incscreen: scope:[incscreen] from main::@2
[11] *((const to_nomodify byte*) screen+(const word) main::offset) ← -- *((const to_nomodify byte*) screen+(const word) main::offset)
[12] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← -- *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1)
[13] *((const to_nomodify byte*) screen+(const word) main::offset) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset)
[14] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1)
to:incscreen::@return
incscreen::@return: scope:[incscreen] from incscreen
[15] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) incscreen((word) incscreen::ptr)
(word) incscreen::ptr
(void()) main()
(byte) main::x
(byte) main::x#1 202.0
(byte) main::x#2 75.75
Initial phi equivalence classes
[ main::x#2 main::x#1 ]
Complete equivalence classes
[ main::x#2 main::x#1 ]
Allocated zp[1]:2 [ main::x#2 main::x#1 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// 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
// [4] phi from @1 to main [phi:@1->main]
main_from___b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label offset = $28*$a
.label x = 2
// [5] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [5] phi (byte) main::x#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta.z x
jmp __b1
// main::@1
__b1:
// [6] if((byte) main::x#2<(byte) $fe) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z x
cmp #$fe
bcc __b2_from___b1
jmp __breturn
// main::@return
__breturn:
// [7] return
rts
// [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
__b2_from___b1:
jmp __b2
// main::@2
__b2:
// [9] call incscreen
jsr incscreen
jmp __b3
// main::@3
__b3:
// [10] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuz1=_inc_vbuz1
inc.z x
// [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
__b1_from___b3:
// [5] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@3->main::@1#0] -- register_copy
jmp __b1
}
// incscreen
incscreen: {
// [11] *((const to_nomodify byte*) screen+(const word) main::offset) ← -- *((const to_nomodify byte*) screen+(const word) main::offset) -- _deref_pbuc1=_dec__deref_pbuc1
dec screen+main.offset
// [12] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← -- *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) -- _deref_pbuc1=_dec__deref_pbuc1
dec screen+main.offset+1
// [13] *((const to_nomodify byte*) screen+(const word) main::offset) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset) -- _deref_pbuc1=_inc__deref_pbuc1
inc screen+main.offset
// [14] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc1
inc screen+main.offset+1
jmp __breturn
// incscreen::@return
__breturn:
// [15] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Potential registers zp[1]:2 [ main::x#2 main::x#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 277.75: zp[1]:2 [ main::x#2 main::x#1 ]
Uplift Scope [incscreen]
Uplift Scope []
Uplifting [main] best 346 combination reg byte x [ main::x#2 main::x#1 ]
Uplifting [incscreen] best 346 combination
Uplifting [] best 346 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// 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
// [4] phi from @1 to main [phi:@1->main]
main_from___b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label offset = $28*$a
// [5] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [5] phi (byte) main::x#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp __b1
// main::@1
__b1:
// [6] if((byte) main::x#2<(byte) $fe) goto main::@2 -- vbuxx_lt_vbuc1_then_la1
cpx #$fe
bcc __b2_from___b1
jmp __breturn
// main::@return
__breturn:
// [7] return
rts
// [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
__b2_from___b1:
jmp __b2
// main::@2
__b2:
// [9] call incscreen
jsr incscreen
jmp __b3
// main::@3
__b3:
// [10] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuxx=_inc_vbuxx
inx
// [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
__b1_from___b3:
// [5] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@3->main::@1#0] -- register_copy
jmp __b1
}
// incscreen
incscreen: {
// [11] *((const to_nomodify byte*) screen+(const word) main::offset) ← -- *((const to_nomodify byte*) screen+(const word) main::offset) -- _deref_pbuc1=_dec__deref_pbuc1
dec screen+main.offset
// [12] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← -- *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) -- _deref_pbuc1=_dec__deref_pbuc1
dec screen+main.offset+1
// [13] *((const to_nomodify byte*) screen+(const word) main::offset) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset) -- _deref_pbuc1=_inc__deref_pbuc1
inc screen+main.offset
// [14] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc1
inc screen+main.offset+1
jmp __breturn
// incscreen::@return
__breturn:
// [15] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b2_from___b1 with __b2
Removing instruction __b1_from___bbegin:
Removing instruction __b1:
Removing instruction main_from___b1:
Removing instruction __bend_from___b1:
Removing instruction __b2_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction __b1_from_main:
Removing instruction __breturn:
Removing instruction __b3:
Removing instruction __b1_from___b3:
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()) incscreen((word) incscreen::ptr)
(label) incscreen::@return
(word) incscreen::ptr
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(const word) main::offset = (word)(number) $28*(number) $a
(byte) main::x
(byte) main::x#1 reg byte x 202.0
(byte) main::x#2 reg byte x 75.75
(const to_nomodify byte*) screen = (byte*) 1024
reg byte x [ main::x#2 main::x#1 ]
FINAL ASSEMBLER
Score: 211
// File Comments
// 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
// [4] phi from @1 to main [phi:@1->main]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label offset = $28*$a
// [5] phi from main to main::@1 [phi:main->main::@1]
// [5] phi (byte) main::x#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
// main::@1
__b1:
// for (char x=0;x<254;x++)
// [6] if((byte) main::x#2<(byte) $fe) goto main::@2 -- vbuxx_lt_vbuc1_then_la1
cpx #$fe
bcc __b2
// main::@return
// }
// [7] return
rts
// [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
// main::@2
__b2:
// incscreen(offset)
// [9] call incscreen
jsr incscreen
// main::@3
// for (char x=0;x<254;x++)
// [10] (byte) main::x#1 ← ++ (byte) main::x#2 -- vbuxx=_inc_vbuxx
inx
// [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
// [5] phi (byte) main::x#2 = (byte) main::x#1 [phi:main::@3->main::@1#0] -- register_copy
jmp __b1
}
// incscreen
incscreen: {
// --(*(screen+ptr));
// [11] *((const to_nomodify byte*) screen+(const word) main::offset) ← -- *((const to_nomodify byte*) screen+(const word) main::offset) -- _deref_pbuc1=_dec__deref_pbuc1
dec screen+main.offset
// (*(screen+ptr+1))--;
// [12] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← -- *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) -- _deref_pbuc1=_dec__deref_pbuc1
dec screen+main.offset+1
// ++(*(screen+ptr));
// [13] *((const to_nomodify byte*) screen+(const word) main::offset) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset) -- _deref_pbuc1=_inc__deref_pbuc1
inc screen+main.offset
// (*(screen+ptr+1))++;
// [14] *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) ← ++ *((const to_nomodify byte*) screen+(const word) main::offset+(byte) 1) -- _deref_pbuc1=_inc__deref_pbuc1
inc screen+main.offset+1
// incscreen::@return
// }
// [15] return
rts
}
// File Data

View File

@ -0,0 +1,18 @@
(label) @1
(label) @begin
(label) @end
(void()) incscreen((word) incscreen::ptr)
(label) incscreen::@return
(word) incscreen::ptr
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(const word) main::offset = (word)(number) $28*(number) $a
(byte) main::x
(byte) main::x#1 reg byte x 202.0
(byte) main::x#2 reg byte x 75.75
(const to_nomodify byte*) screen = (byte*) 1024
reg byte x [ main::x#2 main::x#1 ]