1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added line anim - work in (early) progress.

This commit is contained in:
jespergravgaard 2018-05-08 00:25:33 +02:00
parent 808b60d06a
commit f492173178
12 changed files with 1006 additions and 0 deletions

View File

@ -0,0 +1,4 @@
lda {z1}
sta {c1},x
lda {z1}+1
sta {c1}+1,x

View File

@ -0,0 +1,4 @@
lda {z1}
sta {c1},y
lda {z1}+1
sta {c1}+1,y

View File

@ -0,0 +1,13 @@
lda {c1},x
sta {z1}
lda {c1}+1,x
sta {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1

View File

@ -0,0 +1,13 @@
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1

View File

@ -0,0 +1,8 @@
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1

View File

@ -0,0 +1,12 @@
lda {z2}
asl
sta {z1}
lda {z2}+1
rol
sta {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1

View File

@ -44,6 +44,11 @@ public class TestPrograms {
AsmFragmentTemplateUsages.logUsages(log, false, false, false, false, false, false);
}
@Test
public void testLineAnim() throws IOException, URISyntaxException {
compileAndCompare("line-anim");
}
@Test
public void testInlineFunctionLevel2() throws IOException, URISyntaxException {
compileAndCompare("inline-function-level2");

View File

@ -0,0 +1,37 @@
// Animated lines drawn on a single color bitmap
// The number of points
const byte SIZE = 4;
// The coordinates of the lines to animate
word[4] x_start = { 10, 20, 30, 30 };
byte[4] y_start = { 10, 10, 10, 20 };
word[4] x_end = { 20, 10, 20, 20 };
byte[4] y_end = { 20, 20, 10, 20 };
// Current x position fixed point [12.4]
word[4] x_cur;
// Current y position fixed point [12.4]
word[4] y_cur;
// X position addition per frame s[3.4]
signed byte[4] x_add;
// Y position addition per frame s[3.4]
signed byte[4] y_add;
// Frame delay (counted down to 0)
byte[4] delay;
// Frame number (counted down to 0)
byte[4] frame;
void main() {
for( byte i=0; i!=8; i+=2) {
init(i);
}
}
void init(byte point_idx) {
x_cur[point_idx] = x_start[point_idx]<<4;
y_cur[point_idx] = ((word)y_start[point_idx>>1])<<4;
}

View File

@ -0,0 +1,59 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
jsr main
main: {
ldx #0
b1:
jsr init
inx
inx
cpx #8
bne b1
rts
}
init: {
.label _0 = 2
.label _2 = 2
.label _3 = 2
lda x_start,x
sta _0
lda x_start+1,x
sta _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
lda _0
sta x_cur,x
lda _0+1
sta x_cur+1,x
txa
lsr
tay
lda y_start,y
sta _2
lda #0
sta _2+1
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
lda _3
sta y_cur,x
lda _3+1
sta y_cur+1,x
rts
}
x_start: .word $a, $14, $1e, $1e
y_start: .byte $a, $a, $a, $14
x_cur: .fill 8, 0
y_cur: .fill 8, 0

View File

@ -0,0 +1,35 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@2
@2: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main [ ] ( )
to:@end
@end: scope:[] from @2
[3] phi() [ ] ( )
main: scope:[main] from @2
[4] phi() [ ] ( main:2 [ ] )
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@3/(byte) main::i#1 ) [ main::i#2 ] ( main:2 [ main::i#2 ] )
[6] (byte) init::point_idx#0 ← (byte) main::i#2 [ main::i#2 init::point_idx#0 ] ( main:2 [ main::i#2 init::point_idx#0 ] )
[7] call init [ main::i#2 ] ( main:2 [ main::i#2 ] )
to:main::@3
main::@3: scope:[main] from main::@1
[8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#1 ] ( main:2 [ main::i#1 ] )
[9] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 8) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] )
to:main::@return
main::@return: scope:[main] from main::@3
[10] return [ ] ( main:2 [ ] )
to:@return
init: scope:[init] from main::@1
[11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] )
[12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] )
[13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] )
[14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] )
[15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] )
[16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] )
to:init::@return
init::@return: scope:[init] from init
[17] return [ ] ( main:2::init:7 [ main::i#2 ] )
to:@return

View File

@ -0,0 +1,785 @@
PARSING src/test/java/dk/camelot64/kickc/test/kc/line-anim.kc
// Animated lines drawn on a single color bitmap
// The number of points
const byte SIZE = 4;
// The coordinates of the lines to animate
word[4] x_start = { 10, 20, 30, 30 };
byte[4] y_start = { 10, 10, 10, 20 };
word[4] x_end = { 20, 10, 20, 20 };
byte[4] y_end = { 20, 20, 10, 20 };
// Current x position fixed point [12.4]
word[4] x_cur;
// Current y position fixed point [12.4]
word[4] y_cur;
// X position addition per frame s[3.4]
signed byte[4] x_add;
// Y position addition per frame s[3.4]
signed byte[4] y_add;
// Frame delay (counted down to 0)
byte[4] delay;
// Frame number (counted down to 0)
byte[4] frame;
void main() {
for( byte i=0; i!=8; i+=2) {
init(i);
}
}
void init(byte point_idx) {
x_cur[point_idx] = x_start[point_idx]<<4;
y_cur[point_idx] = ((word)y_start[point_idx>>1])<<4;
}
SYMBOLS
(label) @1
(label) @2
(label) @begin
(label) @end
(byte) SIZE
(byte[4]) delay
(byte[4]) frame
(void()) init((byte) init::point_idx)
(word~) init::$0
(byte~) init::$1
(word~) init::$2
(word~) init::$3
(label) init::@return
(byte) init::point_idx
(void()) main()
(void~) main::$0
(bool~) main::$1
(label) main::@1
(label) main::@2
(label) main::@return
(byte) main::i
(signed byte[4]) x_add
(word[4]) x_cur
(word[4]) x_end
(word[4]) x_start
(signed byte[4]) y_add
(word[4]) y_cur
(byte[4]) y_end
(byte[4]) y_start
INITIAL CONTROL FLOW GRAPH
@begin: scope:[] from
(byte) SIZE ← (byte/signed byte/word/signed word/dword/signed dword) 4
(word[4]) x_start ← { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 30, (byte/signed byte/word/signed word/dword/signed dword) 30 }
(byte[4]) y_start ← { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20 }
(word[4]) x_end ← { (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 20 }
(byte[4]) y_end ← { (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20 }
(word[4]) x_cur ← { fill( 4, 0) }
(word[4]) y_cur ← { fill( 4, 0) }
(signed byte[4]) x_add ← { fill( 4, 0) }
(signed byte[4]) y_add ← { fill( 4, 0) }
(byte[4]) delay ← { fill( 4, 0) }
(byte[4]) frame ← { fill( 4, 0) }
to:@1
main: scope:[main] from
(byte) main::i ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@1
(void~) main::$0 ← call init (byte) main::i
(byte) main::i ← (byte) main::i + (byte/signed byte/word/signed word/dword/signed dword) 2
(bool~) main::$1 ← (byte) main::i != (byte/signed byte/word/signed word/dword/signed dword) 8
if((bool~) main::$1) goto main::@1
to:main::@2
main::@2: scope:[main] from main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
@1: scope:[] from @begin
to:@2
init: scope:[init] from
(word~) init::$0 ← *((word[4]) x_start + (byte) init::point_idx) << (byte/signed byte/word/signed word/dword/signed dword) 4
*((word[4]) x_cur + (byte) init::point_idx) ← (word~) init::$0
(byte~) init::$1 ← (byte) init::point_idx >> (byte/signed byte/word/signed word/dword/signed dword) 1
(word~) init::$2 ← ((word)) *((byte[4]) y_start + (byte~) init::$1)
(word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4
*((word[4]) y_cur + (byte) init::point_idx) ← (word~) init::$3
to:init::@return
init::@return: scope:[init] from init
return
to:@return
@2: scope:[] from @1
call main
to:@end
@end: scope:[] from @2
Eliminating unused variable (byte) SIZE and assignment [0] (byte) SIZE ← (byte/signed byte/word/signed word/dword/signed dword) 4
Eliminating unused variable (word[4]) x_end and assignment [3] (word[4]) x_end ← { (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 20 }
Eliminating unused variable (byte[4]) y_end and assignment [4] (byte[4]) y_end ← { (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20 }
Eliminating unused variable (signed byte[4]) x_add and assignment [7] (signed byte[4]) x_add ← { fill( 4, 0) }
Eliminating unused variable (signed byte[4]) y_add and assignment [8] (signed byte[4]) y_add ← { fill( 4, 0) }
Eliminating unused variable (byte[4]) delay and assignment [9] (byte[4]) delay ← { fill( 4, 0) }
Eliminating unused variable (byte[4]) frame and assignment [10] (byte[4]) frame ← { fill( 4, 0) }
Eliminating unused variable - keeping the call (void~) main::$0
Removing empty block main::@2
Removing empty block @1
PROCEDURE MODIFY VARIABLE ANALYSIS
Completing Phi functions...
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
@begin: scope:[] from
(word[4]) x_start#0 ← { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 30, (byte/signed byte/word/signed word/dword/signed dword) 30 }
(byte[4]) y_start#0 ← { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20 }
(word[4]) x_cur#0 ← { fill( 4, 0) }
(word[4]) y_cur#0 ← { fill( 4, 0) }
to:@2
main: scope:[main] from @2
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:main::@1
main::@1: scope:[main] from main main::@3
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 )
(byte) init::point_idx#0 ← (byte) main::i#2
call init
to:main::@3
main::@3: scope:[main] from main::@1
(byte) main::i#3 ← phi( main::@1/(byte) main::i#2 )
(byte) main::i#1 ← (byte) main::i#3 + (byte/signed byte/word/signed word/dword/signed dword) 2
(bool~) main::$1 ← (byte) main::i#1 != (byte/signed byte/word/signed word/dword/signed dword) 8
if((bool~) main::$1) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
return
to:@return
init: scope:[init] from main::@1
(byte) init::point_idx#1 ← phi( main::@1/(byte) init::point_idx#0 )
(word~) init::$0 ← *((word[4]) x_start#0 + (byte) init::point_idx#1) << (byte/signed byte/word/signed word/dword/signed dword) 4
*((word[4]) x_cur#0 + (byte) init::point_idx#1) ← (word~) init::$0
(byte~) init::$1 ← (byte) init::point_idx#1 >> (byte/signed byte/word/signed word/dword/signed dword) 1
(word~) init::$2 ← ((word)) *((byte[4]) y_start#0 + (byte~) init::$1)
(word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4
*((word[4]) y_cur#0 + (byte) init::point_idx#1) ← (word~) init::$3
to:init::@return
init::@return: scope:[init] from init
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()) init((byte) init::point_idx)
(word~) init::$0
(byte~) init::$1
(word~) init::$2
(word~) init::$3
(label) init::@return
(byte) init::point_idx
(byte) init::point_idx#0
(byte) init::point_idx#1
(void()) main()
(bool~) main::$1
(label) main::@1
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
(byte) main::i#3
(word[4]) x_cur
(word[4]) x_cur#0
(word[4]) x_start
(word[4]) x_start#0
(word[4]) y_cur
(word[4]) y_cur#0
(byte[4]) y_start
(byte[4]) y_start#0
OPTIMIZING CONTROL FLOW GRAPH
Culled Empty Block (label) @3
Succesful SSA optimization Pass2CullEmptyBlocks
Not aliassing across scopes: init::point_idx#0 main::i#2
Not aliassing across scopes: init::point_idx#1 init::point_idx#0
Alias (byte) main::i#2 = (byte) main::i#3
Succesful SSA optimization Pass2AliasElimination
Not aliassing across scopes: init::point_idx#0 main::i#2
Not aliassing across scopes: init::point_idx#1 init::point_idx#0
Redundant Phi (byte) init::point_idx#1 (byte) init::point_idx#0
Succesful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) main::$1 if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 8) goto main::@1
Succesful SSA optimization Pass2ConditionalJumpSimplification
Constant (const word[4]) x_start#0 = { 10, 20, 30, 30 }
Constant (const byte[4]) y_start#0 = { 10, 10, 10, 20 }
Constant (const word[4]) x_cur#0 = { fill( 4, 0) }
Constant (const word[4]) y_cur#0 = { fill( 4, 0) }
Constant (const byte) main::i#0 = 0
Succesful SSA optimization Pass2ConstantIdentification
Not aliassing across scopes: init::point_idx#0 main::i#2
OPTIMIZING CONTROL FLOW GRAPH
Inlining constant with var siblings (const byte) main::i#0
Inlining constant with var siblings (const byte) main::i#0
Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Succesful SSA optimization Pass2ConstantInlining
Block Sequence Planned @begin @2 @end main main::@1 main::@3 main::@return init init::@return
Added new block during phi lifting main::@4(between main::@3 and main::@1)
Block Sequence Planned @begin @2 @end main main::@1 main::@3 main::@return main::@4 init init::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
CALL GRAPH
Calls in [] to main:2
Calls in [main] to init:7
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Created 1 initial phi equivalence classes
Coalesced [11] main::i#4 ← main::i#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) main::@4
Block Sequence Planned @begin @2 @end main main::@1 main::@3 main::@return init init::@return
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi() [ ] ( )
to:@2
@2: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main [ ] ( )
to:@end
@end: scope:[] from @2
[3] phi() [ ] ( )
main: scope:[main] from @2
[4] phi() [ ] ( main:2 [ ] )
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@3/(byte) main::i#1 ) [ main::i#2 ] ( main:2 [ main::i#2 ] )
[6] (byte) init::point_idx#0 ← (byte) main::i#2 [ main::i#2 init::point_idx#0 ] ( main:2 [ main::i#2 init::point_idx#0 ] )
[7] call init [ main::i#2 ] ( main:2 [ main::i#2 ] )
to:main::@3
main::@3: scope:[main] from main::@1
[8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#1 ] ( main:2 [ main::i#1 ] )
[9] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 8) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] )
to:main::@return
main::@return: scope:[main] from main::@3
[10] return [ ] ( main:2 [ ] )
to:@return
init: scope:[init] from main::@1
[11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] )
[12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] )
[13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] )
[14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] )
[15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] )
[16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] )
to:init::@return
init::@return: scope:[init] from init
[17] return [ ] ( main:2::init:7 [ main::i#2 ] )
to:@return
DOMINATORS
@begin dominated by @begin
@2 dominated by @2 @begin
@end dominated by @2 @begin @end
main dominated by @2 @begin main
main::@1 dominated by @2 @begin main::@1 main
main::@3 dominated by @2 @begin main::@1 main main::@3
main::@return dominated by main::@return @2 @begin main::@1 main main::@3
init dominated by init @2 @begin main::@1 main
init::@return dominated by init @2 @begin main::@1 init::@return main
NATURAL LOOPS
Found back edge: Loop head: main::@1 tails: main::@3 blocks: null
Populated: Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@1
Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@1
NATURAL LOOPS WITH DEPTH
Found 0 loops in scope []
Found 1 loops in scope [main]
Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@1
Found 0 loops in scope [init]
Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@1 depth: 1
VARIABLE REGISTER WEIGHTS
(void()) init((byte) init::point_idx)
(word~) init::$0 4.0
(byte~) init::$1 4.0
(word~) init::$2 4.0
(word~) init::$3 4.0
(byte) init::point_idx
(byte) init::point_idx#0 3.166666666666667
(void()) main()
(byte) main::i
(byte) main::i#1 16.5
(byte) main::i#2 11.0
(word[4]) x_cur
(word[4]) x_start
(word[4]) y_cur
(byte[4]) y_start
Initial phi equivalence classes
[ main::i#2 main::i#1 ]
Added variable init::point_idx#0 to zero page equivalence class [ init::point_idx#0 ]
Added variable init::$0 to zero page equivalence class [ init::$0 ]
Added variable init::$1 to zero page equivalence class [ init::$1 ]
Added variable init::$2 to zero page equivalence class [ init::$2 ]
Added variable init::$3 to zero page equivalence class [ init::$3 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ init::point_idx#0 ]
[ init::$0 ]
[ init::$1 ]
[ init::$2 ]
[ init::$3 ]
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Allocated zp ZP_BYTE:3 [ init::point_idx#0 ]
Allocated zp ZP_WORD:4 [ init::$0 ]
Allocated zp ZP_BYTE:6 [ init::$1 ]
Allocated zp ZP_WORD:7 [ init::$2 ]
Allocated zp ZP_WORD:9 [ init::$3 ]
INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
jmp b2
//SEG4 @2
b2:
//SEG5 [2] call main [ ] ( )
//SEG6 [4] phi from @2 to main [phi:@2->main]
main_from_b2:
jsr main
//SEG7 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG8 @end
bend:
//SEG9 main
main: {
.label i = 2
//SEG10 [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta i
jmp b1
//SEG12 [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
b1_from_b3:
//SEG13 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@3->main::@1#0] -- register_copy
jmp b1
//SEG14 main::@1
b1:
//SEG15 [6] (byte) init::point_idx#0 ← (byte) main::i#2 [ main::i#2 init::point_idx#0 ] ( main:2 [ main::i#2 init::point_idx#0 ] ) -- vbuz1=vbuz2
lda i
sta init.point_idx
//SEG16 [7] call init [ main::i#2 ] ( main:2 [ main::i#2 ] )
jsr init
jmp b3
//SEG17 main::@3
b3:
//SEG18 [8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuz1=vbuz1_plus_2
lda i
clc
adc #2
sta i
//SEG19 [9] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 8) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuz1_neq_vbuc1_then_la1
lda i
cmp #8
bne b1_from_b3
jmp breturn
//SEG20 main::@return
breturn:
//SEG21 [10] return [ ] ( main:2 [ ] )
rts
}
//SEG22 init
init: {
.label _0 = 4
.label _1 = 6
.label _2 = 7
.label _3 = 9
.label point_idx = 3
//SEG23 [11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] ) -- vwuz1=pwuc1_derefidx_vbuz2_rol_4
ldy point_idx
lda x_start,y
sta _0
lda x_start+1,y
sta _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
//SEG24 [12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] ) -- pwuc1_derefidx_vbuz1=vwuz2
ldy point_idx
lda _0
sta x_cur,y
lda _0+1
sta x_cur+1,y
//SEG25 [13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] ) -- vbuz1=vbuz2_ror_1
lda point_idx
lsr
sta _1
//SEG26 [14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] ) -- vwuz1=_word_pbuc1_derefidx_vbuz2
ldy _1
lda y_start,y
sta _2
lda #0
sta _2+1
//SEG27 [15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] ) -- vwuz1=vwuz2_rol_4
lda _2
asl
sta _3
lda _2+1
rol
sta _3+1
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
//SEG28 [16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] ) -- pwuc1_derefidx_vbuz1=vwuz2
ldy point_idx
lda _3
sta y_cur,y
lda _3+1
sta y_cur+1,y
jmp breturn
//SEG29 init::@return
breturn:
//SEG30 [17] return [ ] ( main:2::init:7 [ main::i#2 ] )
rts
}
x_start: .word $a, $14, $1e, $1e
y_start: .byte $a, $a, $a, $14
x_cur: .fill 8, 0
y_cur: .fill 8, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ init::point_idx#0 ]
Statement [12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] ) always clobbers reg byte a
Statement [13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] ) always clobbers reg byte a
Statement [14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] ) always clobbers reg byte a
Statement [15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] ) always clobbers reg byte a
Statement [16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] ) always clobbers reg byte a
Statement [11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] ) always clobbers reg byte a
Statement [12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] ) always clobbers reg byte a
Statement [13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] ) always clobbers reg byte a
Statement [14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] ) always clobbers reg byte a
Statement [15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] ) always clobbers reg byte a
Statement [16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:3 [ init::point_idx#0 ] : zp ZP_BYTE:3 , reg byte x , reg byte y ,
Potential registers zp ZP_WORD:4 [ init::$0 ] : zp ZP_WORD:4 ,
Potential registers zp ZP_BYTE:6 [ init::$1 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_WORD:7 [ init::$2 ] : zp ZP_WORD:7 ,
Potential registers zp ZP_WORD:9 [ init::$3 ] : zp ZP_WORD:9 ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Uplift Scope [init] 4: zp ZP_WORD:4 [ init::$0 ] 4: zp ZP_BYTE:6 [ init::$1 ] 4: zp ZP_WORD:7 [ init::$2 ] 4: zp ZP_WORD:9 [ init::$3 ] 3.17: zp ZP_BYTE:3 [ init::point_idx#0 ]
Uplift Scope []
Uplifting [main] best 507 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [init] best 463 combination zp ZP_WORD:4 [ init::$0 ] reg byte a [ init::$1 ] zp ZP_WORD:7 [ init::$2 ] zp ZP_WORD:9 [ init::$3 ] reg byte x [ init::point_idx#0 ]
Uplifting [] best 463 combination
Coalescing zero page register with common assignment [ zp ZP_WORD:7 [ init::$2 ] ] with [ zp ZP_WORD:9 [ init::$3 ] ] - score: 1
Coalescing zero page register [ zp ZP_WORD:4 [ init::$0 ] ] with [ zp ZP_WORD:7 [ init::$2 init::$3 ] ]
Allocated (was zp ZP_WORD:4) zp ZP_WORD:2 [ init::$0 init::$2 init::$3 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
jmp b2
//SEG4 @2
b2:
//SEG5 [2] call main [ ] ( )
//SEG6 [4] phi from @2 to main [phi:@2->main]
main_from_b2:
jsr main
//SEG7 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
jmp bend
//SEG8 @end
bend:
//SEG9 main
main: {
//SEG10 [5] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
//SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp b1
//SEG12 [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
b1_from_b3:
//SEG13 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@3->main::@1#0] -- register_copy
jmp b1
//SEG14 main::@1
b1:
//SEG15 [6] (byte) init::point_idx#0 ← (byte) main::i#2 [ main::i#2 init::point_idx#0 ] ( main:2 [ main::i#2 init::point_idx#0 ] )
// (byte) init::point_idx#0 = (byte) main::i#2 // register copy reg byte x
//SEG16 [7] call init [ main::i#2 ] ( main:2 [ main::i#2 ] )
jsr init
jmp b3
//SEG17 main::@3
b3:
//SEG18 [8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx=vbuxx_plus_2
inx
inx
//SEG19 [9] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 8) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx_neq_vbuc1_then_la1
cpx #8
bne b1_from_b3
jmp breturn
//SEG20 main::@return
breturn:
//SEG21 [10] return [ ] ( main:2 [ ] )
rts
}
//SEG22 init
init: {
.label _0 = 2
.label _2 = 2
.label _3 = 2
//SEG23 [11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] ) -- vwuz1=pwuc1_derefidx_vbuxx_rol_4
lda x_start,x
sta _0
lda x_start+1,x
sta _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
//SEG24 [12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] ) -- pwuc1_derefidx_vbuxx=vwuz1
lda _0
sta x_cur,x
lda _0+1
sta x_cur+1,x
//SEG25 [13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] ) -- vbuaa=vbuxx_ror_1
txa
lsr
//SEG26 [14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] ) -- vwuz1=_word_pbuc1_derefidx_vbuaa
tay
lda y_start,y
sta _2
lda #0
sta _2+1
//SEG27 [15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] ) -- vwuz1=vwuz1_rol_4
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
//SEG28 [16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] ) -- pwuc1_derefidx_vbuxx=vwuz1
lda _3
sta y_cur,x
lda _3+1
sta y_cur+1,x
jmp breturn
//SEG29 init::@return
breturn:
//SEG30 [17] return [ ] ( main:2::init:7 [ main::i#2 ] )
rts
}
x_start: .word $a, $14, $1e, $1e
y_start: .byte $a, $a, $a, $14
x_cur: .fill 8, 0
y_cur: .fill 8, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b2
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp b3
Removing instruction jmp breturn
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b3 with b1
Removing instruction bbegin:
Removing instruction b2_from_bbegin:
Removing instruction main_from_b2:
Removing instruction bend_from_b2:
Removing instruction b1_from_b3:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b2:
Removing instruction bend:
Removing instruction b1_from_main:
Removing instruction b3:
Removing instruction breturn:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp b1
Succesful ASM optimization Pass5NextJumpElimination
FINAL SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(void()) init((byte) init::point_idx)
(word~) init::$0 $0 zp ZP_WORD:2 4.0
(byte~) init::$1 reg byte a 4.0
(word~) init::$2 $2 zp ZP_WORD:2 4.0
(word~) init::$3 $3 zp ZP_WORD:2 4.0
(label) init::@return
(byte) init::point_idx
(byte) init::point_idx#0 reg byte x 3.166666666666667
(void()) main()
(label) main::@1
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#1 reg byte x 16.5
(byte) main::i#2 reg byte x 11.0
(word[4]) x_cur
(const word[4]) x_cur#0 x_cur = { fill( 4, 0) }
(word[4]) x_start
(const word[4]) x_start#0 x_start = { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 30, (byte/signed byte/word/signed word/dword/signed dword) 30 }
(word[4]) y_cur
(const word[4]) y_cur#0 y_cur = { fill( 4, 0) }
(byte[4]) y_start
(const byte[4]) y_start#0 y_start = { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20 }
reg byte x [ main::i#2 main::i#1 ]
reg byte x [ init::point_idx#0 ]
zp ZP_WORD:2 [ init::$0 init::$2 init::$3 ]
reg byte a [ init::$1 ]
FINAL ASSEMBLER
Score: 328
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
//SEG2 @begin
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
//SEG4 @2
//SEG5 [2] call main [ ] ( )
//SEG6 [4] phi from @2 to main [phi:@2->main]
jsr main
//SEG7 [3] phi from @2 to @end [phi:@2->@end]
//SEG8 @end
//SEG9 main
main: {
//SEG10 [5] phi from main to main::@1 [phi:main->main::@1]
//SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
//SEG12 [5] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
//SEG13 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@3->main::@1#0] -- register_copy
//SEG14 main::@1
b1:
//SEG15 [6] (byte) init::point_idx#0 ← (byte) main::i#2 [ main::i#2 init::point_idx#0 ] ( main:2 [ main::i#2 init::point_idx#0 ] )
// (byte) init::point_idx#0 = (byte) main::i#2 // register copy reg byte x
//SEG16 [7] call init [ main::i#2 ] ( main:2 [ main::i#2 ] )
jsr init
//SEG17 main::@3
//SEG18 [8] (byte) main::i#1 ← (byte) main::i#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx=vbuxx_plus_2
inx
inx
//SEG19 [9] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 8) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx_neq_vbuc1_then_la1
cpx #8
bne b1
//SEG20 main::@return
//SEG21 [10] return [ ] ( main:2 [ ] )
rts
}
//SEG22 init
init: {
.label _0 = 2
.label _2 = 2
.label _3 = 2
//SEG23 [11] (word~) init::$0 ← *((const word[4]) x_start#0 + (byte) init::point_idx#0) << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$0 ] ) -- vwuz1=pwuc1_derefidx_vbuxx_rol_4
lda x_start,x
sta _0
lda x_start+1,x
sta _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
asl _0
rol _0+1
//SEG24 [12] *((const word[4]) x_cur#0 + (byte) init::point_idx#0) ← (word~) init::$0 [ init::point_idx#0 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 ] ) -- pwuc1_derefidx_vbuxx=vwuz1
lda _0
sta x_cur,x
lda _0+1
sta x_cur+1,x
//SEG25 [13] (byte~) init::$1 ← (byte) init::point_idx#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ init::point_idx#0 init::$1 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$1 ] ) -- vbuaa=vbuxx_ror_1
txa
lsr
//SEG26 [14] (word~) init::$2 ← ((word)) *((const byte[4]) y_start#0 + (byte~) init::$1) [ init::point_idx#0 init::$2 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$2 ] ) -- vwuz1=_word_pbuc1_derefidx_vbuaa
tay
lda y_start,y
sta _2
lda #0
sta _2+1
//SEG27 [15] (word~) init::$3 ← (word~) init::$2 << (byte/signed byte/word/signed word/dword/signed dword) 4 [ init::point_idx#0 init::$3 ] ( main:2::init:7 [ main::i#2 init::point_idx#0 init::$3 ] ) -- vwuz1=vwuz1_rol_4
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
asl _3
rol _3+1
//SEG28 [16] *((const word[4]) y_cur#0 + (byte) init::point_idx#0) ← (word~) init::$3 [ ] ( main:2::init:7 [ main::i#2 ] ) -- pwuc1_derefidx_vbuxx=vwuz1
lda _3
sta y_cur,x
lda _3+1
sta y_cur+1,x
//SEG29 init::@return
//SEG30 [17] return [ ] ( main:2::init:7 [ main::i#2 ] )
rts
}
x_start: .word $a, $14, $1e, $1e
y_start: .byte $a, $a, $a, $14
x_cur: .fill 8, 0
y_cur: .fill 8, 0

View File

@ -0,0 +1,31 @@
(label) @2
(label) @begin
(label) @end
(void()) init((byte) init::point_idx)
(word~) init::$0 $0 zp ZP_WORD:2 4.0
(byte~) init::$1 reg byte a 4.0
(word~) init::$2 $2 zp ZP_WORD:2 4.0
(word~) init::$3 $3 zp ZP_WORD:2 4.0
(label) init::@return
(byte) init::point_idx
(byte) init::point_idx#0 reg byte x 3.166666666666667
(void()) main()
(label) main::@1
(label) main::@3
(label) main::@return
(byte) main::i
(byte) main::i#1 reg byte x 16.5
(byte) main::i#2 reg byte x 11.0
(word[4]) x_cur
(const word[4]) x_cur#0 x_cur = { fill( 4, 0) }
(word[4]) x_start
(const word[4]) x_start#0 x_start = { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20, (byte/signed byte/word/signed word/dword/signed dword) 30, (byte/signed byte/word/signed word/dword/signed dword) 30 }
(word[4]) y_cur
(const word[4]) y_cur#0 y_cur = { fill( 4, 0) }
(byte[4]) y_start
(const byte[4]) y_start#0 y_start = { (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 10, (byte/signed byte/word/signed word/dword/signed dword) 20 }
reg byte x [ main::i#2 main::i#1 ]
reg byte x [ init::point_idx#0 ]
zp ZP_WORD:2 [ init::$0 init::$2 init::$3 ]
reg byte a [ init::$1 ]