mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 15:29:10 +00:00
parent
b319398702
commit
50c8175b30
@ -80,12 +80,10 @@ public class TestPrograms {
|
|||||||
assertError("pointer-void-err-0", "Void pointer math not allowed.");
|
assertError("pointer-void-err-0", "Void pointer math not allowed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
@Test
|
@Test
|
||||||
public void testPointerVoid3() throws IOException, URISyntaxException {
|
public void testPointerVoid3() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("pointer-void-3");
|
compileAndCompare("pointer-void-3");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPointerVoid2() throws IOException, URISyntaxException {
|
public void testPointerVoid2() throws IOException, URISyntaxException {
|
||||||
@ -749,6 +747,11 @@ public class TestPrograms {
|
|||||||
compileAndCompare("word-pointer-math");
|
compileAndCompare("word-pointer-math");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWordPointerMath1() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("word-pointer-math-1");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWordPointerMath0() throws IOException, URISyntaxException {
|
public void testWordPointerMath0() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("word-pointer-math-0");
|
compileAndCompare("word-pointer-math-0");
|
||||||
|
@ -1,24 +1,21 @@
|
|||||||
// Test void pointer - issues when assigning returns from malloc()
|
// Test void pointer - issues when assigning returns from malloc()
|
||||||
|
|
||||||
void main() {
|
|
||||||
byte* buf1 = malloc(64);
|
|
||||||
byte* buf2 = malloc(64);
|
|
||||||
|
|
||||||
|
const byte* SCREEN = 0x0400;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
byte* buf1 = malloc();
|
||||||
|
byte* buf2 = malloc();
|
||||||
*buf1 = 'a';
|
*buf1 = 'a';
|
||||||
*buf2 = 'b';
|
*buf2 = 'b';
|
||||||
|
|
||||||
const byte* SCREEN = 0x0400;
|
|
||||||
SCREEN[0] = *buf1;
|
SCREEN[0] = *buf1;
|
||||||
SCREEN[1] = *buf2;
|
SCREEN[1] = *buf2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* HEAP_START = 0xc000;
|
|
||||||
|
|
||||||
unsigned char* heap_head = HEAP_START;
|
byte* heap_head = 0xc000;
|
||||||
|
|
||||||
void* malloc(unsigned int size) {
|
void* malloc() {
|
||||||
void* mem = heap_head;
|
heap_head++;
|
||||||
heap_head+= size;
|
return heap_head;
|
||||||
return mem;
|
|
||||||
}
|
}
|
||||||
|
8
src/test/kc/word-pointer-math-1.kc
Normal file
8
src/test/kc/word-pointer-math-1.kc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Tests word pointer math - subtracting two word pointers
|
||||||
|
void main() {
|
||||||
|
word* w1 = 0x1000;
|
||||||
|
word* w2 = 0x1140;
|
||||||
|
word wd = w2 - w1;
|
||||||
|
const word* SCREEN = 0x0400;
|
||||||
|
*SCREEN = wd;
|
||||||
|
}
|
31
src/test/ref/pointer-void-3.asm
Normal file
31
src/test/ref/pointer-void-3.asm
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Test void pointer - issues when assigning returns from malloc()
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label heap_head = 2
|
||||||
|
main: {
|
||||||
|
lda #<$c000
|
||||||
|
sta heap_head
|
||||||
|
lda #>$c000
|
||||||
|
sta heap_head+1
|
||||||
|
jsr malloc
|
||||||
|
jsr malloc
|
||||||
|
lda #'a'
|
||||||
|
ldy #0
|
||||||
|
sta (heap_head),y
|
||||||
|
lda #'b'
|
||||||
|
sta (heap_head),y
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN+1
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
malloc: {
|
||||||
|
inc heap_head
|
||||||
|
bne !+
|
||||||
|
inc heap_head+1
|
||||||
|
!:
|
||||||
|
rts
|
||||||
|
}
|
33
src/test/ref/pointer-void-3.cfg
Normal file
33
src/test/ref/pointer-void-3.cfg
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
@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()
|
||||||
|
[5] call malloc
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main
|
||||||
|
[6] phi()
|
||||||
|
[7] call malloc
|
||||||
|
to:main::@2
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
[8] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'a'
|
||||||
|
[9] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'b'
|
||||||
|
[10] *((const byte*) SCREEN#0) ← *((byte*)(void*)(byte*) heap_head#11)
|
||||||
|
[11] *((const byte*) SCREEN#0+(byte) 1) ← *((byte*)(void*)(byte*) heap_head#11)
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@2
|
||||||
|
[12] return
|
||||||
|
to:@return
|
||||||
|
malloc: scope:[malloc] from main main::@1
|
||||||
|
[13] (byte*) heap_head#10 ← phi( main/(byte*) 49152 main::@1/(byte*) heap_head#11 )
|
||||||
|
[14] (byte*) heap_head#11 ← ++ (byte*) heap_head#10
|
||||||
|
to:malloc::@return
|
||||||
|
malloc::@return: scope:[malloc] from malloc
|
||||||
|
[15] return
|
||||||
|
to:@return
|
551
src/test/ref/pointer-void-3.log
Normal file
551
src/test/ref/pointer-void-3.log
Normal file
@ -0,0 +1,551 @@
|
|||||||
|
Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (number) $400
|
||||||
|
Adding pointer type conversion cast to void pointer (byte*) main::$0 in (byte*) main::buf1 ← (void*~) main::$0
|
||||||
|
Adding pointer type conversion cast to void pointer (byte*) main::$1 in (byte*) main::buf2 ← (void*~) main::$1
|
||||||
|
Adding pointer type conversion cast (byte*) heap_head in (byte*) heap_head ← (number) $c000
|
||||||
|
Adding void pointer type conversion cast (void*) heap_head in (void*) malloc::return ← (byte*) heap_head
|
||||||
|
Culled Empty Block (label) malloc::@1
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
@begin: scope:[] from
|
||||||
|
(byte*) SCREEN#0 ← ((byte*)) (number) $400
|
||||||
|
to:@1
|
||||||
|
main: scope:[main] from @2
|
||||||
|
(byte*) heap_head#13 ← phi( @2/(byte*) heap_head#14 )
|
||||||
|
call malloc
|
||||||
|
(void*) malloc::return#0 ← (void*) malloc::return#3
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main
|
||||||
|
(byte*) heap_head#7 ← phi( main/(byte*) heap_head#5 )
|
||||||
|
(void*) malloc::return#4 ← phi( main/(void*) malloc::return#0 )
|
||||||
|
(void*~) main::$0 ← (void*) malloc::return#4
|
||||||
|
(byte*) heap_head#0 ← (byte*) heap_head#7
|
||||||
|
(byte*) main::buf1#0 ← ((byte*)) (void*~) main::$0
|
||||||
|
call malloc
|
||||||
|
(void*) malloc::return#1 ← (void*) malloc::return#3
|
||||||
|
to:main::@2
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
(byte*) main::buf1#1 ← phi( main::@1/(byte*) main::buf1#0 )
|
||||||
|
(byte*) heap_head#8 ← phi( main::@1/(byte*) heap_head#5 )
|
||||||
|
(void*) malloc::return#5 ← phi( main::@1/(void*) malloc::return#1 )
|
||||||
|
(void*~) main::$1 ← (void*) malloc::return#5
|
||||||
|
(byte*) heap_head#1 ← (byte*) heap_head#8
|
||||||
|
(byte*) main::buf2#0 ← ((byte*)) (void*~) main::$1
|
||||||
|
*((byte*) main::buf1#1) ← (byte) 'a'
|
||||||
|
*((byte*) main::buf2#0) ← (byte) 'b'
|
||||||
|
*((byte*) SCREEN#0 + (number) 0) ← *((byte*) main::buf1#1)
|
||||||
|
*((byte*) SCREEN#0 + (number) 1) ← *((byte*) main::buf2#0)
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@2
|
||||||
|
(byte*) heap_head#9 ← phi( main::@2/(byte*) heap_head#1 )
|
||||||
|
(byte*) heap_head#2 ← (byte*) heap_head#9
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
(byte*) heap_head#3 ← ((byte*)) (number) $c000
|
||||||
|
to:@2
|
||||||
|
malloc: scope:[malloc] from main main::@1
|
||||||
|
(byte*) heap_head#10 ← phi( main/(byte*) heap_head#13 main::@1/(byte*) heap_head#0 )
|
||||||
|
(byte*) heap_head#4 ← ++ (byte*) heap_head#10
|
||||||
|
(void*) malloc::return#2 ← ((void*)) (byte*) heap_head#4
|
||||||
|
to:malloc::@return
|
||||||
|
malloc::@return: scope:[malloc] from malloc
|
||||||
|
(byte*) heap_head#11 ← phi( malloc/(byte*) heap_head#4 )
|
||||||
|
(void*) malloc::return#6 ← phi( malloc/(void*) malloc::return#2 )
|
||||||
|
(void*) malloc::return#3 ← (void*) malloc::return#6
|
||||||
|
(byte*) heap_head#5 ← (byte*) heap_head#11
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
@2: scope:[] from @1
|
||||||
|
(byte*) heap_head#14 ← phi( @1/(byte*) heap_head#3 )
|
||||||
|
call main
|
||||||
|
to:@3
|
||||||
|
@3: scope:[] from @2
|
||||||
|
(byte*) heap_head#12 ← phi( @2/(byte*) heap_head#2 )
|
||||||
|
(byte*) heap_head#6 ← (byte*) heap_head#12
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @3
|
||||||
|
|
||||||
|
SYMBOL TABLE SSA
|
||||||
|
(label) @1
|
||||||
|
(label) @2
|
||||||
|
(label) @3
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(byte*) SCREEN
|
||||||
|
(byte*) SCREEN#0
|
||||||
|
(byte*) heap_head
|
||||||
|
(byte*) heap_head#0
|
||||||
|
(byte*) heap_head#1
|
||||||
|
(byte*) heap_head#10
|
||||||
|
(byte*) heap_head#11
|
||||||
|
(byte*) heap_head#12
|
||||||
|
(byte*) heap_head#13
|
||||||
|
(byte*) heap_head#14
|
||||||
|
(byte*) heap_head#2
|
||||||
|
(byte*) heap_head#3
|
||||||
|
(byte*) heap_head#4
|
||||||
|
(byte*) heap_head#5
|
||||||
|
(byte*) heap_head#6
|
||||||
|
(byte*) heap_head#7
|
||||||
|
(byte*) heap_head#8
|
||||||
|
(byte*) heap_head#9
|
||||||
|
(void()) main()
|
||||||
|
(void*~) main::$0
|
||||||
|
(void*~) main::$1
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@return
|
||||||
|
(byte*) main::buf1
|
||||||
|
(byte*) main::buf1#0
|
||||||
|
(byte*) main::buf1#1
|
||||||
|
(byte*) main::buf2
|
||||||
|
(byte*) main::buf2#0
|
||||||
|
(void*()) malloc()
|
||||||
|
(label) malloc::@return
|
||||||
|
(void*) malloc::return
|
||||||
|
(void*) malloc::return#0
|
||||||
|
(void*) malloc::return#1
|
||||||
|
(void*) malloc::return#2
|
||||||
|
(void*) malloc::return#3
|
||||||
|
(void*) malloc::return#4
|
||||||
|
(void*) malloc::return#5
|
||||||
|
(void*) malloc::return#6
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) 0 in *((byte*) SCREEN#0 + (number) 0) ← *((byte*) main::buf1#1)
|
||||||
|
Adding number conversion cast (unumber) 1 in *((byte*) SCREEN#0 + (number) 1) ← *((byte*) main::buf2#0)
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Inlining cast (byte*) SCREEN#0 ← (byte*)(number) $400
|
||||||
|
Inlining cast (byte*) main::buf1#0 ← (byte*)(void*~) main::$0
|
||||||
|
Inlining cast (byte*) main::buf2#0 ← (byte*)(void*~) main::$1
|
||||||
|
Inlining cast (byte*) heap_head#3 ← (byte*)(number) $c000
|
||||||
|
Inlining cast (void*) malloc::return#2 ← (void*)(byte*) heap_head#4
|
||||||
|
Successful SSA optimization Pass2InlineCast
|
||||||
|
Simplifying constant pointer cast (byte*) 1024
|
||||||
|
Simplifying constant integer cast 0
|
||||||
|
Simplifying constant integer cast 1
|
||||||
|
Simplifying constant pointer cast (byte*) 49152
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (byte) 0
|
||||||
|
Finalized unsigned number type (byte) 1
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Alias (void*) malloc::return#0 = (void*) malloc::return#4
|
||||||
|
Alias (byte*) heap_head#0 = (byte*) heap_head#7
|
||||||
|
Alias (void*) malloc::return#1 = (void*) malloc::return#5
|
||||||
|
Alias (byte*) main::buf1#0 = (byte*) main::buf1#1
|
||||||
|
Alias (byte*) heap_head#1 = (byte*) heap_head#8 (byte*) heap_head#9 (byte*) heap_head#2
|
||||||
|
Alias (void*) malloc::return#2 = (void*) malloc::return#6 (void*) malloc::return#3
|
||||||
|
Alias (byte*) heap_head#11 = (byte*) heap_head#4 (byte*) heap_head#5
|
||||||
|
Alias (byte*) heap_head#14 = (byte*) heap_head#3
|
||||||
|
Alias (byte*) heap_head#12 = (byte*) heap_head#6
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Identical Phi Values (byte*) heap_head#13 (byte*) heap_head#14
|
||||||
|
Identical Phi Values (byte*) heap_head#0 (byte*) heap_head#11
|
||||||
|
Identical Phi Values (byte*) heap_head#1 (byte*) heap_head#11
|
||||||
|
Identical Phi Values (byte*) heap_head#12 (byte*) heap_head#1
|
||||||
|
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||||
|
Constant (const byte*) SCREEN#0 = (byte*) 1024
|
||||||
|
Constant (const byte*) heap_head#14 = (byte*) 49152
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Simplifying expression containing zero SCREEN#0 in [16] *((const byte*) SCREEN#0 + (byte) 0) ← *((byte*) main::buf1#0)
|
||||||
|
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||||
|
Inlining Noop Cast [3] (byte*) main::buf1#0 ← (byte*)(void*~) main::$0 keeping main::buf1#0
|
||||||
|
Inlining Noop Cast [7] (byte*) main::buf2#0 ← (byte*)(void*~) main::$1 keeping main::buf2#0
|
||||||
|
Successful SSA optimization Pass2NopCastInlining
|
||||||
|
Inlining Noop Cast [15] (void*) malloc::return#2 ← (void*)(byte*) heap_head#11 keeping heap_head#11
|
||||||
|
Successful SSA optimization Pass2NopCastInlining
|
||||||
|
Inlining Noop Cast [1] (void*) malloc::return#0 ← (void*)(byte*) heap_head#11 keeping heap_head#11
|
||||||
|
Inlining Noop Cast [5] (void*) malloc::return#1 ← (void*)(byte*) heap_head#11 keeping heap_head#11
|
||||||
|
Successful SSA optimization Pass2NopCastInlining
|
||||||
|
Inlining Noop Cast [2] (void*) main::buf1#0 ← (void*)(byte*) heap_head#11 keeping heap_head#11
|
||||||
|
Inlining Noop Cast [6] (void*) main::buf2#0 ← (void*)(byte*) heap_head#11 keeping heap_head#11
|
||||||
|
Successful SSA optimization Pass2NopCastInlining
|
||||||
|
Inlining constant with var siblings (const byte*) heap_head#14
|
||||||
|
Constant inlined heap_head#14 = (byte*) 49152
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Consolidated array index constant in *(SCREEN#0+1)
|
||||||
|
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||||
|
Adding NOP phi() at start of @begin
|
||||||
|
Adding NOP phi() at start of @1
|
||||||
|
Adding NOP phi() at start of @2
|
||||||
|
Adding NOP phi() at start of @3
|
||||||
|
Adding NOP phi() at start of @end
|
||||||
|
Adding NOP phi() at start of main
|
||||||
|
CALL GRAPH
|
||||||
|
Calls in [] to main:3
|
||||||
|
Calls in [main] to malloc:7 malloc:9
|
||||||
|
|
||||||
|
Created 1 initial phi equivalence classes
|
||||||
|
Coalesced [8] heap_head#15 ← heap_head#11
|
||||||
|
Coalesced down to 1 phi equivalence classes
|
||||||
|
Culled Empty Block (label) @1
|
||||||
|
Culled Empty Block (label) @3
|
||||||
|
Renumbering block @2 to @1
|
||||||
|
Adding NOP phi() at start of @begin
|
||||||
|
Adding NOP phi() at start of @1
|
||||||
|
Adding NOP phi() at start of @end
|
||||||
|
Adding NOP phi() at start of main
|
||||||
|
Adding NOP phi() at start of main::@1
|
||||||
|
|
||||||
|
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()
|
||||||
|
[5] call malloc
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main
|
||||||
|
[6] phi()
|
||||||
|
[7] call malloc
|
||||||
|
to:main::@2
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
[8] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'a'
|
||||||
|
[9] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'b'
|
||||||
|
[10] *((const byte*) SCREEN#0) ← *((byte*)(void*)(byte*) heap_head#11)
|
||||||
|
[11] *((const byte*) SCREEN#0+(byte) 1) ← *((byte*)(void*)(byte*) heap_head#11)
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@2
|
||||||
|
[12] return
|
||||||
|
to:@return
|
||||||
|
malloc: scope:[malloc] from main main::@1
|
||||||
|
[13] (byte*) heap_head#10 ← phi( main/(byte*) 49152 main::@1/(byte*) heap_head#11 )
|
||||||
|
[14] (byte*) heap_head#11 ← ++ (byte*) heap_head#10
|
||||||
|
to:malloc::@return
|
||||||
|
malloc::@return: scope:[malloc] from malloc
|
||||||
|
[15] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
(byte*) SCREEN
|
||||||
|
(byte*) heap_head
|
||||||
|
(byte*) heap_head#10 4.0
|
||||||
|
(byte*) heap_head#11 0.5
|
||||||
|
(void()) main()
|
||||||
|
(byte*) main::buf1
|
||||||
|
(byte*) main::buf2
|
||||||
|
(void*()) malloc()
|
||||||
|
(void*) malloc::return
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
[ heap_head#10 heap_head#11 ]
|
||||||
|
Complete equivalence classes
|
||||||
|
[ heap_head#10 heap_head#11 ]
|
||||||
|
Allocated zp ZP_WORD:2 [ heap_head#10 heap_head#11 ]
|
||||||
|
|
||||||
|
INITIAL ASM
|
||||||
|
//SEG0 File Comments
|
||||||
|
// Test void pointer - issues when assigning returns from malloc()
|
||||||
|
//SEG1 Basic Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(bbegin)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
//SEG2 Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label heap_head = 2
|
||||||
|
//SEG3 @begin
|
||||||
|
bbegin:
|
||||||
|
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
b1_from_bbegin:
|
||||||
|
jmp b1
|
||||||
|
//SEG5 @1
|
||||||
|
b1:
|
||||||
|
//SEG6 [2] call main
|
||||||
|
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||||
|
main_from_b1:
|
||||||
|
jsr main
|
||||||
|
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
bend_from_b1:
|
||||||
|
jmp bend
|
||||||
|
//SEG9 @end
|
||||||
|
bend:
|
||||||
|
//SEG10 main
|
||||||
|
main: {
|
||||||
|
//SEG11 [5] call malloc
|
||||||
|
//SEG12 [13] phi from main to malloc [phi:main->malloc]
|
||||||
|
malloc_from_main:
|
||||||
|
//SEG13 [13] phi (byte*) heap_head#10 = (byte*) 49152 [phi:main->malloc#0] -- pbuz1=pbuc1
|
||||||
|
lda #<$c000
|
||||||
|
sta heap_head
|
||||||
|
lda #>$c000
|
||||||
|
sta heap_head+1
|
||||||
|
jsr malloc
|
||||||
|
//SEG14 [6] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
b1_from_main:
|
||||||
|
jmp b1
|
||||||
|
//SEG15 main::@1
|
||||||
|
b1:
|
||||||
|
//SEG16 [7] call malloc
|
||||||
|
//SEG17 [13] phi from main::@1 to malloc [phi:main::@1->malloc]
|
||||||
|
malloc_from_b1:
|
||||||
|
//SEG18 [13] phi (byte*) heap_head#10 = (byte*) heap_head#11 [phi:main::@1->malloc#0] -- register_copy
|
||||||
|
jsr malloc
|
||||||
|
jmp b2
|
||||||
|
//SEG19 main::@2
|
||||||
|
b2:
|
||||||
|
//SEG20 [8] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'a' -- _deref_pbuz1=vbuc1
|
||||||
|
lda #'a'
|
||||||
|
ldy #0
|
||||||
|
sta (heap_head),y
|
||||||
|
//SEG21 [9] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'b' -- _deref_pbuz1=vbuc1
|
||||||
|
lda #'b'
|
||||||
|
ldy #0
|
||||||
|
sta (heap_head),y
|
||||||
|
//SEG22 [10] *((const byte*) SCREEN#0) ← *((byte*)(void*)(byte*) heap_head#11) -- _deref_pbuc1=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN
|
||||||
|
//SEG23 [11] *((const byte*) SCREEN#0+(byte) 1) ← *((byte*)(void*)(byte*) heap_head#11) -- _deref_pbuc1=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN+1
|
||||||
|
jmp breturn
|
||||||
|
//SEG24 main::@return
|
||||||
|
breturn:
|
||||||
|
//SEG25 [12] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG26 malloc
|
||||||
|
malloc: {
|
||||||
|
//SEG27 [14] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 -- pbuz1=_inc_pbuz1
|
||||||
|
inc heap_head
|
||||||
|
bne !+
|
||||||
|
inc heap_head+1
|
||||||
|
!:
|
||||||
|
jmp breturn
|
||||||
|
//SEG28 malloc::@return
|
||||||
|
breturn:
|
||||||
|
//SEG29 [15] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG30 File Data
|
||||||
|
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [8] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'a' [ heap_head#11 ] ( main:2 [ heap_head#11 ] ) always clobbers reg byte a reg byte y
|
||||||
|
Statement [9] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'b' [ heap_head#11 ] ( main:2 [ heap_head#11 ] ) always clobbers reg byte a reg byte y
|
||||||
|
Statement [10] *((const byte*) SCREEN#0) ← *((byte*)(void*)(byte*) heap_head#11) [ heap_head#11 ] ( main:2 [ heap_head#11 ] ) always clobbers reg byte a reg byte y
|
||||||
|
Statement [11] *((const byte*) SCREEN#0+(byte) 1) ← *((byte*)(void*)(byte*) heap_head#11) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
|
||||||
|
Potential registers zp ZP_WORD:2 [ heap_head#10 heap_head#11 ] : zp ZP_WORD:2 ,
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [] 4.5: zp ZP_WORD:2 [ heap_head#10 heap_head#11 ]
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope [malloc]
|
||||||
|
|
||||||
|
Uplifting [] best 112 combination zp ZP_WORD:2 [ heap_head#10 heap_head#11 ]
|
||||||
|
Uplifting [main] best 112 combination
|
||||||
|
Uplifting [malloc] best 112 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
//SEG0 File Comments
|
||||||
|
// Test void pointer - issues when assigning returns from malloc()
|
||||||
|
//SEG1 Basic Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(bbegin)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
//SEG2 Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label heap_head = 2
|
||||||
|
//SEG3 @begin
|
||||||
|
bbegin:
|
||||||
|
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
b1_from_bbegin:
|
||||||
|
jmp b1
|
||||||
|
//SEG5 @1
|
||||||
|
b1:
|
||||||
|
//SEG6 [2] call main
|
||||||
|
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||||
|
main_from_b1:
|
||||||
|
jsr main
|
||||||
|
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
bend_from_b1:
|
||||||
|
jmp bend
|
||||||
|
//SEG9 @end
|
||||||
|
bend:
|
||||||
|
//SEG10 main
|
||||||
|
main: {
|
||||||
|
//SEG11 [5] call malloc
|
||||||
|
//SEG12 [13] phi from main to malloc [phi:main->malloc]
|
||||||
|
malloc_from_main:
|
||||||
|
//SEG13 [13] phi (byte*) heap_head#10 = (byte*) 49152 [phi:main->malloc#0] -- pbuz1=pbuc1
|
||||||
|
lda #<$c000
|
||||||
|
sta heap_head
|
||||||
|
lda #>$c000
|
||||||
|
sta heap_head+1
|
||||||
|
jsr malloc
|
||||||
|
//SEG14 [6] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
b1_from_main:
|
||||||
|
jmp b1
|
||||||
|
//SEG15 main::@1
|
||||||
|
b1:
|
||||||
|
//SEG16 [7] call malloc
|
||||||
|
//SEG17 [13] phi from main::@1 to malloc [phi:main::@1->malloc]
|
||||||
|
malloc_from_b1:
|
||||||
|
//SEG18 [13] phi (byte*) heap_head#10 = (byte*) heap_head#11 [phi:main::@1->malloc#0] -- register_copy
|
||||||
|
jsr malloc
|
||||||
|
jmp b2
|
||||||
|
//SEG19 main::@2
|
||||||
|
b2:
|
||||||
|
//SEG20 [8] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'a' -- _deref_pbuz1=vbuc1
|
||||||
|
lda #'a'
|
||||||
|
ldy #0
|
||||||
|
sta (heap_head),y
|
||||||
|
//SEG21 [9] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'b' -- _deref_pbuz1=vbuc1
|
||||||
|
lda #'b'
|
||||||
|
ldy #0
|
||||||
|
sta (heap_head),y
|
||||||
|
//SEG22 [10] *((const byte*) SCREEN#0) ← *((byte*)(void*)(byte*) heap_head#11) -- _deref_pbuc1=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN
|
||||||
|
//SEG23 [11] *((const byte*) SCREEN#0+(byte) 1) ← *((byte*)(void*)(byte*) heap_head#11) -- _deref_pbuc1=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN+1
|
||||||
|
jmp breturn
|
||||||
|
//SEG24 main::@return
|
||||||
|
breturn:
|
||||||
|
//SEG25 [12] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG26 malloc
|
||||||
|
malloc: {
|
||||||
|
//SEG27 [14] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 -- pbuz1=_inc_pbuz1
|
||||||
|
inc heap_head
|
||||||
|
bne !+
|
||||||
|
inc heap_head+1
|
||||||
|
!:
|
||||||
|
jmp breturn
|
||||||
|
//SEG28 malloc::@return
|
||||||
|
breturn:
|
||||||
|
//SEG29 [15] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG30 File Data
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp b1
|
||||||
|
Removing instruction jmp bend
|
||||||
|
Removing instruction jmp b1
|
||||||
|
Removing instruction jmp b2
|
||||||
|
Removing instruction jmp breturn
|
||||||
|
Removing instruction jmp breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction ldy #0
|
||||||
|
Removing instruction ldy #0
|
||||||
|
Removing instruction ldy #0
|
||||||
|
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||||
|
Removing instruction b1_from_bbegin:
|
||||||
|
Removing instruction b1:
|
||||||
|
Removing instruction main_from_b1:
|
||||||
|
Removing instruction bend_from_b1:
|
||||||
|
Removing instruction b1_from_main:
|
||||||
|
Removing instruction malloc_from_b1:
|
||||||
|
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||||
|
Removing instruction bend:
|
||||||
|
Removing instruction malloc_from_main:
|
||||||
|
Removing instruction b1:
|
||||||
|
Removing instruction b2:
|
||||||
|
Removing instruction breturn:
|
||||||
|
Removing instruction breturn:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
Updating BasicUpstart to call main directly
|
||||||
|
Removing instruction jsr main
|
||||||
|
Succesful ASM optimization Pass5SkipBegin
|
||||||
|
Removing instruction bbegin:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
(label) @1
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(byte*) SCREEN
|
||||||
|
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
|
||||||
|
(byte*) heap_head
|
||||||
|
(byte*) heap_head#10 heap_head zp ZP_WORD:2 4.0
|
||||||
|
(byte*) heap_head#11 heap_head zp ZP_WORD:2 0.5
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@return
|
||||||
|
(byte*) main::buf1
|
||||||
|
(byte*) main::buf2
|
||||||
|
(void*()) malloc()
|
||||||
|
(label) malloc::@return
|
||||||
|
(void*) malloc::return
|
||||||
|
|
||||||
|
zp ZP_WORD:2 [ heap_head#10 heap_head#11 ]
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 82
|
||||||
|
|
||||||
|
//SEG0 File Comments
|
||||||
|
// Test void pointer - issues when assigning returns from malloc()
|
||||||
|
//SEG1 Basic Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
//SEG2 Global Constants & labels
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label heap_head = 2
|
||||||
|
//SEG3 @begin
|
||||||
|
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
//SEG5 @1
|
||||||
|
//SEG6 [2] call main
|
||||||
|
//SEG7 [4] phi from @1 to main [phi:@1->main]
|
||||||
|
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
//SEG9 @end
|
||||||
|
//SEG10 main
|
||||||
|
main: {
|
||||||
|
//SEG11 [5] call malloc
|
||||||
|
//SEG12 [13] phi from main to malloc [phi:main->malloc]
|
||||||
|
//SEG13 [13] phi (byte*) heap_head#10 = (byte*) 49152 [phi:main->malloc#0] -- pbuz1=pbuc1
|
||||||
|
lda #<$c000
|
||||||
|
sta heap_head
|
||||||
|
lda #>$c000
|
||||||
|
sta heap_head+1
|
||||||
|
jsr malloc
|
||||||
|
//SEG14 [6] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
//SEG15 main::@1
|
||||||
|
//SEG16 [7] call malloc
|
||||||
|
//SEG17 [13] phi from main::@1 to malloc [phi:main::@1->malloc]
|
||||||
|
//SEG18 [13] phi (byte*) heap_head#10 = (byte*) heap_head#11 [phi:main::@1->malloc#0] -- register_copy
|
||||||
|
jsr malloc
|
||||||
|
//SEG19 main::@2
|
||||||
|
//SEG20 [8] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'a' -- _deref_pbuz1=vbuc1
|
||||||
|
lda #'a'
|
||||||
|
ldy #0
|
||||||
|
sta (heap_head),y
|
||||||
|
//SEG21 [9] *((byte*)(void*)(byte*) heap_head#11) ← (byte) 'b' -- _deref_pbuz1=vbuc1
|
||||||
|
lda #'b'
|
||||||
|
sta (heap_head),y
|
||||||
|
//SEG22 [10] *((const byte*) SCREEN#0) ← *((byte*)(void*)(byte*) heap_head#11) -- _deref_pbuc1=_deref_pbuz1
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN
|
||||||
|
//SEG23 [11] *((const byte*) SCREEN#0+(byte) 1) ← *((byte*)(void*)(byte*) heap_head#11) -- _deref_pbuc1=_deref_pbuz1
|
||||||
|
lda (heap_head),y
|
||||||
|
sta SCREEN+1
|
||||||
|
//SEG24 main::@return
|
||||||
|
//SEG25 [12] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG26 malloc
|
||||||
|
malloc: {
|
||||||
|
//SEG27 [14] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 -- pbuz1=_inc_pbuz1
|
||||||
|
inc heap_head
|
||||||
|
bne !+
|
||||||
|
inc heap_head+1
|
||||||
|
!:
|
||||||
|
//SEG28 malloc::@return
|
||||||
|
//SEG29 [15] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG30 File Data
|
||||||
|
|
19
src/test/ref/pointer-void-3.sym
Normal file
19
src/test/ref/pointer-void-3.sym
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
(label) @1
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(byte*) SCREEN
|
||||||
|
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
|
||||||
|
(byte*) heap_head
|
||||||
|
(byte*) heap_head#10 heap_head zp ZP_WORD:2 4.0
|
||||||
|
(byte*) heap_head#11 heap_head zp ZP_WORD:2 0.5
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@1
|
||||||
|
(label) main::@2
|
||||||
|
(label) main::@return
|
||||||
|
(byte*) main::buf1
|
||||||
|
(byte*) main::buf2
|
||||||
|
(void*()) malloc()
|
||||||
|
(label) malloc::@return
|
||||||
|
(void*) malloc::return
|
||||||
|
|
||||||
|
zp ZP_WORD:2 [ heap_head#10 heap_head#11 ]
|
16
src/test/ref/word-pointer-math-1.asm
Normal file
16
src/test/ref/word-pointer-math-1.asm
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Tests word pointer math - subtracting two word pointers
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
.const SIZEOF_WORD = 2
|
||||||
|
main: {
|
||||||
|
.label w1 = $1000
|
||||||
|
.label w2 = $1140
|
||||||
|
.label SCREEN = $400
|
||||||
|
.const wd = w2-w1*SIZEOF_WORD
|
||||||
|
lda #<wd
|
||||||
|
sta SCREEN
|
||||||
|
lda #>wd
|
||||||
|
sta SCREEN+1
|
||||||
|
rts
|
||||||
|
}
|
15
src/test/ref/word-pointer-math-1.cfg
Normal file
15
src/test/ref/word-pointer-math-1.cfg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@begin: scope:[] from
|
||||||
|
[0] phi()
|
||||||
|
to:@1
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
[1] phi()
|
||||||
|
[2] call main
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @1
|
||||||
|
[3] phi()
|
||||||
|
main: scope:[main] from @1
|
||||||
|
[4] *((const word*) main::SCREEN#0) ← (const word) main::wd#0
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
[5] return
|
||||||
|
to:@return
|
278
src/test/ref/word-pointer-math-1.log
Normal file
278
src/test/ref/word-pointer-math-1.log
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
Adding pointer type conversion cast (word*) main::w1 in (word*) main::w1 ← (number) $1000
|
||||||
|
Adding pointer type conversion cast (word*) main::w2 in (word*) main::w2 ← (number) $1140
|
||||||
|
Adding pointer type conversion cast (word*) main::SCREEN in (word*) main::SCREEN ← (number) $400
|
||||||
|
Fixing pointer addition (word~) main::$0 ← (word*) main::w2 - (word*) main::w1
|
||||||
|
Identified constant variable (word*) main::w1
|
||||||
|
Identified constant variable (word*) main::w2
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
@begin: scope:[] from
|
||||||
|
to:@1
|
||||||
|
main: scope:[main] from @1
|
||||||
|
(word*) main::w1#0 ← ((word*)) (number) $1000
|
||||||
|
(word*) main::w2#0 ← ((word*)) (number) $1140
|
||||||
|
(word*~) main::$1 ← (word*) main::w1#0 * (const byte) SIZEOF_WORD
|
||||||
|
(word~) main::$0 ← (word*) main::w2#0 - (word*~) main::$1
|
||||||
|
(word) main::wd#0 ← (word~) main::$0
|
||||||
|
(word*) main::SCREEN#0 ← ((word*)) (number) $400
|
||||||
|
*((word*) main::SCREEN#0) ← (word) main::wd#0
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
call main
|
||||||
|
to:@2
|
||||||
|
@2: scope:[] from @1
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @2
|
||||||
|
|
||||||
|
SYMBOL TABLE SSA
|
||||||
|
(label) @1
|
||||||
|
(label) @2
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(const byte) SIZEOF_WORD = (byte) 2
|
||||||
|
(void()) main()
|
||||||
|
(word~) main::$0
|
||||||
|
(word*~) main::$1
|
||||||
|
(label) main::@return
|
||||||
|
(word*) main::SCREEN
|
||||||
|
(word*) main::SCREEN#0
|
||||||
|
(word*) main::w1
|
||||||
|
(word*) main::w1#0
|
||||||
|
(word*) main::w2
|
||||||
|
(word*) main::w2#0
|
||||||
|
(word) main::wd
|
||||||
|
(word) main::wd#0
|
||||||
|
|
||||||
|
Inlining cast (word*) main::w1#0 ← (word*)(number) $1000
|
||||||
|
Inlining cast (word*) main::w2#0 ← (word*)(number) $1140
|
||||||
|
Inlining cast (word*) main::SCREEN#0 ← (word*)(number) $400
|
||||||
|
Successful SSA optimization Pass2InlineCast
|
||||||
|
Simplifying constant pointer cast (word*) 4096
|
||||||
|
Simplifying constant pointer cast (word*) 4416
|
||||||
|
Simplifying constant pointer cast (word*) 1024
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Alias (word) main::wd#0 = (word~) main::$0
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Constant (const word*) main::w1#0 = (word*) 4096
|
||||||
|
Constant (const word*) main::w2#0 = (word*) 4416
|
||||||
|
Constant (const word*) main::SCREEN#0 = (word*) 1024
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant right-side identified [0] (word*~) main::$1 ← (const word*) main::w1#0 * (const byte) SIZEOF_WORD
|
||||||
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||||
|
Constant (const word*) main::$1 = main::w1#0*SIZEOF_WORD
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant right-side identified [0] (word) main::wd#0 ← (const word*) main::w2#0 - (const word*) main::$1
|
||||||
|
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||||
|
Constant (const word) main::wd#0 = main::w2#0-main::$1
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Constant inlined main::$1 = (const word*) main::w1#0*(const byte) SIZEOF_WORD
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
Adding NOP phi() at start of @begin
|
||||||
|
Adding NOP phi() at start of @1
|
||||||
|
Adding NOP phi() at start of @2
|
||||||
|
Adding NOP phi() at start of @end
|
||||||
|
CALL GRAPH
|
||||||
|
Calls in [] to main:2
|
||||||
|
|
||||||
|
Created 0 initial phi equivalence classes
|
||||||
|
Coalesced down to 0 phi equivalence classes
|
||||||
|
Culled Empty Block (label) @2
|
||||||
|
Adding NOP phi() at start of @begin
|
||||||
|
Adding NOP phi() at start of @1
|
||||||
|
Adding NOP phi() at start of @end
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
@begin: scope:[] from
|
||||||
|
[0] phi()
|
||||||
|
to:@1
|
||||||
|
@1: scope:[] from @begin
|
||||||
|
[1] phi()
|
||||||
|
[2] call main
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @1
|
||||||
|
[3] phi()
|
||||||
|
main: scope:[main] from @1
|
||||||
|
[4] *((const word*) main::SCREEN#0) ← (const word) main::wd#0
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main
|
||||||
|
[5] return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
(void()) main()
|
||||||
|
(word*) main::SCREEN
|
||||||
|
(word*) main::w1
|
||||||
|
(word*) main::w2
|
||||||
|
(word) main::wd
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
Complete equivalence classes
|
||||||
|
|
||||||
|
INITIAL ASM
|
||||||
|
//SEG0 File Comments
|
||||||
|
// Tests word pointer math - subtracting two word pointers
|
||||||
|
//SEG1 Basic Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(bbegin)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
//SEG2 Global Constants & labels
|
||||||
|
.const SIZEOF_WORD = 2
|
||||||
|
//SEG3 @begin
|
||||||
|
bbegin:
|
||||||
|
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
b1_from_bbegin:
|
||||||
|
jmp b1
|
||||||
|
//SEG5 @1
|
||||||
|
b1:
|
||||||
|
//SEG6 [2] call main
|
||||||
|
jsr main
|
||||||
|
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
bend_from_b1:
|
||||||
|
jmp bend
|
||||||
|
//SEG8 @end
|
||||||
|
bend:
|
||||||
|
//SEG9 main
|
||||||
|
main: {
|
||||||
|
.label w1 = $1000
|
||||||
|
.label w2 = $1140
|
||||||
|
.label SCREEN = $400
|
||||||
|
.const wd = w2-w1*SIZEOF_WORD
|
||||||
|
//SEG10 [4] *((const word*) main::SCREEN#0) ← (const word) main::wd#0 -- _deref_pwuc1=vwuc2
|
||||||
|
lda #<wd
|
||||||
|
sta SCREEN
|
||||||
|
lda #>wd
|
||||||
|
sta SCREEN+1
|
||||||
|
jmp breturn
|
||||||
|
//SEG11 main::@return
|
||||||
|
breturn:
|
||||||
|
//SEG12 [5] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG13 File Data
|
||||||
|
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [4] *((const word*) main::SCREEN#0) ← (const word) main::wd#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [main]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [main] best 33 combination
|
||||||
|
Uplifting [] best 33 combination
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
//SEG0 File Comments
|
||||||
|
// Tests word pointer math - subtracting two word pointers
|
||||||
|
//SEG1 Basic Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(bbegin)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
//SEG2 Global Constants & labels
|
||||||
|
.const SIZEOF_WORD = 2
|
||||||
|
//SEG3 @begin
|
||||||
|
bbegin:
|
||||||
|
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
b1_from_bbegin:
|
||||||
|
jmp b1
|
||||||
|
//SEG5 @1
|
||||||
|
b1:
|
||||||
|
//SEG6 [2] call main
|
||||||
|
jsr main
|
||||||
|
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
bend_from_b1:
|
||||||
|
jmp bend
|
||||||
|
//SEG8 @end
|
||||||
|
bend:
|
||||||
|
//SEG9 main
|
||||||
|
main: {
|
||||||
|
.label w1 = $1000
|
||||||
|
.label w2 = $1140
|
||||||
|
.label SCREEN = $400
|
||||||
|
.const wd = w2-w1*SIZEOF_WORD
|
||||||
|
//SEG10 [4] *((const word*) main::SCREEN#0) ← (const word) main::wd#0 -- _deref_pwuc1=vwuc2
|
||||||
|
lda #<wd
|
||||||
|
sta SCREEN
|
||||||
|
lda #>wd
|
||||||
|
sta SCREEN+1
|
||||||
|
jmp breturn
|
||||||
|
//SEG11 main::@return
|
||||||
|
breturn:
|
||||||
|
//SEG12 [5] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG13 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) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
(word*) main::SCREEN
|
||||||
|
(const word*) main::SCREEN#0 SCREEN = (word*) 1024
|
||||||
|
(word*) main::w1
|
||||||
|
(const word*) main::w1#0 w1 = (word*) 4096
|
||||||
|
(word*) main::w2
|
||||||
|
(const word*) main::w2#0 w2 = (word*) 4416
|
||||||
|
(word) main::wd
|
||||||
|
(const word) main::wd#0 wd = (const word*) main::w2#0-(const word*) main::w1#0*(const byte) SIZEOF_WORD
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 18
|
||||||
|
|
||||||
|
//SEG0 File Comments
|
||||||
|
// Tests word pointer math - subtracting two word pointers
|
||||||
|
//SEG1 Basic Upstart
|
||||||
|
.pc = $801 "Basic"
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.pc = $80d "Program"
|
||||||
|
//SEG2 Global Constants & labels
|
||||||
|
.const SIZEOF_WORD = 2
|
||||||
|
//SEG3 @begin
|
||||||
|
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||||
|
//SEG5 @1
|
||||||
|
//SEG6 [2] call main
|
||||||
|
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||||
|
//SEG8 @end
|
||||||
|
//SEG9 main
|
||||||
|
main: {
|
||||||
|
.label w1 = $1000
|
||||||
|
.label w2 = $1140
|
||||||
|
.label SCREEN = $400
|
||||||
|
.const wd = w2-w1*SIZEOF_WORD
|
||||||
|
//SEG10 [4] *((const word*) main::SCREEN#0) ← (const word) main::wd#0 -- _deref_pwuc1=vwuc2
|
||||||
|
lda #<wd
|
||||||
|
sta SCREEN
|
||||||
|
lda #>wd
|
||||||
|
sta SCREEN+1
|
||||||
|
//SEG11 main::@return
|
||||||
|
//SEG12 [5] return
|
||||||
|
rts
|
||||||
|
}
|
||||||
|
//SEG13 File Data
|
||||||
|
|
15
src/test/ref/word-pointer-math-1.sym
Normal file
15
src/test/ref/word-pointer-math-1.sym
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
(label) @1
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
|
||||||
|
(void()) main()
|
||||||
|
(label) main::@return
|
||||||
|
(word*) main::SCREEN
|
||||||
|
(const word*) main::SCREEN#0 SCREEN = (word*) 1024
|
||||||
|
(word*) main::w1
|
||||||
|
(const word*) main::w1#0 w1 = (word*) 4096
|
||||||
|
(word*) main::w2
|
||||||
|
(const word*) main::w2#0 w2 = (word*) 4416
|
||||||
|
(word) main::wd
|
||||||
|
(const word) main::wd#0 wd = (const word*) main::w2#0-(const word*) main::w1#0*(const byte) SIZEOF_WORD
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user