mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-23 13:31:12 +00:00
Removed test that does not contribute.
This commit is contained in:
parent
d3dbba3383
commit
49b58cc610
@ -47,11 +47,6 @@ public class TestPrograms {
|
|||||||
compileAndCompare("adventofcode/2020-04.c");
|
compileAndCompare("adventofcode/2020-04.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStructArrayProblem1() throws IOException, URISyntaxException {
|
|
||||||
compileAndCompare("struct-array-problem-1.c");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAdventOfCode03() throws IOException, URISyntaxException {
|
public void testAdventOfCode03() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("adventofcode/2020-03.c");
|
compileAndCompare("adventofcode/2020-03.c");
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
// Demonstrates problem with structs containing arrays and auto-type conversion
|
|
||||||
// https://gitlab.com/camelot/kickc/-/issues/593
|
|
||||||
|
|
||||||
typedef struct hostslots {
|
|
||||||
// this should be [8][32], but kickc doesn't do double arrays
|
|
||||||
unsigned char host[256];
|
|
||||||
} HostSlots;
|
|
||||||
#define HOSTSLOT_SIZE 32
|
|
||||||
|
|
||||||
char * const OUT = 0x8000;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
__mem HostSlots slots1 = {"some data that would fit a normal 8x32 double array"};
|
|
||||||
__mem HostSlots slots2 = {"more data that would fit a normal 8x32 double array"};
|
|
||||||
doStuff(&slots1);
|
|
||||||
doStuff(&slots2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doStuff(HostSlots *hs) {
|
|
||||||
for(unsigned char i = 0; i < 8; i++) {
|
|
||||||
// should be:
|
|
||||||
// if (hs->host[i][0] != 0) {
|
|
||||||
char *hsp = hs->host[i * HOSTSLOT_SIZE];
|
|
||||||
if (*hsp != 0) {
|
|
||||||
*(OUT + i) = 1;
|
|
||||||
} else {
|
|
||||||
*(OUT + i) = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
// Demonstrates problem with structs containing arrays and auto-type conversion
|
|
||||||
// https://gitlab.com/camelot/kickc/-/issues/593
|
|
||||||
.pc = $801 "Basic"
|
|
||||||
:BasicUpstart(main)
|
|
||||||
.pc = $80d "Program"
|
|
||||||
.const SIZEOF_STRUCT_HOSTSLOTS = 0
|
|
||||||
.label OUT = $8000
|
|
||||||
main: {
|
|
||||||
// slots1 = {"some data that would fit a normal 8x32 double array"}
|
|
||||||
ldy #SIZEOF_STRUCT_HOSTSLOTS
|
|
||||||
!:
|
|
||||||
lda __0-1,y
|
|
||||||
sta slots1-1,y
|
|
||||||
dey
|
|
||||||
bne !-
|
|
||||||
// slots2 = {"more data that would fit a normal 8x32 double array"}
|
|
||||||
ldy #SIZEOF_STRUCT_HOSTSLOTS
|
|
||||||
!:
|
|
||||||
lda __1-1,y
|
|
||||||
sta slots2-1,y
|
|
||||||
dey
|
|
||||||
bne !-
|
|
||||||
// doStuff(&slots1)
|
|
||||||
lda #<slots1
|
|
||||||
sta.z doStuff.hs
|
|
||||||
lda #>slots1
|
|
||||||
sta.z doStuff.hs+1
|
|
||||||
jsr doStuff
|
|
||||||
// doStuff(&slots2)
|
|
||||||
lda #<slots2
|
|
||||||
sta.z doStuff.hs
|
|
||||||
lda #>slots2
|
|
||||||
sta.z doStuff.hs+1
|
|
||||||
jsr doStuff
|
|
||||||
// }
|
|
||||||
rts
|
|
||||||
slots1: .fill SIZEOF_STRUCT_HOSTSLOTS, 0
|
|
||||||
slots2: .fill SIZEOF_STRUCT_HOSTSLOTS, 0
|
|
||||||
}
|
|
||||||
// doStuff(struct hostslots* zp(2) hs)
|
|
||||||
doStuff: {
|
|
||||||
.label hsp = 5
|
|
||||||
.label i = 4
|
|
||||||
.label hs = 2
|
|
||||||
lda #0
|
|
||||||
sta.z i
|
|
||||||
__b1:
|
|
||||||
// for(unsigned char i = 0; i < 8; i++)
|
|
||||||
lda.z i
|
|
||||||
cmp #8
|
|
||||||
bcc __b2
|
|
||||||
// }
|
|
||||||
rts
|
|
||||||
__b2:
|
|
||||||
// i * HOSTSLOT_SIZE
|
|
||||||
lda.z i
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
// hsp = hs->host[i * HOSTSLOT_SIZE]
|
|
||||||
// should be:
|
|
||||||
// if (hs->host[i][0] != 0) {
|
|
||||||
.assert "Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa ", 0, 1
|
|
||||||
// if (*hsp != 0)
|
|
||||||
ldy #0
|
|
||||||
lda (hsp),y
|
|
||||||
cmp #0
|
|
||||||
bne __b3
|
|
||||||
// *(OUT + i) = 2
|
|
||||||
lda #2
|
|
||||||
ldy.z i
|
|
||||||
sta OUT,y
|
|
||||||
__b4:
|
|
||||||
// for(unsigned char i = 0; i < 8; i++)
|
|
||||||
inc.z i
|
|
||||||
jmp __b1
|
|
||||||
__b3:
|
|
||||||
// *(OUT + i) = 1
|
|
||||||
lda #1
|
|
||||||
ldy.z i
|
|
||||||
sta OUT,y
|
|
||||||
jmp __b4
|
|
||||||
}
|
|
||||||
__0: .text "some data that would fit a normal 8x32 double array"
|
|
||||||
.byte 0
|
|
||||||
.fill $cc, 0
|
|
||||||
__1: .text "more data that would fit a normal 8x32 double array"
|
|
||||||
.byte 0
|
|
||||||
.fill $cc, 0
|
|
@ -1,40 +0,0 @@
|
|||||||
|
|
||||||
void main()
|
|
||||||
main: scope:[main] from
|
|
||||||
[0] *(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS)
|
|
||||||
[1] *(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS)
|
|
||||||
[2] call doStuff
|
|
||||||
to:main::@1
|
|
||||||
main::@1: scope:[main] from main
|
|
||||||
[3] phi()
|
|
||||||
[4] call doStuff
|
|
||||||
to:main::@return
|
|
||||||
main::@return: scope:[main] from main::@1
|
|
||||||
[5] return
|
|
||||||
to:@return
|
|
||||||
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
doStuff: scope:[doStuff] from main main::@1
|
|
||||||
[6] doStuff::hs#4 = phi( main/&main::slots1, main::@1/&main::slots2 )
|
|
||||||
to:doStuff::@1
|
|
||||||
doStuff::@1: scope:[doStuff] from doStuff doStuff::@4
|
|
||||||
[7] doStuff::i#2 = phi( doStuff/0, doStuff::@4/doStuff::i#1 )
|
|
||||||
[8] if(doStuff::i#2<8) goto doStuff::@2
|
|
||||||
to:doStuff::@return
|
|
||||||
doStuff::@return: scope:[doStuff] from doStuff::@1
|
|
||||||
[9] return
|
|
||||||
to:@return
|
|
||||||
doStuff::@2: scope:[doStuff] from doStuff::@1
|
|
||||||
[10] doStuff::$1 = doStuff::i#2 << 5
|
|
||||||
[11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
[12] if(*doStuff::hsp#0!=0) goto doStuff::@3
|
|
||||||
to:doStuff::@5
|
|
||||||
doStuff::@5: scope:[doStuff] from doStuff::@2
|
|
||||||
[13] OUT[doStuff::i#2] = 2
|
|
||||||
to:doStuff::@4
|
|
||||||
doStuff::@4: scope:[doStuff] from doStuff::@3 doStuff::@5
|
|
||||||
[14] doStuff::i#1 = ++ doStuff::i#2
|
|
||||||
to:doStuff::@1
|
|
||||||
doStuff::@3: scope:[doStuff] from doStuff::@2
|
|
||||||
[15] OUT[doStuff::i#2] = 1
|
|
||||||
to:doStuff::@4
|
|
@ -1,670 +0,0 @@
|
|||||||
Fixing struct type size struct hostslots to 256
|
|
||||||
Fixing struct type SIZE_OF struct hostslots to 256
|
|
||||||
Fixing struct type SIZE_OF struct hostslots to 256
|
|
||||||
Setting struct to load/store in variable affected by address-of main::$0 = call doStuff &main::slots1
|
|
||||||
Setting struct to load/store in variable affected by address-of main::$1 = call doStuff &main::slots2
|
|
||||||
|
|
||||||
CONTROL FLOW GRAPH SSA
|
|
||||||
|
|
||||||
void main()
|
|
||||||
main: scope:[main] from __start
|
|
||||||
*(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS)
|
|
||||||
main::slots1 = struct-unwound {*(&main::slots1)}
|
|
||||||
*(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS)
|
|
||||||
main::slots2 = struct-unwound {*(&main::slots2)}
|
|
||||||
doStuff::hs#0 = &main::slots1
|
|
||||||
call doStuff
|
|
||||||
to:main::@1
|
|
||||||
main::@1: scope:[main] from main
|
|
||||||
doStuff::hs#1 = &main::slots2
|
|
||||||
call doStuff
|
|
||||||
to:main::@2
|
|
||||||
main::@2: scope:[main] from main::@1
|
|
||||||
to:main::@return
|
|
||||||
main::@return: scope:[main] from main::@2
|
|
||||||
return
|
|
||||||
to:@return
|
|
||||||
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
doStuff: scope:[doStuff] from main main::@1
|
|
||||||
doStuff::hs#4 = phi( main/doStuff::hs#0, main::@1/doStuff::hs#1 )
|
|
||||||
doStuff::i#0 = 0
|
|
||||||
to:doStuff::@1
|
|
||||||
doStuff::@1: scope:[doStuff] from doStuff doStuff::@4
|
|
||||||
doStuff::hs#3 = phi( doStuff/doStuff::hs#4, doStuff::@4/doStuff::hs#5 )
|
|
||||||
doStuff::i#2 = phi( doStuff/doStuff::i#0, doStuff::@4/doStuff::i#1 )
|
|
||||||
doStuff::$0 = doStuff::i#2 < 8
|
|
||||||
if(doStuff::$0) goto doStuff::@2
|
|
||||||
to:doStuff::@return
|
|
||||||
doStuff::@2: scope:[doStuff] from doStuff::@1
|
|
||||||
doStuff::hs#2 = phi( doStuff::@1/doStuff::hs#3 )
|
|
||||||
doStuff::i#3 = phi( doStuff::@1/doStuff::i#2 )
|
|
||||||
doStuff::$1 = doStuff::i#3 * $20
|
|
||||||
doStuff::$6 = (byte*)doStuff::hs#2
|
|
||||||
doStuff::$5 = doStuff::$6 + OFFSET_STRUCT_HOSTSLOTS_HOST
|
|
||||||
doStuff::hsp#0 = ((byte*)) doStuff::$5[doStuff::$1]
|
|
||||||
doStuff::$2 = *doStuff::hsp#0 != 0
|
|
||||||
if(doStuff::$2) goto doStuff::@3
|
|
||||||
to:doStuff::@5
|
|
||||||
doStuff::@3: scope:[doStuff] from doStuff::@2
|
|
||||||
doStuff::hs#6 = phi( doStuff::@2/doStuff::hs#2 )
|
|
||||||
doStuff::i#4 = phi( doStuff::@2/doStuff::i#3 )
|
|
||||||
doStuff::$4 = OUT + doStuff::i#4
|
|
||||||
*doStuff::$4 = 1
|
|
||||||
to:doStuff::@4
|
|
||||||
doStuff::@5: scope:[doStuff] from doStuff::@2
|
|
||||||
doStuff::hs#7 = phi( doStuff::@2/doStuff::hs#2 )
|
|
||||||
doStuff::i#5 = phi( doStuff::@2/doStuff::i#3 )
|
|
||||||
doStuff::$3 = OUT + doStuff::i#5
|
|
||||||
*doStuff::$3 = 2
|
|
||||||
to:doStuff::@4
|
|
||||||
doStuff::@4: scope:[doStuff] from doStuff::@3 doStuff::@5
|
|
||||||
doStuff::hs#5 = phi( doStuff::@3/doStuff::hs#6, doStuff::@5/doStuff::hs#7 )
|
|
||||||
doStuff::i#6 = phi( doStuff::@3/doStuff::i#4, doStuff::@5/doStuff::i#5 )
|
|
||||||
doStuff::i#1 = ++ doStuff::i#6
|
|
||||||
to:doStuff::@1
|
|
||||||
doStuff::@return: scope:[doStuff] from doStuff::@1
|
|
||||||
return
|
|
||||||
to:@return
|
|
||||||
|
|
||||||
void __start()
|
|
||||||
__start: scope:[__start] from
|
|
||||||
call main
|
|
||||||
to:__start::@1
|
|
||||||
__start::@1: scope:[__start] from __start
|
|
||||||
to:__start::@return
|
|
||||||
__start::@return: scope:[__start] from __start::@1
|
|
||||||
return
|
|
||||||
to:@return
|
|
||||||
|
|
||||||
SYMBOL TABLE SSA
|
|
||||||
const struct hostslots $0 = { host: "some data that would fit a normal 8x32 double array" }
|
|
||||||
const struct hostslots $1 = { host: "more data that would fit a normal 8x32 double array" }
|
|
||||||
const byte OFFSET_STRUCT_HOSTSLOTS_HOST = 0
|
|
||||||
const nomodify byte* OUT = (byte*)$8000
|
|
||||||
const byte SIZEOF_STRUCT_HOSTSLOTS = 0
|
|
||||||
void __start()
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
bool~ doStuff::$0
|
|
||||||
number~ doStuff::$1
|
|
||||||
bool~ doStuff::$2
|
|
||||||
byte*~ doStuff::$3
|
|
||||||
byte*~ doStuff::$4
|
|
||||||
byte*~ doStuff::$5
|
|
||||||
byte*~ doStuff::$6
|
|
||||||
struct hostslots* doStuff::hs
|
|
||||||
struct hostslots* doStuff::hs#0
|
|
||||||
struct hostslots* doStuff::hs#1
|
|
||||||
struct hostslots* doStuff::hs#2
|
|
||||||
struct hostslots* doStuff::hs#3
|
|
||||||
struct hostslots* doStuff::hs#4
|
|
||||||
struct hostslots* doStuff::hs#5
|
|
||||||
struct hostslots* doStuff::hs#6
|
|
||||||
struct hostslots* doStuff::hs#7
|
|
||||||
byte* doStuff::hsp
|
|
||||||
byte* doStuff::hsp#0
|
|
||||||
byte doStuff::i
|
|
||||||
byte doStuff::i#0
|
|
||||||
byte doStuff::i#1
|
|
||||||
byte doStuff::i#2
|
|
||||||
byte doStuff::i#3
|
|
||||||
byte doStuff::i#4
|
|
||||||
byte doStuff::i#5
|
|
||||||
byte doStuff::i#6
|
|
||||||
void main()
|
|
||||||
struct hostslots main::slots1 loadstore
|
|
||||||
struct hostslots main::slots2 loadstore
|
|
||||||
|
|
||||||
Adding number conversion cast (unumber) 8 in doStuff::$0 = doStuff::i#2 < 8
|
|
||||||
Adding number conversion cast (unumber) $20 in doStuff::$1 = doStuff::i#3 * $20
|
|
||||||
Adding number conversion cast (unumber) doStuff::$1 in doStuff::$1 = doStuff::i#3 * (unumber)$20
|
|
||||||
Adding number conversion cast (unumber) 0 in doStuff::$2 = *doStuff::hsp#0 != 0
|
|
||||||
Adding number conversion cast (unumber) 1 in *doStuff::$4 = 1
|
|
||||||
Adding number conversion cast (unumber) 2 in *doStuff::$3 = 2
|
|
||||||
Successful SSA optimization PassNAddNumberTypeConversions
|
|
||||||
Inlining cast doStuff::hsp#0 = (byte*)doStuff::$5[doStuff::$1]
|
|
||||||
Inlining cast *doStuff::$4 = (unumber)1
|
|
||||||
Inlining cast *doStuff::$3 = (unumber)2
|
|
||||||
Successful SSA optimization Pass2InlineCast
|
|
||||||
Simplifying constant pointer cast (byte*) 32768
|
|
||||||
Simplifying constant integer cast 8
|
|
||||||
Simplifying constant integer cast $20
|
|
||||||
Simplifying constant integer cast 0
|
|
||||||
Simplifying constant integer cast 1
|
|
||||||
Simplifying constant integer cast 2
|
|
||||||
Successful SSA optimization PassNCastSimplification
|
|
||||||
Finalized unsigned number type 8
|
|
||||||
Finalized unsigned number type $20
|
|
||||||
Finalized unsigned number type 0
|
|
||||||
Finalized unsigned number type 1
|
|
||||||
Finalized unsigned number type 2
|
|
||||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
|
||||||
Inferred type updated to byte in doStuff::$1 = doStuff::i#3 * $20
|
|
||||||
Alias doStuff::i#2 = doStuff::i#3 doStuff::i#4 doStuff::i#5
|
|
||||||
Alias doStuff::hs#2 = doStuff::hs#3 doStuff::hs#6 doStuff::hs#7
|
|
||||||
Successful SSA optimization Pass2AliasElimination
|
|
||||||
Alias doStuff::i#2 = doStuff::i#6
|
|
||||||
Alias doStuff::hs#2 = doStuff::hs#5
|
|
||||||
Successful SSA optimization Pass2AliasElimination
|
|
||||||
Identical Phi Values doStuff::hs#2 doStuff::hs#4
|
|
||||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
|
||||||
Simple Condition doStuff::$0 [13] if(doStuff::i#2<8) goto doStuff::@2
|
|
||||||
Simple Condition doStuff::$2 [19] if(*doStuff::hsp#0!=0) goto doStuff::@3
|
|
||||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
|
||||||
Removing C-classic struct-unwound assignment [1] main::slots1 = struct-unwound {*(&main::slots1)}
|
|
||||||
Removing C-classic struct-unwound assignment [3] main::slots2 = struct-unwound {*(&main::slots2)}
|
|
||||||
Constant doStuff::hs#0 = &main::slots1
|
|
||||||
Constant doStuff::hs#1 = &main::slots2
|
|
||||||
Constant doStuff::i#0 = 0
|
|
||||||
Successful SSA optimization Pass2ConstantIdentification
|
|
||||||
Converting *(pointer+n) to pointer[n] [21] *doStuff::$4 = 1 -- OUT[doStuff::i#2]
|
|
||||||
Converting *(pointer+n) to pointer[n] [23] *doStuff::$3 = 2 -- OUT[doStuff::i#2]
|
|
||||||
Successful SSA optimization Pass2InlineDerefIdx
|
|
||||||
Simplifying expression containing zero doStuff::$6 in [16] doStuff::$5 = doStuff::$6 + OFFSET_STRUCT_HOSTSLOTS_HOST
|
|
||||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
|
||||||
Eliminating unused variable doStuff::$4 and assignment [13] doStuff::$4 = OUT + doStuff::i#2
|
|
||||||
Eliminating unused variable doStuff::$3 and assignment [15] doStuff::$3 = OUT + doStuff::i#2
|
|
||||||
Eliminating unused constant OFFSET_STRUCT_HOSTSLOTS_HOST
|
|
||||||
Successful SSA optimization PassNEliminateUnusedVars
|
|
||||||
Removing unused procedure __start
|
|
||||||
Removing unused procedure block __start
|
|
||||||
Removing unused procedure block __start::@1
|
|
||||||
Removing unused procedure block __start::@return
|
|
||||||
Successful SSA optimization PassNEliminateEmptyStart
|
|
||||||
Alias doStuff::$5 = doStuff::$6
|
|
||||||
Successful SSA optimization Pass2AliasElimination
|
|
||||||
Inlining Noop Cast [9] doStuff::$5 = (byte*)doStuff::hs#4 keeping doStuff::hs#4
|
|
||||||
Successful SSA optimization Pass2NopCastInlining
|
|
||||||
Rewriting multiplication to use shift [8] doStuff::$1 = doStuff::i#2 * $20
|
|
||||||
Successful SSA optimization Pass2MultiplyToShiftRewriting
|
|
||||||
Inlining constant with var siblings doStuff::hs#0
|
|
||||||
Inlining constant with var siblings doStuff::hs#1
|
|
||||||
Inlining constant with var siblings doStuff::i#0
|
|
||||||
Constant inlined doStuff::hs#0 = &main::slots1
|
|
||||||
Constant inlined doStuff::hs#1 = &main::slots2
|
|
||||||
Constant inlined doStuff::i#0 = 0
|
|
||||||
Successful SSA optimization Pass2ConstantInlining
|
|
||||||
Adding NOP phi() at start of main::@1
|
|
||||||
Adding NOP phi() at start of main::@2
|
|
||||||
CALL GRAPH
|
|
||||||
Calls in [main] to doStuff:2 doStuff:4
|
|
||||||
|
|
||||||
Created 2 initial phi equivalence classes
|
|
||||||
Coalesced [16] doStuff::i#7 = doStuff::i#1
|
|
||||||
Coalesced down to 2 phi equivalence classes
|
|
||||||
Culled Empty Block label main::@2
|
|
||||||
Adding NOP phi() at start of main::@1
|
|
||||||
|
|
||||||
FINAL CONTROL FLOW GRAPH
|
|
||||||
|
|
||||||
void main()
|
|
||||||
main: scope:[main] from
|
|
||||||
[0] *(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS)
|
|
||||||
[1] *(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS)
|
|
||||||
[2] call doStuff
|
|
||||||
to:main::@1
|
|
||||||
main::@1: scope:[main] from main
|
|
||||||
[3] phi()
|
|
||||||
[4] call doStuff
|
|
||||||
to:main::@return
|
|
||||||
main::@return: scope:[main] from main::@1
|
|
||||||
[5] return
|
|
||||||
to:@return
|
|
||||||
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
doStuff: scope:[doStuff] from main main::@1
|
|
||||||
[6] doStuff::hs#4 = phi( main/&main::slots1, main::@1/&main::slots2 )
|
|
||||||
to:doStuff::@1
|
|
||||||
doStuff::@1: scope:[doStuff] from doStuff doStuff::@4
|
|
||||||
[7] doStuff::i#2 = phi( doStuff/0, doStuff::@4/doStuff::i#1 )
|
|
||||||
[8] if(doStuff::i#2<8) goto doStuff::@2
|
|
||||||
to:doStuff::@return
|
|
||||||
doStuff::@return: scope:[doStuff] from doStuff::@1
|
|
||||||
[9] return
|
|
||||||
to:@return
|
|
||||||
doStuff::@2: scope:[doStuff] from doStuff::@1
|
|
||||||
[10] doStuff::$1 = doStuff::i#2 << 5
|
|
||||||
[11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
[12] if(*doStuff::hsp#0!=0) goto doStuff::@3
|
|
||||||
to:doStuff::@5
|
|
||||||
doStuff::@5: scope:[doStuff] from doStuff::@2
|
|
||||||
[13] OUT[doStuff::i#2] = 2
|
|
||||||
to:doStuff::@4
|
|
||||||
doStuff::@4: scope:[doStuff] from doStuff::@3 doStuff::@5
|
|
||||||
[14] doStuff::i#1 = ++ doStuff::i#2
|
|
||||||
to:doStuff::@1
|
|
||||||
doStuff::@3: scope:[doStuff] from doStuff::@2
|
|
||||||
[15] OUT[doStuff::i#2] = 1
|
|
||||||
to:doStuff::@4
|
|
||||||
|
|
||||||
|
|
||||||
VARIABLE REGISTER WEIGHTS
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
byte~ doStuff::$1 101.0
|
|
||||||
struct hostslots* doStuff::hs
|
|
||||||
struct hostslots* doStuff::hs#4
|
|
||||||
byte* doStuff::hsp
|
|
||||||
byte* doStuff::hsp#0 202.0
|
|
||||||
byte doStuff::i
|
|
||||||
byte doStuff::i#1 202.0
|
|
||||||
byte doStuff::i#2 86.57142857142857
|
|
||||||
void main()
|
|
||||||
struct hostslots main::slots1 loadstore
|
|
||||||
struct hostslots main::slots2 loadstore
|
|
||||||
|
|
||||||
Initial phi equivalence classes
|
|
||||||
[ doStuff::hs#4 ]
|
|
||||||
[ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Added variable doStuff::$1 to live range equivalence class [ doStuff::$1 ]
|
|
||||||
Added variable doStuff::hsp#0 to live range equivalence class [ doStuff::hsp#0 ]
|
|
||||||
Added variable main::slots1 to live range equivalence class [ main::slots1 ]
|
|
||||||
Added variable main::slots2 to live range equivalence class [ main::slots2 ]
|
|
||||||
Complete equivalence classes
|
|
||||||
[ doStuff::hs#4 ]
|
|
||||||
[ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
[ doStuff::$1 ]
|
|
||||||
[ doStuff::hsp#0 ]
|
|
||||||
[ main::slots1 ]
|
|
||||||
[ main::slots2 ]
|
|
||||||
Allocated zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Allocated zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Allocated zp[1]:5 [ doStuff::$1 ]
|
|
||||||
Allocated zp[2]:6 [ doStuff::hsp#0 ]
|
|
||||||
Allocated mem[256] [ main::slots1 ]
|
|
||||||
Allocated mem[256] [ main::slots2 ]
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuz3. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuz3
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
|
||||||
Statement [0] *(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) [ main::slots2 ] ( [ main::slots2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [1] *(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) [ ] ( [ ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [10] doStuff::$1 = doStuff::i#2 << 5 [ doStuff::hs#4 doStuff::i#2 doStuff::$1 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 doStuff::$1 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 doStuff::$1 ] { } ) always clobbers reg byte a
|
|
||||||
Removing always clobbered register reg byte a as potential for zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuz3. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuz3 allocation: zp[1]:5 [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa allocation: reg byte a [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuxx. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuxx allocation: reg byte x [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuyy. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuyy allocation: reg byte y [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
MISSING FRAGMENTS
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuz3. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuz3
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuxx. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuxx
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuyy. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuyy
|
|
||||||
Statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] [ doStuff::hs#4 doStuff::i#2 doStuff::hsp#0 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 doStuff::hsp#0 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 doStuff::hsp#0 ] { } ) always clobbers reg byte a reg byte x reg byte y
|
|
||||||
Removing always clobbered register reg byte x as potential for zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Removing always clobbered register reg byte y as potential for zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Statement [12] if(*doStuff::hsp#0!=0) goto doStuff::@3 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [13] OUT[doStuff::i#2] = 2 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [15] OUT[doStuff::i#2] = 1 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [0] *(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) [ main::slots2 ] ( [ main::slots2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [1] *(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) [ ] ( [ ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [8] if(doStuff::i#2<8) goto doStuff::@2 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a
|
|
||||||
Statement [10] doStuff::$1 = doStuff::i#2 << 5 [ doStuff::hs#4 doStuff::i#2 doStuff::$1 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 doStuff::$1 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 doStuff::$1 ] { } ) always clobbers reg byte a
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuz3. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuz3 allocation: zp[1]:5 [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa allocation: reg byte a [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuxx. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuxx allocation: reg byte x [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Potential register analysis [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] missing fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuyy. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuyy allocation: reg byte y [ doStuff::$1 ] zp[2]:6 [ doStuff::hsp#0 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
MISSING FRAGMENTS
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuz3. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuz3
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuxx. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuxx
|
|
||||||
Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuyy. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuyy
|
|
||||||
Statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1] [ doStuff::hs#4 doStuff::i#2 doStuff::hsp#0 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 doStuff::hsp#0 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 doStuff::hsp#0 ] { } ) always clobbers reg byte a reg byte x reg byte y
|
|
||||||
Statement [12] if(*doStuff::hsp#0!=0) goto doStuff::@3 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [13] OUT[doStuff::i#2] = 2 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Statement [15] OUT[doStuff::i#2] = 1 [ doStuff::hs#4 doStuff::i#2 ] ( doStuff:2 [ doStuff::hs#4 doStuff::i#2 ] { } doStuff:4 [ doStuff::hs#4 doStuff::i#2 ] { } ) always clobbers reg byte a reg byte y
|
|
||||||
Potential registers zp[2]:2 [ doStuff::hs#4 ] : zp[2]:2 ,
|
|
||||||
Potential registers zp[1]:4 [ doStuff::i#2 doStuff::i#1 ] : zp[1]:4 ,
|
|
||||||
Potential registers zp[1]:5 [ doStuff::$1 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
|
||||||
Potential registers zp[2]:6 [ doStuff::hsp#0 ] : zp[2]:6 ,
|
|
||||||
Potential registers mem[256] [ main::slots1 ] : mem[256] ,
|
|
||||||
Potential registers mem[256] [ main::slots2 ] : mem[256] ,
|
|
||||||
|
|
||||||
REGISTER UPLIFT SCOPES
|
|
||||||
Uplift Scope [doStuff] 288.57: zp[1]:4 [ doStuff::i#2 doStuff::i#1 ] 202: zp[2]:6 [ doStuff::hsp#0 ] 101: zp[1]:5 [ doStuff::$1 ] 0: zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Uplift Scope [hostslots]
|
|
||||||
Uplift Scope [main] 0: mem[256] [ main::slots1 ] 0: mem[256] [ main::slots2 ]
|
|
||||||
Uplift Scope []
|
|
||||||
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuz3. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuz3
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuxx. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuxx
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuyy. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuyy
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Uplifting [doStuff] best 887 combination zp[1]:4 [ doStuff::i#2 doStuff::i#1 ] zp[2]:6 [ doStuff::hsp#0 ] reg byte a [ doStuff::$1 ] zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Uplifting [hostslots] best 887 combination
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Uplifting [main] best 887 combination mem[256] [ main::slots1 ] mem[256] [ main::slots2 ]
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Uplifting [] best 887 combination
|
|
||||||
Attempting to uplift remaining variables inzp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
Uplifting [doStuff] best 887 combination zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
Allocated (was zp[2]:6) zp[2]:5 [ doStuff::hsp#0 ]
|
|
||||||
Warning! Unknown fragment for statement [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa
|
|
||||||
/Users/jespergravgaard/c64/kickc/src/test/kc/struct-array-problem-1.c:23:9:
|
|
||||||
|
|
||||||
ASSEMBLER BEFORE OPTIMIZATION
|
|
||||||
// File Comments
|
|
||||||
// Demonstrates problem with structs containing arrays and auto-type conversion
|
|
||||||
// https://gitlab.com/camelot/kickc/-/issues/593
|
|
||||||
// Upstart
|
|
||||||
.pc = $801 "Basic"
|
|
||||||
:BasicUpstart(main)
|
|
||||||
.pc = $80d "Program"
|
|
||||||
// Global Constants & labels
|
|
||||||
.const SIZEOF_STRUCT_HOSTSLOTS = 0
|
|
||||||
.label OUT = $8000
|
|
||||||
// main
|
|
||||||
main: {
|
|
||||||
// [0] *(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
|
|
||||||
ldy #SIZEOF_STRUCT_HOSTSLOTS
|
|
||||||
!:
|
|
||||||
lda __0-1,y
|
|
||||||
sta slots1-1,y
|
|
||||||
dey
|
|
||||||
bne !-
|
|
||||||
// [1] *(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
|
|
||||||
ldy #SIZEOF_STRUCT_HOSTSLOTS
|
|
||||||
!:
|
|
||||||
lda __1-1,y
|
|
||||||
sta slots2-1,y
|
|
||||||
dey
|
|
||||||
bne !-
|
|
||||||
// [2] call doStuff
|
|
||||||
// [6] phi from main to doStuff [phi:main->doStuff]
|
|
||||||
doStuff_from_main:
|
|
||||||
// [6] phi doStuff::hs#4 = &main::slots1 [phi:main->doStuff#0] -- pssz1=pssc1
|
|
||||||
lda #<slots1
|
|
||||||
sta.z doStuff.hs
|
|
||||||
lda #>slots1
|
|
||||||
sta.z doStuff.hs+1
|
|
||||||
jsr doStuff
|
|
||||||
// [3] phi from main to main::@1 [phi:main->main::@1]
|
|
||||||
__b1_from_main:
|
|
||||||
jmp __b1
|
|
||||||
// main::@1
|
|
||||||
__b1:
|
|
||||||
// [4] call doStuff
|
|
||||||
// [6] phi from main::@1 to doStuff [phi:main::@1->doStuff]
|
|
||||||
doStuff_from___b1:
|
|
||||||
// [6] phi doStuff::hs#4 = &main::slots2 [phi:main::@1->doStuff#0] -- pssz1=pssc1
|
|
||||||
lda #<slots2
|
|
||||||
sta.z doStuff.hs
|
|
||||||
lda #>slots2
|
|
||||||
sta.z doStuff.hs+1
|
|
||||||
jsr doStuff
|
|
||||||
jmp __breturn
|
|
||||||
// main::@return
|
|
||||||
__breturn:
|
|
||||||
// [5] return
|
|
||||||
rts
|
|
||||||
slots1: .fill SIZEOF_STRUCT_HOSTSLOTS, 0
|
|
||||||
slots2: .fill SIZEOF_STRUCT_HOSTSLOTS, 0
|
|
||||||
}
|
|
||||||
// doStuff
|
|
||||||
// doStuff(struct hostslots* zp(2) hs)
|
|
||||||
doStuff: {
|
|
||||||
.label hsp = 5
|
|
||||||
.label i = 4
|
|
||||||
.label hs = 2
|
|
||||||
// [7] phi from doStuff to doStuff::@1 [phi:doStuff->doStuff::@1]
|
|
||||||
__b1_from_doStuff:
|
|
||||||
// [7] phi doStuff::i#2 = 0 [phi:doStuff->doStuff::@1#0] -- vbuz1=vbuc1
|
|
||||||
lda #0
|
|
||||||
sta.z i
|
|
||||||
jmp __b1
|
|
||||||
// doStuff::@1
|
|
||||||
__b1:
|
|
||||||
// [8] if(doStuff::i#2<8) goto doStuff::@2 -- vbuz1_lt_vbuc1_then_la1
|
|
||||||
lda.z i
|
|
||||||
cmp #8
|
|
||||||
bcc __b2
|
|
||||||
jmp __breturn
|
|
||||||
// doStuff::@return
|
|
||||||
__breturn:
|
|
||||||
// [9] return
|
|
||||||
rts
|
|
||||||
// doStuff::@2
|
|
||||||
__b2:
|
|
||||||
// [10] doStuff::$1 = doStuff::i#2 << 5 -- vbuaa=vbuz1_rol_5
|
|
||||||
lda.z i
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
// [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
// should be:
|
|
||||||
// if (hs->host[i][0] != 0) {
|
|
||||||
.assert "Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa ", 0, 1
|
|
||||||
// [12] if(*doStuff::hsp#0!=0) goto doStuff::@3 -- _deref_pbuz1_neq_0_then_la1
|
|
||||||
ldy #0
|
|
||||||
lda (hsp),y
|
|
||||||
cmp #0
|
|
||||||
bne __b3
|
|
||||||
jmp __b5
|
|
||||||
// doStuff::@5
|
|
||||||
__b5:
|
|
||||||
// [13] OUT[doStuff::i#2] = 2 -- pbuc1_derefidx_vbuz1=vbuc2
|
|
||||||
lda #2
|
|
||||||
ldy.z i
|
|
||||||
sta OUT,y
|
|
||||||
jmp __b4
|
|
||||||
// doStuff::@4
|
|
||||||
__b4:
|
|
||||||
// [14] doStuff::i#1 = ++ doStuff::i#2 -- vbuz1=_inc_vbuz1
|
|
||||||
inc.z i
|
|
||||||
// [7] phi from doStuff::@4 to doStuff::@1 [phi:doStuff::@4->doStuff::@1]
|
|
||||||
__b1_from___b4:
|
|
||||||
// [7] phi doStuff::i#2 = doStuff::i#1 [phi:doStuff::@4->doStuff::@1#0] -- register_copy
|
|
||||||
jmp __b1
|
|
||||||
// doStuff::@3
|
|
||||||
__b3:
|
|
||||||
// [15] OUT[doStuff::i#2] = 1 -- pbuc1_derefidx_vbuz1=vbuc2
|
|
||||||
lda #1
|
|
||||||
ldy.z i
|
|
||||||
sta OUT,y
|
|
||||||
jmp __b4
|
|
||||||
}
|
|
||||||
// File Data
|
|
||||||
__0: .text "some data that would fit a normal 8x32 double array"
|
|
||||||
.byte 0
|
|
||||||
.fill $cc, 0
|
|
||||||
__1: .text "more data that would fit a normal 8x32 double array"
|
|
||||||
.byte 0
|
|
||||||
.fill $cc, 0
|
|
||||||
|
|
||||||
ASSEMBLER OPTIMIZATIONS
|
|
||||||
Removing instruction jmp __b1
|
|
||||||
Removing instruction jmp __breturn
|
|
||||||
Removing instruction jmp __b1
|
|
||||||
Removing instruction jmp __breturn
|
|
||||||
Removing instruction jmp __b5
|
|
||||||
Removing instruction jmp __b4
|
|
||||||
Succesful ASM optimization Pass5NextJumpElimination
|
|
||||||
Removing instruction __b1_from_main:
|
|
||||||
Removing instruction doStuff_from___b1:
|
|
||||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
|
||||||
Removing instruction doStuff_from_main:
|
|
||||||
Removing instruction __b1:
|
|
||||||
Removing instruction __breturn:
|
|
||||||
Removing instruction __b1_from_doStuff:
|
|
||||||
Removing instruction __breturn:
|
|
||||||
Removing instruction __b5:
|
|
||||||
Removing instruction __b1_from___b4:
|
|
||||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
|
||||||
|
|
||||||
FINAL SYMBOL TABLE
|
|
||||||
const struct hostslots $0 = { host: "some data that would fit a normal 8x32 double array" }
|
|
||||||
const struct hostslots $1 = { host: "more data that would fit a normal 8x32 double array" }
|
|
||||||
const nomodify byte* OUT = (byte*) 32768
|
|
||||||
const byte SIZEOF_STRUCT_HOSTSLOTS = 0
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
byte~ doStuff::$1 reg byte a 101.0
|
|
||||||
struct hostslots* doStuff::hs
|
|
||||||
struct hostslots* doStuff::hs#4 hs zp[2]:2
|
|
||||||
byte* doStuff::hsp
|
|
||||||
byte* doStuff::hsp#0 hsp zp[2]:5 202.0
|
|
||||||
byte doStuff::i
|
|
||||||
byte doStuff::i#1 i zp[1]:4 202.0
|
|
||||||
byte doStuff::i#2 i zp[1]:4 86.57142857142857
|
|
||||||
void main()
|
|
||||||
struct hostslots main::slots1 loadstore mem[256]
|
|
||||||
struct hostslots main::slots2 loadstore mem[256]
|
|
||||||
|
|
||||||
zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
reg byte a [ doStuff::$1 ]
|
|
||||||
zp[2]:5 [ doStuff::hsp#0 ]
|
|
||||||
mem[256] [ main::slots1 ]
|
|
||||||
mem[256] [ main::slots2 ]
|
|
||||||
|
|
||||||
|
|
||||||
FINAL ASSEMBLER
|
|
||||||
Score: 761
|
|
||||||
|
|
||||||
// File Comments
|
|
||||||
// Demonstrates problem with structs containing arrays and auto-type conversion
|
|
||||||
// https://gitlab.com/camelot/kickc/-/issues/593
|
|
||||||
// Upstart
|
|
||||||
.pc = $801 "Basic"
|
|
||||||
:BasicUpstart(main)
|
|
||||||
.pc = $80d "Program"
|
|
||||||
// Global Constants & labels
|
|
||||||
.const SIZEOF_STRUCT_HOSTSLOTS = 0
|
|
||||||
.label OUT = $8000
|
|
||||||
// main
|
|
||||||
main: {
|
|
||||||
// slots1 = {"some data that would fit a normal 8x32 double array"}
|
|
||||||
// [0] *(&main::slots1) = memcpy(*(&$0), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
|
|
||||||
ldy #SIZEOF_STRUCT_HOSTSLOTS
|
|
||||||
!:
|
|
||||||
lda __0-1,y
|
|
||||||
sta slots1-1,y
|
|
||||||
dey
|
|
||||||
bne !-
|
|
||||||
// slots2 = {"more data that would fit a normal 8x32 double array"}
|
|
||||||
// [1] *(&main::slots2) = memcpy(*(&$1), struct hostslots, SIZEOF_STRUCT_HOSTSLOTS) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
|
|
||||||
ldy #SIZEOF_STRUCT_HOSTSLOTS
|
|
||||||
!:
|
|
||||||
lda __1-1,y
|
|
||||||
sta slots2-1,y
|
|
||||||
dey
|
|
||||||
bne !-
|
|
||||||
// doStuff(&slots1)
|
|
||||||
// [2] call doStuff
|
|
||||||
// [6] phi from main to doStuff [phi:main->doStuff]
|
|
||||||
// [6] phi doStuff::hs#4 = &main::slots1 [phi:main->doStuff#0] -- pssz1=pssc1
|
|
||||||
lda #<slots1
|
|
||||||
sta.z doStuff.hs
|
|
||||||
lda #>slots1
|
|
||||||
sta.z doStuff.hs+1
|
|
||||||
jsr doStuff
|
|
||||||
// [3] phi from main to main::@1 [phi:main->main::@1]
|
|
||||||
// main::@1
|
|
||||||
// doStuff(&slots2)
|
|
||||||
// [4] call doStuff
|
|
||||||
// [6] phi from main::@1 to doStuff [phi:main::@1->doStuff]
|
|
||||||
// [6] phi doStuff::hs#4 = &main::slots2 [phi:main::@1->doStuff#0] -- pssz1=pssc1
|
|
||||||
lda #<slots2
|
|
||||||
sta.z doStuff.hs
|
|
||||||
lda #>slots2
|
|
||||||
sta.z doStuff.hs+1
|
|
||||||
jsr doStuff
|
|
||||||
// main::@return
|
|
||||||
// }
|
|
||||||
// [5] return
|
|
||||||
rts
|
|
||||||
slots1: .fill SIZEOF_STRUCT_HOSTSLOTS, 0
|
|
||||||
slots2: .fill SIZEOF_STRUCT_HOSTSLOTS, 0
|
|
||||||
}
|
|
||||||
// doStuff
|
|
||||||
// doStuff(struct hostslots* zp(2) hs)
|
|
||||||
doStuff: {
|
|
||||||
.label hsp = 5
|
|
||||||
.label i = 4
|
|
||||||
.label hs = 2
|
|
||||||
// [7] phi from doStuff to doStuff::@1 [phi:doStuff->doStuff::@1]
|
|
||||||
// [7] phi doStuff::i#2 = 0 [phi:doStuff->doStuff::@1#0] -- vbuz1=vbuc1
|
|
||||||
lda #0
|
|
||||||
sta.z i
|
|
||||||
// doStuff::@1
|
|
||||||
__b1:
|
|
||||||
// for(unsigned char i = 0; i < 8; i++)
|
|
||||||
// [8] if(doStuff::i#2<8) goto doStuff::@2 -- vbuz1_lt_vbuc1_then_la1
|
|
||||||
lda.z i
|
|
||||||
cmp #8
|
|
||||||
bcc __b2
|
|
||||||
// doStuff::@return
|
|
||||||
// }
|
|
||||||
// [9] return
|
|
||||||
rts
|
|
||||||
// doStuff::@2
|
|
||||||
__b2:
|
|
||||||
// i * HOSTSLOT_SIZE
|
|
||||||
// [10] doStuff::$1 = doStuff::i#2 << 5 -- vbuaa=vbuz1_rol_5
|
|
||||||
lda.z i
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
asl
|
|
||||||
// hsp = hs->host[i * HOSTSLOT_SIZE]
|
|
||||||
// [11] doStuff::hsp#0 = (byte*)((byte*)doStuff::hs#4)[doStuff::$1]
|
|
||||||
// should be:
|
|
||||||
// if (hs->host[i][0] != 0) {
|
|
||||||
.assert "Missing ASM fragment Fragment not found pbuz1=_ptr_pbuz2_derefidx_vbuaa. Attempted variations pbuz1=_ptr_pbuz2_derefidx_vbuaa ", 0, 1
|
|
||||||
// if (*hsp != 0)
|
|
||||||
// [12] if(*doStuff::hsp#0!=0) goto doStuff::@3 -- _deref_pbuz1_neq_0_then_la1
|
|
||||||
ldy #0
|
|
||||||
lda (hsp),y
|
|
||||||
cmp #0
|
|
||||||
bne __b3
|
|
||||||
// doStuff::@5
|
|
||||||
// *(OUT + i) = 2
|
|
||||||
// [13] OUT[doStuff::i#2] = 2 -- pbuc1_derefidx_vbuz1=vbuc2
|
|
||||||
lda #2
|
|
||||||
ldy.z i
|
|
||||||
sta OUT,y
|
|
||||||
// doStuff::@4
|
|
||||||
__b4:
|
|
||||||
// for(unsigned char i = 0; i < 8; i++)
|
|
||||||
// [14] doStuff::i#1 = ++ doStuff::i#2 -- vbuz1=_inc_vbuz1
|
|
||||||
inc.z i
|
|
||||||
// [7] phi from doStuff::@4 to doStuff::@1 [phi:doStuff::@4->doStuff::@1]
|
|
||||||
// [7] phi doStuff::i#2 = doStuff::i#1 [phi:doStuff::@4->doStuff::@1#0] -- register_copy
|
|
||||||
jmp __b1
|
|
||||||
// doStuff::@3
|
|
||||||
__b3:
|
|
||||||
// *(OUT + i) = 1
|
|
||||||
// [15] OUT[doStuff::i#2] = 1 -- pbuc1_derefidx_vbuz1=vbuc2
|
|
||||||
lda #1
|
|
||||||
ldy.z i
|
|
||||||
sta OUT,y
|
|
||||||
jmp __b4
|
|
||||||
}
|
|
||||||
// File Data
|
|
||||||
__0: .text "some data that would fit a normal 8x32 double array"
|
|
||||||
.byte 0
|
|
||||||
.fill $cc, 0
|
|
||||||
__1: .text "more data that would fit a normal 8x32 double array"
|
|
||||||
.byte 0
|
|
||||||
.fill $cc, 0
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
|||||||
const struct hostslots $0 = { host: "some data that would fit a normal 8x32 double array" }
|
|
||||||
const struct hostslots $1 = { host: "more data that would fit a normal 8x32 double array" }
|
|
||||||
const nomodify byte* OUT = (byte*) 32768
|
|
||||||
const byte SIZEOF_STRUCT_HOSTSLOTS = 0
|
|
||||||
void doStuff(struct hostslots* doStuff::hs)
|
|
||||||
byte~ doStuff::$1 reg byte a 101.0
|
|
||||||
struct hostslots* doStuff::hs
|
|
||||||
struct hostslots* doStuff::hs#4 hs zp[2]:2
|
|
||||||
byte* doStuff::hsp
|
|
||||||
byte* doStuff::hsp#0 hsp zp[2]:5 202.0
|
|
||||||
byte doStuff::i
|
|
||||||
byte doStuff::i#1 i zp[1]:4 202.0
|
|
||||||
byte doStuff::i#2 i zp[1]:4 86.57142857142857
|
|
||||||
void main()
|
|
||||||
struct hostslots main::slots1 loadstore mem[256]
|
|
||||||
struct hostslots main::slots2 loadstore mem[256]
|
|
||||||
|
|
||||||
zp[2]:2 [ doStuff::hs#4 ]
|
|
||||||
zp[1]:4 [ doStuff::i#2 doStuff::i#1 ]
|
|
||||||
reg byte a [ doStuff::$1 ]
|
|
||||||
zp[2]:5 [ doStuff::hsp#0 ]
|
|
||||||
mem[256] [ main::slots1 ]
|
|
||||||
mem[256] [ main::slots2 ]
|
|
Loading…
Reference in New Issue
Block a user