1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-31 22:31:14 +00:00

Added a few fragments and a test of an array of structs with a function pointer.

This commit is contained in:
jespergravgaard 2021-09-27 00:06:43 +02:00
parent 5f7d7c45be
commit ec78f4932c
15 changed files with 1072 additions and 178 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 85a010c64 85a012cf9
//KICKC FRAGMENT CACHE 974006396 97400843e
//FRAGMENT vbuzz=vbuc1
ldz #{c1}
//FRAGMENT vbuzz_lt_vbuc1_then_la1

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 85a010c64 85a012cf9
//KICKC FRAGMENT CACHE 974006396 97400843e
//FRAGMENT _deref_pbuc1=vbuc2
lda #{c2}
sta {c1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 85a010c64 85a012cf9
//KICKC FRAGMENT CACHE 974006396 97400843e
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,14 +1,4 @@
//KICKC FRAGMENT CACHE 85a010c64 85a012cf9
//FRAGMENT vwsm1=vwsc1
lda #<{c1}
sta {m1}
lda #>{c1}
sta {m1}+1
//FRAGMENT vwsz1=vwsc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//KICKC FRAGMENT CACHE 974006396 97400843e
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}
@ -16,129 +6,6 @@ sta {z1}
lda {z1}
cmp #{c1}
bcc {la1}
//FRAGMENT vbum1=vbuz2_rol_1
lda {z2}
asl
sta {m1}
//FRAGMENT pwsc1_derefidx_vbum1=vwsz2
ldy {m1}
lda {z2}
sta {c1},y
lda {z2}+1
sta {c1}+1,y
//FRAGMENT vwsz1=_inc_vwsz1
inc {z1}
bne !+
inc {z1}+1
!:
//FRAGMENT pwsc1_derefidx_vbum1=vwsm2
ldy {m1}
lda {m2}
sta {c1},y
lda {m2}+1
sta {c1}+1,y
//FRAGMENT vwsm1=_inc_vwsm1
inc {m1}
bne !+
inc {m1}+1
!:
//FRAGMENT vbuz1=_inc_vbuz1
inc {z1}
//FRAGMENT vbuaa_lt_vbuc1_then_la1
cmp #{c1}
bcc {la1}
//FRAGMENT vbuaa=vbuz1_rol_1
lda {z1}
asl
//FRAGMENT vbuxx=vbuz1_rol_1
lda {z1}
asl
tax
//FRAGMENT vbuyy=vbuz1_rol_1
lda {z1}
asl
tay
//FRAGMENT vbum1=vbuaa_rol_1
asl
sta {m1}
//FRAGMENT vbuaa=vbuaa_rol_1
asl
//FRAGMENT vbuxx=vbuaa_rol_1
asl
tax
//FRAGMENT vbuyy=vbuaa_rol_1
asl
tay
//FRAGMENT vbum1=vbuxx_rol_1
txa
asl
sta {m1}
//FRAGMENT vbuaa=vbuxx_rol_1
txa
asl
//FRAGMENT vbuxx=vbuxx_rol_1
txa
asl
tax
//FRAGMENT vbuyy=vbuxx_rol_1
txa
asl
tay
//FRAGMENT vbum1=vbuyy_rol_1
tya
asl
sta {m1}
//FRAGMENT vbuaa=vbuyy_rol_1
tya
asl
//FRAGMENT vbuxx=vbuyy_rol_1
tya
asl
tax
//FRAGMENT vbuyy=vbuyy_rol_1
tya
asl
tay
//FRAGMENT pwsc1_derefidx_vbuaa=vwsz1
tay
lda {z1}
sta {c1},y
lda {z1}+1
sta {c1}+1,y
//FRAGMENT pwsc1_derefidx_vbuxx=vwsz1
lda {z1}
sta {c1},x
lda {z1}+1
sta {c1}+1,x
//FRAGMENT pwsc1_derefidx_vbuyy=vwsz1
lda {z1}
sta {c1},y
lda {z1}+1
sta {c1}+1,y
//FRAGMENT pwsc1_derefidx_vbuxx=vwsm1
lda {m1}
sta {c1},x
lda {m1}+1
sta {c1}+1,x
//FRAGMENT pwsc1_derefidx_vbuyy=vwsm1
lda {m1}
sta {c1},y
lda {m1}+1
sta {c1}+1,y
//FRAGMENT vbuxx_lt_vbuc1_then_la1
cpx #{c1}
bcc {la1}
//FRAGMENT vbuxx=vbuc1
ldx #{c1}
//FRAGMENT vbuxx=_inc_vbuxx
inx
//FRAGMENT vbuyy=vbuc1
ldy #{c1}
//FRAGMENT vbuyy_lt_vbuc1_then_la1
cpy #{c1}
bcc {la1}
//FRAGMENT vbuyy=_inc_vbuyy
iny
//FRAGMENT pbuc1_derefidx_vbuz1=vbuc2
lda #{c2}
ldy {z1}
@ -151,6 +18,9 @@ lda {z1}
clc
adc #2
sta {z1}
//FRAGMENT vbuaa_lt_vbuc1_then_la1
cmp #{c1}
bcc {la1}
//FRAGMENT pbuc1_derefidx_vbuaa=vbuc2
tay
lda #{c2}
@ -164,6 +34,16 @@ sta {c1},y
//FRAGMENT vbuxx=vbuxx_plus_2
inx
inx
//FRAGMENT vbuxx_lt_vbuc1_then_la1
cpx #{c1}
bcc {la1}
//FRAGMENT vbuxx=vbuc1
ldx #{c1}
//FRAGMENT vbuyy=vbuc1
ldy #{c1}
//FRAGMENT vbuyy_lt_vbuc1_then_la1
cpy #{c1}
bcc {la1}
//FRAGMENT vbuyy=vbuyy_plus_2
iny
iny
@ -175,6 +55,8 @@ beq {la1}
lda {z2}
ldy {z1}
sta {c1},y
//FRAGMENT vbuz1=_inc_vbuz1
inc {z1}
//FRAGMENT vbuz1_eq_vbuaa_then_la1
cmp {z1}
beq {la1}
@ -204,6 +86,10 @@ sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuyy=vbuyy
tya
sta {c1},y
//FRAGMENT vbuxx=_inc_vbuxx
inx
//FRAGMENT vbuyy=_inc_vbuyy
iny
//FRAGMENT vbuaa=vbuc1
lda #{c1}
//FRAGMENT vbuz1_eq_vbuyy_then_la1
@ -675,17 +561,58 @@ sta {c1},y
lda {c1}+1,y
adc {c2}+1,y
sta {c1}+1,y
//FRAGMENT vbuaa=vbuz1_rol_1
lda {z1}
asl
//FRAGMENT vbuxx=vbuz1_rol_1
lda {z1}
asl
tax
//FRAGMENT vbuyy=vbuz1_rol_1
lda {z1}
asl
tay
//FRAGMENT vbuz1=vbuaa_rol_1
asl
sta {z1}
//FRAGMENT vbuaa=vbuaa_rol_1
asl
//FRAGMENT vbuxx=vbuaa_rol_1
asl
tax
//FRAGMENT vbuyy=vbuaa_rol_1
asl
tay
//FRAGMENT vbuz1=vbuxx_rol_1
txa
asl
sta {z1}
//FRAGMENT vbuaa=vbuxx_rol_1
txa
asl
//FRAGMENT vbuxx=vbuxx_rol_1
txa
asl
tax
//FRAGMENT vbuyy=vbuxx_rol_1
txa
asl
tay
//FRAGMENT vbuz1=vbuyy_rol_1
tya
asl
sta {z1}
//FRAGMENT vbuaa=vbuyy_rol_1
tya
asl
//FRAGMENT vbuxx=vbuyy_rol_1
tya
asl
tax
//FRAGMENT vbuyy=vbuyy_rol_1
tya
asl
tay
//FRAGMENT pwuc1_derefidx_vbuaa=pwuc1_derefidx_vbuaa_plus_vbuc2
tay
clc
@ -1019,6 +946,11 @@ inx
//FRAGMENT vbuyy=_inc_vbuaa
tay
iny
//FRAGMENT vwsz1=vwsc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT vwsz1=vwsz2_minus_vbsc1
lda {z2}
sec
@ -1215,6 +1147,22 @@ lda {z2}
sta {c1},y
lda {z2}+1
sta {c1}+1,y
//FRAGMENT pwsc1_derefidx_vbuaa=vwsz1
tay
lda {z1}
sta {c1},y
lda {z1}+1
sta {c1}+1,y
//FRAGMENT pwsc1_derefidx_vbuxx=vwsz1
lda {z1}
sta {c1},x
lda {z1}+1
sta {c1}+1,x
//FRAGMENT pwsc1_derefidx_vbuyy=vwsz1
lda {z1}
sta {c1},y
lda {z1}+1
sta {c1}+1,y
//FRAGMENT pvoz1=pvoc1
lda #<{c1}
sta {z1}
@ -2677,6 +2625,11 @@ sta {z1}
lda #>{c1}
sbc {z2}+1
sta {z1}+1
//FRAGMENT vwsz1=_inc_vwsz1
inc {z1}
bne !+
inc {z1}+1
!:
//FRAGMENT vwsz1_gt_vwsc1_then_la1
lda #<{c1}
cmp {z1}
@ -13376,6 +13329,333 @@ bne {la1}
lda {z2}
ldy #0
sta ({z1}),y
//FRAGMENT vbum1=_deref_pbuc1
lda {c1}
sta {m1}
//FRAGMENT vbum1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
sta {m1}
//FRAGMENT vbum1_eq_vbuc1_then_la1
lda #{c1}
cmp {m1}
beq {la1}
//FRAGMENT pbuz1_derefidx_vbum2=vbum3
lda {m3}
ldy {m2}
sta ({z1}),y
//FRAGMENT 0_eq_vbum1_then_la1
lda {m1}
beq {la1}
//FRAGMENT vbum1_neq_vbum2_then_la1
lda {m1}
cmp {m2}
bne {la1}
//FRAGMENT _stackpushbyte_=vbum1
lda {m1}
pha
//FRAGMENT vwum1=_word_vbum2
lda {m2}
sta {m1}
lda #0
sta {m1}+1
//FRAGMENT vwum1=vwum2_rol_2
lda {m2}
asl
sta {m1}
lda {m2}+1
rol
sta {m1}+1
asl {m1}
rol {m1}+1
//FRAGMENT vwum1=vwum2_plus_vwum3
lda {m2}
clc
adc {m3}
sta {m1}
lda {m2}+1
adc {m3}+1
sta {m1}+1
//FRAGMENT vwum1=vwum2_rol_3
lda {m2}
asl
sta {m1}
lda {m2}+1
rol
sta {m1}+1
asl {m1}
rol {m1}+1
asl {m1}
rol {m1}+1
//FRAGMENT pbuz1=pbuc1_plus_vwum2
lda {m2}
clc
adc #<{c1}
sta {z1}
lda {m2}+1
adc #>{c1}
sta {z1}+1
//FRAGMENT pbuz1_derefidx_vbum2=vbuc1
lda #{c1}
ldy {m2}
sta ({z1}),y
//FRAGMENT vbum1=vbum1_minus_vbuc1
lax {m1}
axs #{c1}
stx {m1}
//FRAGMENT vbum1=vbum1_plus_vbuc1
lax {m1}
axs #-[{c1}]
stx {m1}
//FRAGMENT vbum1=_deref_pbuz2
ldy #0
lda ({z2}),y
sta {m1}
//FRAGMENT 0_neq_vbum1_then_la1
lda {m1}
bne {la1}
//FRAGMENT vbum1=_dec_vbum1
dec {m1}
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbum2
ldy {m2}
lda {c1},y
ldy #0
sta ({z1}),y
//FRAGMENT vbum1=pbuc1_derefidx_vbum2
ldy {m2}
lda {c1},y
sta {m1}
//FRAGMENT vbum1_ge_vbum2_then_la1
lda {m1}
cmp {m2}
bcs {la1}
//FRAGMENT vwum1=vwum2
lda {m2}
sta {m1}
lda {m2}+1
sta {m1}+1
//FRAGMENT vbsm1=_sbyte_vwum2
lda {m2}
sta {m1}
//FRAGMENT vbsm1=_inc_vbsm1
inc {m1}
//FRAGMENT vbsm1=vbsc1_minus_vbsm2
lda #{c1}
sec
sbc {m2}
sta {m1}
//FRAGMENT vbsm1_ge_0_then_la1
lda {m1}
cmp #0
bpl {la1}
//FRAGMENT vbsm1=vbsc1
lda #{c1}
sta {m1}
//FRAGMENT 0_neq_vbsm1_then_la1
lda {m1}
cmp #0
bne {la1}
//FRAGMENT vbum1=vbum1_minus_vbum2
lda {m1}
sec
sbc {m2}
sta {m1}
//FRAGMENT vwum1=vwuc1
lda #<{c1}
sta {m1}
lda #>{c1}
sta {m1}+1
//FRAGMENT vwum1=_inc_vwum1
inc {m1}
bne !+
inc {m1}+1
!:
//FRAGMENT vbum1_lt_vbum2_then_la1
lda {m1}
cmp {m2}
bcc {la1}
//FRAGMENT pbuz1_derefidx_vbum2=vbuaa
ldy {m2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbum2=vbuxx
ldy {m2}
txa
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbum2=vbuyy
tya
ldy {m2}
sta ({z1}),y
//FRAGMENT vbum1_neq_vbuxx_then_la1
cpx {m1}
bne {la1}
//FRAGMENT vwum1=_word_vbuxx
txa
sta {m1}
lda #0
sta {m1}+1
//FRAGMENT vwum1=_word_vbuyy
tya
sta {m1}
lda #0
sta {m1}+1
//FRAGMENT pbuz1_derefidx_vbuxx=vbum2
txa
tay
lda {m2}
sta ({z1}),y
//FRAGMENT pbuz1_derefidx_vbuyy=vbum2
lda {m2}
sta ({z1}),y
//FRAGMENT vbuaa=pbuc1_derefidx_vbum1
ldy {m1}
lda {c1},y
//FRAGMENT vbuxx=pbuc1_derefidx_vbum1
ldy {m1}
ldx {c1},y
//FRAGMENT vbuyy=pbuc1_derefidx_vbum1
ldx {m1}
ldy {c1},x
//FRAGMENT vbum1=pbuc1_derefidx_vbuaa
tay
lda {c1},y
sta {m1}
//FRAGMENT vbum1=pbuc1_derefidx_vbuxx
lda {c1},x
sta {m1}
//FRAGMENT vbuaa_ge_vbum1_then_la1
cmp {m1}
bcs {la1}
//FRAGMENT vbsaa=_sbyte_vwum1
lda {m1}
//FRAGMENT vbsxx=_sbyte_vwum1
ldx {m1}
//FRAGMENT vbsm1=vbsc1_minus_vbsxx
txa
eor #$ff
sec
adc #{c1}
sta {m1}
//FRAGMENT vbsm1=vbsc1_minus_vbsyy
tya
eor #$ff
sec
adc #{c1}
sta {m1}
//FRAGMENT vbsaa=vbsc1_minus_vbsm1
lda #{c1}
sec
sbc {m1}
//FRAGMENT vbsaa=vbsc1_minus_vbsxx
txa
eor #$ff
sec
adc #{c1}
//FRAGMENT vbsaa=vbsc1_minus_vbsyy
tya
eor #$ff
sec
adc #{c1}
//FRAGMENT vbsxx=vbsc1_minus_vbsm1
lda #{c1}
sec
sbc {m1}
tax
//FRAGMENT vbsxx=vbsc1_minus_vbsxx
txa
eor #$ff
tax
axs #-{c1}-1
//FRAGMENT vbsxx=vbsc1_minus_vbsyy
tya
eor #$ff
tax
axs #-{c1}-1
//FRAGMENT vbsyy=vbsc1_minus_vbsm1
lda #{c1}
sec
sbc {m1}
tay
//FRAGMENT vbsyy=vbsc1_minus_vbsxx
txa
eor #$ff
sec
adc #{c1}
tay
//FRAGMENT vbsyy=vbsc1_minus_vbsyy
tya
eor #$ff
sec
adc #{c1}
tay
//FRAGMENT 0_neq_vbsaa_then_la1
cmp #0
bne {la1}
//FRAGMENT vbuxx=vbuxx_minus_vbum1
txa
sec
sbc {m1}
tax
//FRAGMENT vbum1=vbum1_minus_vbuaa
eor #$ff
sec
adc {m1}
sta {m1}
//FRAGMENT vbum1=vbum1_minus_vbuxx
txa
eor #$ff
sec
adc {m1}
sta {m1}
//FRAGMENT vbum1=vbum1_minus_vbuyy
tya
eor #$ff
sec
adc {m1}
sta {m1}
//FRAGMENT vbuxx_ge_vbum1_then_la1
cpx {m1}
bcs {la1}
//FRAGMENT vbum1_ge_vbuxx_then_la1
lda {m1}
stx $ff
cmp $ff
bcs {la1}
//FRAGMENT vbum1_ge_vbuyy_then_la1
lda {m1}
sty $ff
cmp $ff
bcs {la1}
//FRAGMENT vbuyy_ge_vbum1_then_la1
cpy {m1}
bcs {la1}
//FRAGMENT vbsyy=_sbyte_vwum1
ldy {m1}
//FRAGMENT vbsaa=vbsc1
lda #{c1}
//FRAGMENT 0_neq_vbsxx_then_la1
cpx #0
bne {la1}
//FRAGMENT vbsyy_ge_0_then_la1
cpy #0
bpl {la1}
//FRAGMENT 0_neq_vbsyy_then_la1
cpy #0
bne {la1}
//FRAGMENT vwum1=vwum2_plus_vwum1
clc
lda {m1}
adc {m2}
sta {m1}
lda {m1}+1
adc {m2}+1
sta {m1}+1
//FRAGMENT vwum1=vwum1_rol_3
asl {m1}
rol {m1}+1
asl {m1}
rol {m1}+1
asl {m1}
rol {m1}+1
//FRAGMENT _deref_pbuc1=_byte_pprz1
lda {z1}
sta {c1}
@ -13392,6 +13672,11 @@ lda ({z1}),y
sta !+ +2
!:
jsr $0000
//FRAGMENT vwsm1=vwsc1
lda #<{c1}
sta {m1}
lda #>{c1}
sta {m1}+1
//FRAGMENT vwsm1_lt_vbsc1_then_la1
NO_SYNTHESIS
//FRAGMENT vwsm1_lt_vwuc1_then_la1
@ -13411,6 +13696,17 @@ sta {m1}
lda {m2}
asl
sta {m1}
//FRAGMENT pwsc1_derefidx_vbum1=vwsm2
ldy {m1}
lda {m2}
sta {c1},y
lda {m2}+1
sta {c1}+1,y
//FRAGMENT vwsm1=_inc_vwsm1
inc {m1}
bne !+
inc {m1}+1
!:
//FRAGMENT vbuaa=_byte_vwsm1
lda {m1}
//FRAGMENT vbuxx=_byte_vwsm1
@ -13430,12 +13726,33 @@ tax
lda {m1}
asl
tay
//FRAGMENT vbum1=vbuaa_rol_1
asl
sta {m1}
//FRAGMENT vbum1=vbuxx_rol_1
txa
asl
sta {m1}
//FRAGMENT vbum1=vbuyy_rol_1
tya
asl
sta {m1}
//FRAGMENT pwsc1_derefidx_vbuaa=vwsm1
tay
lda {m1}
sta {c1},y
lda {m1}+1
sta {c1}+1,y
//FRAGMENT pwsc1_derefidx_vbuxx=vwsm1
lda {m1}
sta {c1},x
lda {m1}+1
sta {c1}+1,x
//FRAGMENT pwsc1_derefidx_vbuyy=vwsm1
lda {m1}
sta {c1},y
lda {m1}+1
sta {c1}+1,y
//FRAGMENT vbuz1=vbuz2_band_pbuz3_derefidx_vbuc1
lda {z2}
ldy #{c1}
@ -15691,6 +16008,48 @@ cmp {z1}
beq !+
bcs {la1}
!:
//FRAGMENT vbum1=vbuz2_rol_1
lda {z2}
asl
sta {m1}
//FRAGMENT pwsc1_derefidx_vbum1=vwsz2
ldy {m1}
lda {z2}
sta {c1},y
lda {z2}+1
sta {c1}+1,y
//FRAGMENT vwsm1=_inc_vwsz2
clc
lda {z2}
adc #1
sta {m1}
lda {z2}+1
adc #0
sta {m1}+1
//FRAGMENT vwsm1=_inc_vwsm2
clc
lda {m2}
adc #1
sta {m1}
lda {m2}+1
adc #0
sta {m1}+1
//FRAGMENT vwsz1=_inc_vwsm2
clc
lda {m2}
adc #1
sta {z1}
lda {m2}+1
adc #0
sta {z1}+1
//FRAGMENT vwsz1=_inc_vwsz2
clc
lda {z2}
adc #1
sta {z1}
lda {z2}+1
adc #0
sta {z1}+1
//FRAGMENT pbuz1=_dec_pbuz2
lda {z2}
sec
@ -16131,24 +16490,9 @@ tay
//FRAGMENT vbsyy_lt_0_then_la1
cpy #0
bmi {la1}
//FRAGMENT 0_neq_vbsaa_then_la1
cmp #0
bne {la1}
//FRAGMENT vbsaa=vbsc1
lda #{c1}
//FRAGMENT vbsaa=_inc_vbsaa
clc
adc #1
//FRAGMENT 0_neq_vbsxx_then_la1
cpx #0
bne {la1}
//FRAGMENT 0_neq_vbsyy_then_la1
cpy #0
bne {la1}
//FRAGMENT vbum1=vbum1_plus_vbuc1
lax {m1}
axs #-[{c1}]
stx {m1}
//FRAGMENT pbuc1_derefidx_vbum1=pbuc2_derefidx_vbum2
ldy {m2}
lda {c2},y
@ -16167,27 +16511,3 @@ sta {c1},x
lda #{c2}
ora {c1},y
sta {c1},y
//FRAGMENT vwsm1=_inc_vwsz2
clc
lda {z2}
adc #1
sta {m1}
lda {z2}+1
adc #0
sta {m1}+1
//FRAGMENT vwsm1=_inc_vwsm2
clc
lda {m2}
adc #1
sta {m1}
lda {m2}+1
adc #0
sta {m1}+1
//FRAGMENT vwsz1=_inc_vwsm2
clc
lda {m2}
adc #1
sta {z1}
lda {m2}+1
adc #0
sta {z1}+1

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 85a010c64 85a012cf9
//KICKC FRAGMENT CACHE 974006396 97400843e
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
inc {c1}
//FRAGMENT isr_hardware_all_entry

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 85a010c64 85a012cf9
//KICKC FRAGMENT CACHE 974006396 97400843e
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}

View File

@ -0,0 +1,7 @@
lda {c1},y
sta $fe
lda {c1}+1,y
sta $ff
jsr {la1}
{la1}: @outside_flow
jmp ($fe) @outside_flow

View File

@ -0,0 +1,8 @@
lda ({z1}),y
cmp #<{c1}
bne !+
iny
lda ({z1}),y
cmp #>{c1}
beq {la1}
!:

View File

@ -0,0 +1,6 @@
lda {c1},y
sta !+ +1
lda {c1}+1,y
sta !+ +2
!:
jsr $0000

View File

@ -9,6 +9,11 @@ import java.io.IOException;
*/
public class TestProgramsFast extends TestPrograms {
@Test
public void testStructFunction() throws IOException {
compileAndCompare("struct-function.c");
}
@Test
public void testStructWithHugeArray() throws IOException {
compileAndCompare("struct-with-huge-array.c");

View File

@ -0,0 +1,27 @@
#pragma struct_model(classic)
char * const SCREEN = (char*) 0x0400;
void file(void) {
SCREEN[0] = 'f';
}
void exit(void) {
SCREEN[1] = 'x';
}
struct MENU_ITEM {
char* text;
void (*code)(void);
};
struct MENU_ITEM menu[] = {
{ "File", &file },
{ "Exit", &exit }
};
void main() {
for(char i=0;i<2;i++) {
(*(menu[i].code))();
}
}

View File

@ -0,0 +1,58 @@
// Commodore 64 PRG executable file
.file [name="struct-function.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const OFFSET_STRUCT_MENU_ITEM_CODE = 2
.label SCREEN = $400
.segment Code
main: {
.label i = 2
lda #0
sta.z i
__b1:
// for(char i=0;i<2;i++)
lda.z i
cmp #2
bcc __b2
// }
rts
__b2:
// (*(menu[i].code))()
lda.z i
asl
asl
tay
lda menu+OFFSET_STRUCT_MENU_ITEM_CODE,y
sta !+ +1
lda menu+OFFSET_STRUCT_MENU_ITEM_CODE+1,y
sta !+ +2
!:
jsr 0
// for(char i=0;i<2;i++)
inc.z i
jmp __b1
}
exit: {
// SCREEN[1] = 'x'
lda #'x'
sta SCREEN+1
// }
rts
}
file: {
// SCREEN[0] = 'f'
lda #'f'
sta SCREEN
// }
rts
}
.segment Data
menu: .word menu_item_text, file, menu_item_text1, exit
menu_item_text: .text "File"
.byte 0
menu_item_text1: .text "Exit"
.byte 0

View File

@ -0,0 +1,35 @@
void main()
main: scope:[main] from
[0] phi()
to:main::@1
main::@1: scope:[main] from main main::@3
[1] main::i#2 = phi( main/0, main::@3/main::i#1 )
[2] if(main::i#2<2) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
main::@2: scope:[main] from main::@1
[4] main::$2 = main::i#2 << 2
[5] callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2])
to:main::@3
main::@3: scope:[main] from main::@2
[6] main::i#1 = ++ main::i#2
to:main::@1
void exit()
exit: scope:[exit] from
[7] *(SCREEN+1) = 'x'
to:exit::@return
exit::@return: scope:[exit] from exit
[8] return
to:@return
void file()
file: scope:[file] from
[9] *SCREEN = 'f'
to:file::@return
file::@return: scope:[file] from file
[10] return
to:@return

View File

@ -0,0 +1,413 @@
Calling convention STACK_CALL adding prepare/execute/finalize for call *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2])
CONTROL FLOW GRAPH SSA
void file()
file: scope:[file] from
SCREEN[0] = 'f'
to:file::@return
file::@return: scope:[file] from file
return
to:@return
void exit()
exit: scope:[exit] from
SCREEN[1] = 'x'
to:exit::@return
exit::@return: scope:[exit] from exit
return
to:@return
void main()
main: scope:[main] from __start
main::i#0 = 0
to:main::@1
main::@1: scope:[main] from main main::@3
main::i#2 = phi( main/main::i#0, main::@3/main::i#1 )
main::$0 = main::i#2 < 2
if(main::$0) goto main::@2
to:main::@return
main::@2: scope:[main] from main::@1
main::i#3 = phi( main::@1/main::i#2 )
main::$2 = main::i#3 * SIZEOF_STRUCT_MENU_ITEM
callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2])
to:main::@3
main::@3: scope:[main] from main::@2
main::i#4 = phi( main::@2/main::i#3 )
main::i#1 = ++ main::i#4
to:main::@1
main::@return: scope:[main] from main::@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
__constant char OFFSET_STRUCT_MENU_ITEM_CODE = 2
__constant char * const SCREEN = (char *)$400
__constant char SIZEOF_STRUCT_MENU_ITEM = 4
void __start()
void exit()
void file()
void main()
bool main::$0
char main::$2
char main::i
char main::i#0
char main::i#1
char main::i#2
char main::i#3
char main::i#4
__constant struct MENU_ITEM menu[] = { { text: menu_item_text, code: &file }, { text: menu_item_text1, code: &exit } }
__constant char menu_item_text[5] = "File"
__constant char menu_item_text1[5] = "Exit"
Adding number conversion cast (unumber) 0 in SCREEN[0] = 'f'
Adding number conversion cast (unumber) 1 in SCREEN[1] = 'x'
Adding number conversion cast (unumber) 2 in main::$0 = main::i#2 < 2
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias main::i#2 = main::i#3 main::i#4
Successful SSA optimization Pass2AliasElimination
Simple Condition main::$0 [7] if(main::i#2<2) goto main::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [0] SCREEN[0] = 'f'
Successful SSA optimization PassNSimplifyExpressionWithZero
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
Rewriting multiplication to use shift [6] main::$2 = main::i#2 * SIZEOF_STRUCT_MENU_ITEM
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings main::i#0
Constant inlined main::i#0 = 0
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Eliminating unused constant SIZEOF_STRUCT_MENU_ITEM
Successful SSA optimization PassNEliminateUnusedVars
Adding NOP phi() at start of main
CALL GRAPH
Calls in [main] to null:5
Created 1 initial phi equivalence classes
Coalesced [7] main::i#5 = main::i#1
Coalesced down to 1 phi equivalence classes
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
to:main::@1
main::@1: scope:[main] from main main::@3
[1] main::i#2 = phi( main/0, main::@3/main::i#1 )
[2] if(main::i#2<2) goto main::@2
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
main::@2: scope:[main] from main::@1
[4] main::$2 = main::i#2 << 2
[5] callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2])
to:main::@3
main::@3: scope:[main] from main::@2
[6] main::i#1 = ++ main::i#2
to:main::@1
void exit()
exit: scope:[exit] from
[7] *(SCREEN+1) = 'x'
to:exit::@return
exit::@return: scope:[exit] from exit
[8] return
to:@return
void file()
file: scope:[file] from
[9] *SCREEN = 'f'
to:file::@return
file::@return: scope:[file] from file
[10] return
to:@return
VARIABLE REGISTER WEIGHTS
void exit()
void file()
void main()
char main::$2 // 110.0
char main::i
char main::i#1 // 22.0
char main::i#2 // 14.666666666666666
Initial phi equivalence classes
[ main::i#2 main::i#1 ]
Added variable main::$2 to live range equivalence class [ main::$2 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ main::$2 ]
Allocated zp[1]:2 [ main::$2 ]
Allocated zp[1]:3 [ main::i#2 main::i#1 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] main::$2 = main::i#2 << 2 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [5] callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2]) [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#2 main::i#1 ]
Removing always clobbered register reg byte x as potential for zp[1]:3 [ main::i#2 main::i#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:3 [ main::i#2 main::i#1 ]
Statement [7] *(SCREEN+1) = 'x' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [9] *SCREEN = 'f' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [2] if(main::i#2<2) goto main::@2 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a
Statement [4] main::$2 = main::i#2 << 2 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [5] callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2]) [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a reg byte x reg byte y
Statement [7] *(SCREEN+1) = 'x' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [9] *SCREEN = 'f' [ ] ( [ ] { } ) always clobbers reg byte a
Potential registers zp[1]:3 [ main::i#2 main::i#1 ] : zp[1]:3 ,
Potential registers zp[1]:2 [ main::$2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 110: zp[1]:2 [ main::$2 ] 36.67: zp[1]:3 [ main::i#2 main::i#1 ]
Uplift Scope [file]
Uplift Scope [exit]
Uplift Scope [MENU_ITEM]
Uplift Scope []
Uplifting [main] best 651 combination reg byte a [ main::$2 ] zp[1]:3 [ main::i#2 main::i#1 ]
Uplifting [file] best 651 combination
Uplifting [exit] best 651 combination
Uplifting [MENU_ITEM] best 651 combination
Uplifting [] best 651 combination
Attempting to uplift remaining variables inzp[1]:3 [ main::i#2 main::i#1 ]
Uplifting [main] best 651 combination zp[1]:3 [ main::i#2 main::i#1 ]
Allocated (was zp[1]:3) zp[1]:2 [ main::i#2 main::i#1 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Upstart
// Commodore 64 PRG executable file
.file [name="struct-function.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const OFFSET_STRUCT_MENU_ITEM_CODE = 2
.label SCREEN = $400
.segment Code
// main
main: {
.label i = 2
// [1] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta.z i
jmp __b1
// main::@1
__b1:
// [2] if(main::i#2<2) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z i
cmp #2
bcc __b2
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
// main::@2
__b2:
// [4] main::$2 = main::i#2 << 2 -- vbuaa=vbuz1_rol_2
lda.z i
asl
asl
// [5] callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2]) -- call__deref_(qprc1_derefidx_vbuaa)
tay
lda menu+OFFSET_STRUCT_MENU_ITEM_CODE,y
sta !+ +1
lda menu+OFFSET_STRUCT_MENU_ITEM_CODE+1,y
sta !+ +2
!:
jsr 0
jmp __b3
// main::@3
__b3:
// [6] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1
inc.z i
// [1] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
__b1_from___b3:
// [1] phi main::i#2 = main::i#1 [phi:main::@3->main::@1#0] -- register_copy
jmp __b1
}
// exit
exit: {
// [7] *(SCREEN+1) = 'x' -- _deref_pbuc1=vbuc2
lda #'x'
sta SCREEN+1
jmp __breturn
// exit::@return
__breturn:
// [8] return
rts
}
// file
file: {
// [9] *SCREEN = 'f' -- _deref_pbuc1=vbuc2
lda #'f'
sta SCREEN
jmp __breturn
// file::@return
__breturn:
// [10] return
rts
}
// File Data
.segment Data
menu: .word menu_item_text, file, menu_item_text1, exit
menu_item_text: .text "File"
.byte 0
menu_item_text1: .text "Exit"
.byte 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b3
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from_main:
Removing instruction __breturn:
Removing instruction __b3:
Removing instruction __b1_from___b3:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char OFFSET_STRUCT_MENU_ITEM_CODE = 2
__constant char * const SCREEN = (char *) 1024
void exit()
void file()
void main()
char main::$2 // reg byte a 110.0
char main::i
char main::i#1 // i zp[1]:2 22.0
char main::i#2 // i zp[1]:2 14.666666666666666
__constant struct MENU_ITEM menu[] = { { text: menu_item_text, code: &file }, { text: menu_item_text1, code: &exit } }
__constant char menu_item_text[5] = "File"
__constant char menu_item_text1[5] = "Exit"
zp[1]:2 [ main::i#2 main::i#1 ]
reg byte a [ main::$2 ]
FINAL ASSEMBLER
Score: 555
// File Comments
// Upstart
// Commodore 64 PRG executable file
.file [name="struct-function.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const OFFSET_STRUCT_MENU_ITEM_CODE = 2
.label SCREEN = $400
.segment Code
// main
main: {
.label i = 2
// [1] phi from main to main::@1 [phi:main->main::@1]
// [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0
sta.z i
// main::@1
__b1:
// for(char i=0;i<2;i++)
// [2] if(main::i#2<2) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z i
cmp #2
bcc __b2
// main::@return
// }
// [3] return
rts
// main::@2
__b2:
// (*(menu[i].code))()
// [4] main::$2 = main::i#2 << 2 -- vbuaa=vbuz1_rol_2
lda.z i
asl
asl
// [5] callexecute *(((void (**)())menu+OFFSET_STRUCT_MENU_ITEM_CODE)[main::$2]) -- call__deref_(qprc1_derefidx_vbuaa)
tay
lda menu+OFFSET_STRUCT_MENU_ITEM_CODE,y
sta !+ +1
lda menu+OFFSET_STRUCT_MENU_ITEM_CODE+1,y
sta !+ +2
!:
jsr 0
// main::@3
// for(char i=0;i<2;i++)
// [6] main::i#1 = ++ main::i#2 -- vbuz1=_inc_vbuz1
inc.z i
// [1] phi from main::@3 to main::@1 [phi:main::@3->main::@1]
// [1] phi main::i#2 = main::i#1 [phi:main::@3->main::@1#0] -- register_copy
jmp __b1
}
// exit
exit: {
// SCREEN[1] = 'x'
// [7] *(SCREEN+1) = 'x' -- _deref_pbuc1=vbuc2
lda #'x'
sta SCREEN+1
// exit::@return
// }
// [8] return
rts
}
// file
file: {
// SCREEN[0] = 'f'
// [9] *SCREEN = 'f' -- _deref_pbuc1=vbuc2
lda #'f'
sta SCREEN
// file::@return
// }
// [10] return
rts
}
// File Data
.segment Data
menu: .word menu_item_text, file, menu_item_text1, exit
menu_item_text: .text "File"
.byte 0
menu_item_text1: .text "Exit"
.byte 0

View File

@ -0,0 +1,15 @@
__constant char OFFSET_STRUCT_MENU_ITEM_CODE = 2
__constant char * const SCREEN = (char *) 1024
void exit()
void file()
void main()
char main::$2 // reg byte a 110.0
char main::i
char main::i#1 // i zp[1]:2 22.0
char main::i#2 // i zp[1]:2 14.666666666666666
__constant struct MENU_ITEM menu[] = { { text: menu_item_text, code: &file }, { text: menu_item_text1, code: &exit } }
__constant char menu_item_text[5] = "File"
__constant char menu_item_text1[5] = "Exit"
zp[1]:2 [ main::i#2 main::i#1 ]
reg byte a [ main::$2 ]