mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-19 08:31:01 +00:00
parent
b319398702
commit
50c8175b30
@ -80,12 +80,10 @@ public class TestPrograms {
|
||||
assertError("pointer-void-err-0", "Void pointer math not allowed.");
|
||||
}
|
||||
|
||||
/*
|
||||
@Test
|
||||
public void testPointerVoid3() throws IOException, URISyntaxException {
|
||||
compileAndCompare("pointer-void-3");
|
||||
}
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testPointerVoid2() throws IOException, URISyntaxException {
|
||||
@ -749,6 +747,11 @@ public class TestPrograms {
|
||||
compileAndCompare("word-pointer-math");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordPointerMath1() throws IOException, URISyntaxException {
|
||||
compileAndCompare("word-pointer-math-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordPointerMath0() throws IOException, URISyntaxException {
|
||||
compileAndCompare("word-pointer-math-0");
|
||||
|
@ -1,24 +1,21 @@
|
||||
// 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';
|
||||
*buf2 = 'b';
|
||||
|
||||
const byte* SCREEN = 0x0400;
|
||||
SCREEN[0] = *buf1;
|
||||
SCREEN[1] = *buf2;
|
||||
|
||||
}
|
||||
|
||||
unsigned char* HEAP_START = 0xc000;
|
||||
|
||||
unsigned char* heap_head = HEAP_START;
|
||||
byte* heap_head = 0xc000;
|
||||
|
||||
void* malloc(unsigned int size) {
|
||||
void* mem = heap_head;
|
||||
heap_head+= size;
|
||||
return mem;
|
||||
void* malloc() {
|
||||
heap_head++;
|
||||
return heap_head;
|
||||
}
|
||||
|
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