mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-17 00:30:07 +00:00
Added CPU-specific fragment caches. Using the caches when testing (for better performance). #469
This commit is contained in:
parent
9953c1d379
commit
558e19f47f
543
src/main/fragment/cache/fragment-cache-mos6502.asm
vendored
Normal file
543
src/main/fragment/cache/fragment-cache-mos6502.asm
vendored
Normal file
@ -0,0 +1,543 @@
|
|||||||
|
//FRAGMENT vbuz1=vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1_lt_vbuc1_then_la1
|
||||||
|
lda {z1}
|
||||||
|
cmp #{c1}
|
||||||
|
bcc {la1}
|
||||||
|
//FRAGMENT pbuc1_derefidx_vbuz1=vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
ldy {z1}
|
||||||
|
sta {c1},y
|
||||||
|
//FRAGMENT vbuz1=vbuz2_band_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
and {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1_neq_0_then_la1
|
||||||
|
lda {z1}
|
||||||
|
cmp #0
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT vbuz1=vbuz1_plus_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
clc
|
||||||
|
adc {z1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=_inc_vbuz1
|
||||||
|
inc {z1}
|
||||||
|
//FRAGMENT vbuaa_lt_vbuc1_then_la1
|
||||||
|
cmp #{c1}
|
||||||
|
bcc {la1}
|
||||||
|
//FRAGMENT pbuc1_derefidx_vbuaa=vbuc2
|
||||||
|
tay
|
||||||
|
lda #{c2}
|
||||||
|
sta {c1},y
|
||||||
|
//FRAGMENT pbuc1_derefidx_vbuxx=vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
sta {c1},x
|
||||||
|
//FRAGMENT pbuc1_derefidx_vbuyy=vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
sta {c1},y
|
||||||
|
//FRAGMENT vbuaa=vbuz1_band_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
and {z1}
|
||||||
|
//FRAGMENT vbuxx=vbuz1_band_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
and {z1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuz1_band_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
and {z1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuz1=vbuxx_band_vbuc1
|
||||||
|
txa
|
||||||
|
and #{c1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuxx_band_vbuc1
|
||||||
|
txa
|
||||||
|
and #{c1}
|
||||||
|
//FRAGMENT vbuxx=vbuxx_band_vbuc1
|
||||||
|
txa
|
||||||
|
and #{c1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuxx_band_vbuc1
|
||||||
|
txa
|
||||||
|
and #{c1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuz1=vbuyy_band_vbuc1
|
||||||
|
tya
|
||||||
|
and #{c1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuyy_band_vbuc1
|
||||||
|
tya
|
||||||
|
and #{c1}
|
||||||
|
//FRAGMENT vbuxx=vbuyy_band_vbuc1
|
||||||
|
tya
|
||||||
|
and #{c1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuyy_band_vbuc1
|
||||||
|
tya
|
||||||
|
and #{c1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuaa_neq_0_then_la1
|
||||||
|
cmp #0
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT vbuxx=vbuxx_plus_vbuc1
|
||||||
|
txa
|
||||||
|
clc
|
||||||
|
adc #{c1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuyy_plus_vbuc1
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc #{c1}
|
||||||
|
tay
|
||||||
|
//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 vbuxx_neq_0_then_la1
|
||||||
|
cpx #0
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT _deref_pbuc1=vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
sta {c1}
|
||||||
|
//FRAGMENT vbuz1=_deref_pbuc1_band_vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
and {c1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuc1_eq_vbuz1_then_la1
|
||||||
|
lda #{c1}
|
||||||
|
cmp {z1}
|
||||||
|
beq {la1}
|
||||||
|
//FRAGMENT vbuc1_neq_vbuz1_then_la1
|
||||||
|
lda #{c1}
|
||||||
|
cmp {z1}
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT vwuz1=vwuc1
|
||||||
|
lda #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pvoz1=pvoc1
|
||||||
|
lda #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT vwuz1=vbuc1
|
||||||
|
lda #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pbuz1=pbuc1
|
||||||
|
lda #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pbuz1=pbuc1_plus_vbuz2
|
||||||
|
lda {z2}
|
||||||
|
clc
|
||||||
|
adc #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
adc #0
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pvoz1=pvoz2
|
||||||
|
lda {z2}
|
||||||
|
sta {z1}
|
||||||
|
lda {z2}+1
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT vbuz1=vbuz1_plus_2
|
||||||
|
lda {z1}
|
||||||
|
clc
|
||||||
|
adc #2
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=_hi_pvoz2
|
||||||
|
lda {z2}+1
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT _deref_pbuc1=vbuz1
|
||||||
|
lda {z1}
|
||||||
|
sta {c1}
|
||||||
|
//FRAGMENT vbuz1=_lo_pvoz2
|
||||||
|
lda {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=_deref_pbuz2
|
||||||
|
ldy #0
|
||||||
|
lda ({z2}),y
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=pbuz2_derefidx_vbuc1
|
||||||
|
ldy #{c1}
|
||||||
|
lda ({z2}),y
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT pbuz1=pbuz2_plus_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
clc
|
||||||
|
adc {z2}
|
||||||
|
sta {z1}
|
||||||
|
lda #0
|
||||||
|
adc {z2}+1
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pbuz1_neq_pbuc1_then_la1
|
||||||
|
lda {z1}+1
|
||||||
|
cmp #>{c1}
|
||||||
|
bne {la1}
|
||||||
|
lda {z1}
|
||||||
|
cmp #<{c1}
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT _deref_pbuz1=_deref_pbuz2
|
||||||
|
ldy #0
|
||||||
|
lda ({z2}),y
|
||||||
|
ldy #0
|
||||||
|
sta ({z1}),y
|
||||||
|
//FRAGMENT pbuz1=_inc_pbuz1
|
||||||
|
inc {z1}
|
||||||
|
bne !+
|
||||||
|
inc {z1}+1
|
||||||
|
!:
|
||||||
|
//FRAGMENT vwuz1_lt_vwuz2_then_la1
|
||||||
|
lda {z1}+1
|
||||||
|
cmp {z2}+1
|
||||||
|
bcc {la1}
|
||||||
|
bne !+
|
||||||
|
lda {z1}
|
||||||
|
cmp {z2}
|
||||||
|
bcc {la1}
|
||||||
|
!:
|
||||||
|
//FRAGMENT vwuz1=_inc_vwuz1
|
||||||
|
inc {z1}
|
||||||
|
bne !+
|
||||||
|
inc {z1}+1
|
||||||
|
!:
|
||||||
|
//FRAGMENT vwuz1_lt_vwuc1_then_la1
|
||||||
|
lda {z1}+1
|
||||||
|
cmp #>{c1}
|
||||||
|
bcc {la1}
|
||||||
|
bne !+
|
||||||
|
lda {z1}
|
||||||
|
cmp #<{c1}
|
||||||
|
bcc {la1}
|
||||||
|
!:
|
||||||
|
//FRAGMENT vbuz1=vbuz2
|
||||||
|
lda {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
|
||||||
|
inc {c1}
|
||||||
|
//FRAGMENT _deref_pbuc1=_dec__deref_pbuc1
|
||||||
|
dec {c1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_rol_1
|
||||||
|
lda {z2}
|
||||||
|
asl
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuz3
|
||||||
|
lda {z2}
|
||||||
|
ora {z3}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=_deref_pbuc1_band_vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
and {c1}
|
||||||
|
//FRAGMENT vbuxx=_deref_pbuc1_band_vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
and {c1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=_deref_pbuc1_band_vbuc2
|
||||||
|
lda #{c2}
|
||||||
|
and {c1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuc1_eq_vbuaa_then_la1
|
||||||
|
cmp #{c1}
|
||||||
|
beq {la1}
|
||||||
|
//FRAGMENT vbuc1_neq_vbuxx_then_la1
|
||||||
|
cpx #{c1}
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT pbuz1=pbuc1_plus_vbuaa
|
||||||
|
clc
|
||||||
|
adc #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
adc #0
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pbuz1=pbuc1_plus_vbuxx
|
||||||
|
txa
|
||||||
|
clc
|
||||||
|
adc #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
adc #0
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT pbuz1=pbuc1_plus_vbuyy
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc #<{c1}
|
||||||
|
sta {z1}
|
||||||
|
lda #>{c1}
|
||||||
|
adc #0
|
||||||
|
sta {z1}+1
|
||||||
|
//FRAGMENT vbuxx=vbuxx_plus_2
|
||||||
|
inx
|
||||||
|
inx
|
||||||
|
//FRAGMENT vbuaa=_hi_pvoz1
|
||||||
|
lda {z1}+1
|
||||||
|
//FRAGMENT vbuxx=_hi_pvoz1
|
||||||
|
lda {z1}+1
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=_hi_pvoz1
|
||||||
|
lda {z1}+1
|
||||||
|
tay
|
||||||
|
//FRAGMENT _deref_pbuc1=vbuaa
|
||||||
|
sta {c1}
|
||||||
|
//FRAGMENT vbuaa=_lo_pvoz1
|
||||||
|
lda {z1}
|
||||||
|
//FRAGMENT vbuxx=_lo_pvoz1
|
||||||
|
lda {z1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=_lo_pvoz1
|
||||||
|
lda {z1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuaa=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda ({z1}),y
|
||||||
|
//FRAGMENT vbuxx=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda ({z1}),y
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=_deref_pbuz1
|
||||||
|
ldy #0
|
||||||
|
lda ({z1}),y
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuaa=pbuz1_derefidx_vbuc1
|
||||||
|
ldy #{c1}
|
||||||
|
lda ({z1}),y
|
||||||
|
//FRAGMENT vbuxx=pbuz1_derefidx_vbuc1
|
||||||
|
ldy #{c1}
|
||||||
|
lda ({z1}),y
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=pbuz1_derefidx_vbuc1
|
||||||
|
ldy #{c1}
|
||||||
|
lda ({z1}),y
|
||||||
|
tay
|
||||||
|
//FRAGMENT _deref_pbuc1=vbuxx
|
||||||
|
stx {c1}
|
||||||
|
//FRAGMENT vbuz1=vbuaa
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuz1
|
||||||
|
lda {z1}
|
||||||
|
//FRAGMENT vbuxx=vbuz1
|
||||||
|
ldx {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuaa_band_vbuc1
|
||||||
|
and #{c1}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuaa_band_vbuc1
|
||||||
|
and #{c1}
|
||||||
|
//FRAGMENT vbuxx=vbuaa_band_vbuc1
|
||||||
|
and #{c1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuaa_band_vbuc1
|
||||||
|
and #{c1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuz1=vbuaa_rol_1
|
||||||
|
asl
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuxx_rol_1
|
||||||
|
txa
|
||||||
|
asl
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuyy_rol_1
|
||||||
|
tya
|
||||||
|
asl
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuz1_rol_1
|
||||||
|
lda {z1}
|
||||||
|
asl
|
||||||
|
//FRAGMENT vbuaa=vbuaa_rol_1
|
||||||
|
asl
|
||||||
|
//FRAGMENT vbuaa=vbuxx_rol_1
|
||||||
|
txa
|
||||||
|
asl
|
||||||
|
//FRAGMENT vbuaa=vbuyy_rol_1
|
||||||
|
tya
|
||||||
|
asl
|
||||||
|
//FRAGMENT vbuxx=vbuz1_rol_1
|
||||||
|
lda {z1}
|
||||||
|
asl
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuaa_rol_1
|
||||||
|
asl
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuxx_rol_1
|
||||||
|
txa
|
||||||
|
asl
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuyy_rol_1
|
||||||
|
tya
|
||||||
|
asl
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuz1_rol_1
|
||||||
|
lda {z1}
|
||||||
|
asl
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuaa_rol_1
|
||||||
|
asl
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuxx_rol_1
|
||||||
|
txa
|
||||||
|
asl
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuyy_rol_1
|
||||||
|
tya
|
||||||
|
asl
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuz2
|
||||||
|
txa
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuyy_bor_vbuz2
|
||||||
|
tya
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuaa
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuaa
|
||||||
|
stx $ff
|
||||||
|
ora $ff
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuyy_bor_vbuaa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuxx
|
||||||
|
txa
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuxx
|
||||||
|
stx {z1}
|
||||||
|
//FRAGMENT _deref_pbuc1=vbuyy
|
||||||
|
sty {c1}
|
||||||
|
//FRAGMENT vbuc1_neq_vbuyy_then_la1
|
||||||
|
cpy #{c1}
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT vbuc1_eq_vbuxx_then_la1
|
||||||
|
cpx #{c1}
|
||||||
|
beq {la1}
|
||||||
|
//FRAGMENT vbuc1_eq_vbuyy_then_la1
|
||||||
|
cpy #{c1}
|
||||||
|
beq {la1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuyy
|
||||||
|
tya
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
//FRAGMENT vbuaa=vbuz1_bor_vbuz2
|
||||||
|
lda {z1}
|
||||||
|
ora {z2}
|
||||||
|
//FRAGMENT vbuaa=vbuz1_bor_vbuaa
|
||||||
|
ora {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuz1_bor_vbuxx
|
||||||
|
txa
|
||||||
|
ora {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuz1_bor_vbuyy
|
||||||
|
tya
|
||||||
|
ora {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuxx
|
||||||
|
stx {z1}
|
||||||
|
//FRAGMENT vbuxx=vbuz1_bor_vbuz2
|
||||||
|
lda {z1}
|
||||||
|
ora {z2}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuz1_bor_vbuaa
|
||||||
|
ora {z1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuz1_bor_vbuxx
|
||||||
|
txa
|
||||||
|
ora {z1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuz1_bor_vbuyy
|
||||||
|
tya
|
||||||
|
ora {z1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuz1=vbuyy
|
||||||
|
sty {z1}
|
||||||
|
//FRAGMENT vbuyy=vbuz1_bor_vbuz2
|
||||||
|
lda {z1}
|
||||||
|
ora {z2}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuz1_bor_vbuaa
|
||||||
|
ora {z1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuz1_bor_vbuxx
|
||||||
|
txa
|
||||||
|
ora {z1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuz1_bor_vbuyy
|
||||||
|
tya
|
||||||
|
ora {z1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuyy
|
||||||
|
txa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuxx_bor_vbuz1
|
||||||
|
txa
|
||||||
|
ora {z1}
|
||||||
|
//FRAGMENT vbuaa=vbuxx_bor_vbuaa
|
||||||
|
stx $ff
|
||||||
|
ora $ff
|
||||||
|
//FRAGMENT vbuaa=vbuxx_bor_vbuyy
|
||||||
|
txa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
//FRAGMENT vbuxx=vbuxx_bor_vbuz1
|
||||||
|
txa
|
||||||
|
ora {z1}
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuxx_bor_vbuaa
|
||||||
|
stx $ff
|
||||||
|
ora $ff
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuxx=vbuxx_bor_vbuyy
|
||||||
|
txa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuxx_bor_vbuz1
|
||||||
|
txa
|
||||||
|
ora {z1}
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuxx_bor_vbuaa
|
||||||
|
stx $ff
|
||||||
|
ora $ff
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy=vbuxx_bor_vbuyy
|
||||||
|
txa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuaa=vbuyy_bor_vbuaa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
//FRAGMENT vbuxx=vbuaa
|
||||||
|
tax
|
||||||
|
//FRAGMENT vbuyy=vbuaa
|
||||||
|
tay
|
||||||
|
//FRAGMENT vbuyy_neq_0_then_la1
|
||||||
|
cpy #0
|
||||||
|
bne {la1}
|
||||||
|
//FRAGMENT pbuz1=pbuz1_plus_vbuc1
|
||||||
|
lda #{c1}
|
||||||
|
clc
|
||||||
|
adc {z1}
|
||||||
|
sta {z1}
|
||||||
|
bcc !+
|
||||||
|
inc {z1}+1
|
||||||
|
!:
|
17689
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
Normal file
17689
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,11 @@
|
|||||||
package dk.camelot64.kickc;
|
package dk.camelot64.kickc;
|
||||||
|
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateMasterSynthesizer;
|
||||||
import dk.camelot64.kickc.model.*;
|
import dk.camelot64.kickc.model.Comment;
|
||||||
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
|
import dk.camelot64.kickc.model.Program;
|
||||||
|
import dk.camelot64.kickc.model.StatementSequence;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||||
@ -95,16 +98,12 @@ public class Compiler {
|
|||||||
program.setAsmFragmentBaseFolder(asmFragmentBaseFolder);
|
program.setAsmFragmentBaseFolder(asmFragmentBaseFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAsmFragmentCacheFolder(Path asmFragmentcacheDir) {
|
public void setAsmFragmentCacheFolder(Path asmFragmentCacheDir) {
|
||||||
program.setAsmFragmentCacheFolder(asmFragmentcacheDir);
|
program.setAsmFragmentCacheFolder(asmFragmentCacheDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initAsmFragmentSynthesizer(AsmFragmentTemplateSynthesizer synthesizer) {
|
public AsmFragmentTemplateMasterSynthesizer getAsmFragmentMasterSynthesizer() {
|
||||||
program.initAsmFragmentSynthesizer(synthesizer);
|
return program.getAsmFragmentMasterSynthesizer();
|
||||||
}
|
|
||||||
|
|
||||||
public AsmFragmentTemplateSynthesizer getAsmFragmentSynthesizer() {
|
|
||||||
return program.getAsmFragmentSynthesizer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLog(CompileLog compileLog) {
|
public void setLog(CompileLog compileLog) {
|
||||||
|
@ -2,6 +2,8 @@ package dk.camelot64.kickc;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
||||||
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateMasterSynthesizer;
|
||||||
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateUsages;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateUsages;
|
||||||
import dk.camelot64.kickc.model.*;
|
import dk.camelot64.kickc.model.*;
|
||||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||||
@ -228,6 +230,10 @@ public class KickC implements Callable<Integer> {
|
|||||||
compiler.setAsmFragmentCacheFolder(fragmentCacheDir);
|
compiler.setAsmFragmentCacheFolder(fragmentCacheDir);
|
||||||
|
|
||||||
Program program = compiler.getProgram();
|
Program program = compiler.getProgram();
|
||||||
|
|
||||||
|
// Initialize the master ASM fragment synthesizer
|
||||||
|
program.initAsmFragmentMasterSynthesizer();
|
||||||
|
|
||||||
Path currentPath = new File(".").toPath();
|
Path currentPath = new File(".").toPath();
|
||||||
|
|
||||||
// Set up Target Platform
|
// Set up Target Platform
|
||||||
@ -256,14 +262,15 @@ public class KickC implements Callable<Integer> {
|
|||||||
TargetCpu targetCpu = TargetCpu.getTargetCpu(cpu, false);
|
TargetCpu targetCpu = TargetCpu.getTargetCpu(cpu, false);
|
||||||
program.getTargetPlatform().setCpu(targetCpu);
|
program.getTargetPlatform().setCpu(targetCpu);
|
||||||
}
|
}
|
||||||
program.initAsmFragmentSynthesizer();
|
|
||||||
|
|
||||||
if(fragment != null) {
|
if(fragment != null) {
|
||||||
if(verbose) {
|
if(verbose) {
|
||||||
compiler.getLog().setVerboseFragmentLog(true);
|
compiler.getLog().setVerboseFragmentLog(true);
|
||||||
}
|
}
|
||||||
compiler.getLog().setSysOut(true);
|
compiler.getLog().setSysOut(true);
|
||||||
Collection<AsmFragmentTemplate> fragmentTemplates = compiler.getAsmFragmentSynthesizer().getBestTemplates(fragment, compiler.getLog());
|
final AsmFragmentTemplateMasterSynthesizer masterSynthesizer = compiler.getAsmFragmentMasterSynthesizer();
|
||||||
|
final AsmFragmentTemplateSynthesizer cpuSynthesizer = masterSynthesizer.getSynthesizer(program.getTargetCpu());
|
||||||
|
Collection<AsmFragmentTemplate> fragmentTemplates = cpuSynthesizer.getBestTemplates(fragment, compiler.getLog());
|
||||||
for(AsmFragmentTemplate fragmentTemplate : fragmentTemplates) {
|
for(AsmFragmentTemplate fragmentTemplate : fragmentTemplates) {
|
||||||
AsmFragmentTemplateUsages.logTemplate(compiler.getLog(), fragmentTemplate, "");
|
AsmFragmentTemplateUsages.logTemplate(compiler.getLog(), fragmentTemplate, "");
|
||||||
}
|
}
|
||||||
@ -393,7 +400,8 @@ public class KickC implements Callable<Integer> {
|
|||||||
asmWriter.close();
|
asmWriter.close();
|
||||||
asmOutputStream.close();
|
asmOutputStream.close();
|
||||||
|
|
||||||
compiler.getAsmFragmentSynthesizer().finalize(compiler.getLog());
|
// Save the fragment synthesizer cache files
|
||||||
|
program.getAsmFragmentMasterSynthesizer().finalize(compiler.getLog());
|
||||||
|
|
||||||
// Copy Resource Files (if out-dir is different from in-dir)
|
// Copy Resource Files (if out-dir is different from in-dir)
|
||||||
if(!CFileDir.toAbsolutePath().equals(outputDir.toAbsolutePath())) {
|
if(!CFileDir.toAbsolutePath().equals(outputDir.toAbsolutePath())) {
|
||||||
|
@ -0,0 +1,170 @@
|
|||||||
|
package dk.camelot64.kickc.fragment;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.CompileLog;
|
||||||
|
import dk.camelot64.kickc.model.TargetCpu;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Cache for ASM fragments. The cache remembers all synthesized fragments allowing for faster access after the first synthesis. */
|
||||||
|
public class AsmFragmentTemplateCache {
|
||||||
|
|
||||||
|
/** The folder containing cached fragment files. */
|
||||||
|
private Path cacheFolder;
|
||||||
|
|
||||||
|
/** The Target CPU (each CPU has it's own cache). */
|
||||||
|
private TargetCpu cpu;
|
||||||
|
|
||||||
|
/** Cache for the best fragment templates. Maps signature to the best fragment template for the signature. Maps to NO_SYNTHESIS if synthesis was unsuccessful. */
|
||||||
|
private Map<String, AsmFragmentTemplate> cache;
|
||||||
|
|
||||||
|
/** Detects any modification of the cache. */
|
||||||
|
private boolean modified;
|
||||||
|
|
||||||
|
public AsmFragmentTemplateCache(Path cacheFolder, TargetCpu cpu, Map<String, AsmFragmentTemplate> cache) {
|
||||||
|
this.cacheFolder = cacheFolder;
|
||||||
|
this.cpu = cpu;
|
||||||
|
this.cache = cache;
|
||||||
|
this.modified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Special singleton representing that the fragment can not be synthesized or loaded. */
|
||||||
|
public static AsmFragmentTemplate NO_SYNTHESIS = new AsmFragmentTemplate("NO_SYNTHESIS", "NO_SYNTHESIS", false);
|
||||||
|
|
||||||
|
/** The prefix for header.lines in the fragment cache file. */
|
||||||
|
public static final String FRAGMENT_HEADER = "//FRAGMENT ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a cached ASM fragment template
|
||||||
|
*
|
||||||
|
* @param signature The signature
|
||||||
|
* @return The cached ASM fragment template. null if not in the cache. NO_SYNTHESIS if synthesis was unsuccessful.
|
||||||
|
*/
|
||||||
|
public AsmFragmentTemplate get(String signature) {
|
||||||
|
return cache.get(signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an ASM fragment template to the cache
|
||||||
|
*
|
||||||
|
* @param signature The signature
|
||||||
|
* @param asmFragmentTemplate The ASM fragment template. NO_SYNTHESIS if synthesis was unsuccessful.
|
||||||
|
*/
|
||||||
|
public void put(String signature, AsmFragmentTemplate asmFragmentTemplate) {
|
||||||
|
this.cache.put(signature, asmFragmentTemplate);
|
||||||
|
this.modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TargetCpu getCpu() {
|
||||||
|
return cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getCacheFileName(TargetCpu cpu) {
|
||||||
|
return "fragment-cache-" + cpu.getName() + ".asm";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to load a fragment cache containing all best synthesized fragments
|
||||||
|
*
|
||||||
|
* @param cacheFolder Folder containing the cache
|
||||||
|
* @param log The compile log
|
||||||
|
* @return The map with all best fragments from the cache file. null if the cache file is not found.
|
||||||
|
*/
|
||||||
|
public static AsmFragmentTemplateCache load(Path cacheFolder, TargetCpu cpu, CompileLog log) {
|
||||||
|
final Date before = new Date();
|
||||||
|
if(cacheFolder == null) {
|
||||||
|
return new AsmFragmentTemplateCache(null, cpu, new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
File cacheFile = cacheFolder.resolve(getCacheFileName(cpu)).toFile();
|
||||||
|
if(!cacheFile.exists()) {
|
||||||
|
return new AsmFragmentTemplateCache(cacheFolder, cpu, new LinkedHashMap<>());
|
||||||
|
}
|
||||||
|
LinkedHashMap<String, AsmFragmentTemplate> cache = new LinkedHashMap<>();
|
||||||
|
BufferedReader fragmentCacheReader = new BufferedReader(new FileReader(cacheFile));
|
||||||
|
String cacheLine = fragmentCacheReader.readLine();
|
||||||
|
StringBuilder body = null;
|
||||||
|
String signature = null;
|
||||||
|
while(cacheLine != null) {
|
||||||
|
// Determine if the line is a new fragment or the continuation of the current fragment body
|
||||||
|
if(cacheLine.startsWith(FRAGMENT_HEADER)) {
|
||||||
|
// New fragment - first put the current one into the cache
|
||||||
|
if(signature != null)
|
||||||
|
addFragment(cache, signature, body);
|
||||||
|
// Clear body and initialize signature
|
||||||
|
body = new StringBuilder();
|
||||||
|
signature = cacheLine.substring(FRAGMENT_HEADER.length());
|
||||||
|
} else {
|
||||||
|
// Continuation of body
|
||||||
|
body.append(cacheLine).append("\n");
|
||||||
|
}
|
||||||
|
cacheLine = fragmentCacheReader.readLine();
|
||||||
|
}
|
||||||
|
// Put the last fragment into the cache
|
||||||
|
if(signature != null)
|
||||||
|
addFragment(cache, signature, body);
|
||||||
|
final Date after = new Date();
|
||||||
|
final long millis = after.getTime() - before.getTime();
|
||||||
|
if(log.isVerboseFragmentLog())
|
||||||
|
log.append("Loaded cached fragments " + cache.size() + " from " + cacheFile.getPath() + " in " + millis + "ms");
|
||||||
|
return new AsmFragmentTemplateCache(cacheFolder, cpu, cache);
|
||||||
|
} catch(IOException e) {
|
||||||
|
throw new RuntimeException("Error loading fragment cache file " + cacheFolder, e);
|
||||||
|
} catch(StringIndexOutOfBoundsException e) {
|
||||||
|
throw new RuntimeException("Problem reading fragment file " + cacheFolder, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addFragment(LinkedHashMap<String, AsmFragmentTemplate> cache, String signature, StringBuilder body) {
|
||||||
|
final String bodyString = body.toString();
|
||||||
|
if(bodyString.startsWith(NO_SYNTHESIS.getBody())) {
|
||||||
|
cache.put(signature, NO_SYNTHESIS);
|
||||||
|
} else {
|
||||||
|
CharStream fragmentCharStream = CharStreams.fromString(bodyString);
|
||||||
|
AsmFragmentTemplate template = new AsmFragmentTemplate(signature, AsmFragmentTemplateSynthesizer.fixNewlines(fragmentCharStream.toString()), true);
|
||||||
|
cache.put(signature, template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to save fragment cache containing all best synthesized fragments
|
||||||
|
*
|
||||||
|
* @param log The compile log
|
||||||
|
*/
|
||||||
|
public void save(CompileLog log) {
|
||||||
|
if(!modified)
|
||||||
|
return;
|
||||||
|
if(this.cacheFolder == null)
|
||||||
|
return;
|
||||||
|
Date before = new Date();
|
||||||
|
File cacheFile = this.cacheFolder.resolve(getCacheFileName(cpu)).toFile();
|
||||||
|
try {
|
||||||
|
PrintStream fragmentFilePrint = new PrintStream(cacheFile);
|
||||||
|
for(String signature : this.cache.keySet()) {
|
||||||
|
AsmFragmentTemplate fragmentTemplate = this.cache.get(signature);
|
||||||
|
fragmentFilePrint.println(FRAGMENT_HEADER + signature);
|
||||||
|
if(fragmentTemplate==NO_SYNTHESIS) {
|
||||||
|
fragmentFilePrint.println(NO_SYNTHESIS.getBody());
|
||||||
|
} else {
|
||||||
|
if(fragmentTemplate.getBody() != null)
|
||||||
|
fragmentFilePrint.println(fragmentTemplate.getBody());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragmentFilePrint.close();
|
||||||
|
final Date after = new Date();
|
||||||
|
final long millis = after.getTime() - before.getTime();
|
||||||
|
if(log.isVerboseFragmentLog())
|
||||||
|
log.append("Saved cached fragments " + this.cache.size() + " to " + cacheFile.getPath() + " in " + millis + "ms");
|
||||||
|
} catch(IOException e) {
|
||||||
|
throw new RuntimeException("Error saving fragment cache file " + cacheFile, e);
|
||||||
|
} catch(StringIndexOutOfBoundsException e) {
|
||||||
|
throw new RuntimeException("Problem saving fragment file " + cacheFile, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package dk.camelot64.kickc.fragment;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.CompileLog;
|
||||||
|
import dk.camelot64.kickc.model.TargetCpu;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The master synthesizer handles the {@link AsmFragmentTemplateSynthesizer} for each used CPU
|
||||||
|
*/
|
||||||
|
public class AsmFragmentTemplateMasterSynthesizer {
|
||||||
|
|
||||||
|
/** Fragment base folder. */
|
||||||
|
private final Path baseFragmentFolder;
|
||||||
|
/** Fragment cache folder. */
|
||||||
|
private final Path cacheFolder;
|
||||||
|
/** Compile Log. */
|
||||||
|
private CompileLog log;
|
||||||
|
|
||||||
|
/** Synthesizers for all (used) CPU's */
|
||||||
|
private Map<TargetCpu, AsmFragmentTemplateSynthesizer> synthesizers;
|
||||||
|
|
||||||
|
/** Create master synthesizer. */
|
||||||
|
public AsmFragmentTemplateMasterSynthesizer(Path baseFragmentFolder, Path cacheFolder, CompileLog log) {
|
||||||
|
this.baseFragmentFolder = baseFragmentFolder;
|
||||||
|
this.cacheFolder = cacheFolder;
|
||||||
|
this.log = log;
|
||||||
|
this.synthesizers = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmFragmentTemplateSynthesizer getSynthesizer(TargetCpu targetCpu) {
|
||||||
|
AsmFragmentTemplateSynthesizer synthesizer = synthesizers.get(targetCpu);
|
||||||
|
if(synthesizer==null) {
|
||||||
|
synthesizer = new AsmFragmentTemplateSynthesizer(baseFragmentFolder, targetCpu, cacheFolder, log);
|
||||||
|
synthesizers.put(targetCpu, synthesizer);
|
||||||
|
}
|
||||||
|
return synthesizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Finalize the master fragment template synthesizer. */
|
||||||
|
public void finalize(CompileLog log) {
|
||||||
|
for(AsmFragmentTemplateSynthesizer synthesizer : synthesizers.values()) {
|
||||||
|
synthesizer.finalize(log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -5,7 +5,10 @@ import dk.camelot64.kickc.model.TargetCpu;
|
|||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -22,20 +25,13 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class AsmFragmentTemplateSynthesizer {
|
public class AsmFragmentTemplateSynthesizer {
|
||||||
|
|
||||||
/** Name of the file holding the fragment cache. */
|
|
||||||
public static final String FRAGMENT_CACHE_FILE = "fragment-cache.asm";
|
|
||||||
|
|
||||||
/** Create synthesizer. */
|
/** Create synthesizer. */
|
||||||
public AsmFragmentTemplateSynthesizer(Path baseFragmentFolder, TargetCpu cpu, Path cacheFolder, CompileLog log) {
|
public AsmFragmentTemplateSynthesizer(Path baseFragmentFolder, TargetCpu cpu, Path cacheFolder, CompileLog log) {
|
||||||
this.baseFragmentFolder = baseFragmentFolder;
|
this.baseFragmentFolder = baseFragmentFolder;
|
||||||
this.cpu = cpu;
|
this.cpu = cpu;
|
||||||
this.cacheFolder = cacheFolder;
|
|
||||||
this.synthesisGraph = new LinkedHashMap<>();
|
this.synthesisGraph = new LinkedHashMap<>();
|
||||||
this.bestTemplateUpdate = new ArrayDeque<>();
|
this.bestTemplateUpdate = new ArrayDeque<>();
|
||||||
this.bestFragmentCache = loadBestFragmentCache(cacheFolder, log);
|
this.fragmentCache = AsmFragmentTemplateCache.load(cacheFolder, cpu, log);
|
||||||
if(this.bestFragmentCache == null)
|
|
||||||
this.bestFragmentCache = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The folder containing fragment files. */
|
/** The folder containing fragment files. */
|
||||||
@ -44,14 +40,8 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
/** The Target CPU - used for obtaining CPU-specific fragment files. */
|
/** The Target CPU - used for obtaining CPU-specific fragment files. */
|
||||||
private TargetCpu cpu;
|
private TargetCpu cpu;
|
||||||
|
|
||||||
/** The folder containing cached fragment files. */
|
|
||||||
private Path cacheFolder;
|
|
||||||
|
|
||||||
/** Cache for the best fragment templates. Maps signature to the best fragment template for the signature. */
|
/** Cache for the best fragment templates. Maps signature to the best fragment template for the signature. */
|
||||||
private Map<String, AsmFragmentTemplate> bestFragmentCache;
|
private AsmFragmentTemplateCache fragmentCache;
|
||||||
|
|
||||||
/** Special singleton representing that the fragment can not be synthesized or loaded. */
|
|
||||||
private AsmFragmentTemplate NO_SYNTHESIS = new AsmFragmentTemplate("NO_SYNTHESIS", null, false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the synthesis for each fragment template signature.
|
* Contains the synthesis for each fragment template signature.
|
||||||
@ -63,8 +53,9 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
private Map<String, AsmFragmentSynthesis> synthesisGraph;
|
private Map<String, AsmFragmentSynthesis> synthesisGraph;
|
||||||
|
|
||||||
/** Finalize the fragment template synthesizer. */
|
/** Finalize the fragment template synthesizer. */
|
||||||
public void finalize(CompileLog log) {
|
void finalize(CompileLog log) {
|
||||||
saveBestFragmentCache(log);
|
if(fragmentCache != null)
|
||||||
|
fragmentCache.save(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,8 +88,8 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*/
|
*/
|
||||||
private AsmFragmentTemplate getFragmentTemplate(String signature, CompileLog log) {
|
private AsmFragmentTemplate getFragmentTemplate(String signature, CompileLog log) {
|
||||||
// Attempt to find in memory/disk cache
|
// Attempt to find in memory/disk cache
|
||||||
AsmFragmentTemplate bestTemplate = bestFragmentCache.get(signature);
|
AsmFragmentTemplate bestTemplate = fragmentCache.get(signature);
|
||||||
if(bestTemplate == NO_SYNTHESIS) {
|
if(bestTemplate == AsmFragmentTemplateCache.NO_SYNTHESIS) {
|
||||||
if(log.isVerboseFragmentLog()) {
|
if(log.isVerboseFragmentLog()) {
|
||||||
log.append("Unknown fragment " + signature);
|
log.append("Unknown fragment " + signature);
|
||||||
}
|
}
|
||||||
@ -111,7 +102,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
if(log.isVerboseFragmentLog()) {
|
if(log.isVerboseFragmentLog()) {
|
||||||
log.append("Unknown fragment " + signature);
|
log.append("Unknown fragment " + signature);
|
||||||
}
|
}
|
||||||
bestFragmentCache.put(signature, NO_SYNTHESIS);
|
fragmentCache.put(signature, AsmFragmentTemplateCache.NO_SYNTHESIS);
|
||||||
throw new UnknownFragmentException(signature);
|
throw new UnknownFragmentException(signature);
|
||||||
}
|
}
|
||||||
double minScore = Double.MAX_VALUE;
|
double minScore = Double.MAX_VALUE;
|
||||||
@ -128,94 +119,13 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
if(log.isVerboseFragmentLog()) {
|
if(log.isVerboseFragmentLog()) {
|
||||||
log.append("Found best fragment " + bestTemplate.getName() + " score: " + minScore);
|
log.append("Found best fragment " + bestTemplate.getName() + " score: " + minScore);
|
||||||
}
|
}
|
||||||
bestFragmentCache.put(signature, bestTemplate);
|
fragmentCache.put(signature, bestTemplate);
|
||||||
}
|
}
|
||||||
// Count usages
|
// Count usages
|
||||||
AsmFragmentTemplateUsages.incUsage(bestTemplate);
|
AsmFragmentTemplateUsages.incUsage(bestTemplate);
|
||||||
return bestTemplate;
|
return bestTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to load a fragment cache containing all best synthesized fragments
|
|
||||||
*
|
|
||||||
* @param cacheFolder Folder containing the cache
|
|
||||||
* @param log The compile log
|
|
||||||
* @return The map with all best fragments from the cache file. null if the cache file is not found.
|
|
||||||
*/
|
|
||||||
private Map<String, AsmFragmentTemplate> loadBestFragmentCache(Path cacheFolder, CompileLog log) {
|
|
||||||
final Date before = new Date();
|
|
||||||
if(cacheFolder == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
File cacheFile = cacheFolder.resolve(FRAGMENT_CACHE_FILE).toFile();
|
|
||||||
if(!cacheFile.exists()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
LinkedHashMap<String, AsmFragmentTemplate> bestFragmentCache = new LinkedHashMap<>();
|
|
||||||
BufferedReader fragmentCacheReader = new BufferedReader(new FileReader(cacheFile));
|
|
||||||
String cacheLine = fragmentCacheReader.readLine();
|
|
||||||
StringBuilder body = null;
|
|
||||||
String signature = null;
|
|
||||||
while(cacheLine != null) {
|
|
||||||
// Determine if the line is a new fragment or the continuation of the current fragment body
|
|
||||||
if(cacheLine.startsWith("//FRAGMENT ")) {
|
|
||||||
// New fragment - first put the current one into the cache
|
|
||||||
if(signature != null) {
|
|
||||||
CharStream fragmentCharStream = CharStreams.fromString(body.toString());
|
|
||||||
AsmFragmentTemplate template = new AsmFragmentTemplate(signature, fixNewlines(fragmentCharStream.toString()), true);
|
|
||||||
bestFragmentCache.put(signature, template);
|
|
||||||
}
|
|
||||||
body = new StringBuilder();
|
|
||||||
signature = cacheLine.substring(11);
|
|
||||||
} else {
|
|
||||||
// Continuation of body
|
|
||||||
body.append(cacheLine).append("\n");
|
|
||||||
}
|
|
||||||
cacheLine = fragmentCacheReader.readLine();
|
|
||||||
}
|
|
||||||
final Date after = new Date();
|
|
||||||
final long millis = after.getTime() - before.getTime();
|
|
||||||
if(log.isVerboseFragmentLog())
|
|
||||||
log.append("Loaded cached fragments " + bestFragmentCache.size() + " from " + cacheFile.getPath() + " in " + millis + "ms");
|
|
||||||
return bestFragmentCache;
|
|
||||||
} catch(IOException e) {
|
|
||||||
throw new RuntimeException("Error loading fragment cache file " + baseFragmentFolder, e);
|
|
||||||
} catch(StringIndexOutOfBoundsException e) {
|
|
||||||
throw new RuntimeException("Problem reading fragment file " + baseFragmentFolder, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to save fragment cache containing all best synthesized fragments
|
|
||||||
*
|
|
||||||
* @param log The compile log
|
|
||||||
*/
|
|
||||||
public void saveBestFragmentCache(CompileLog log) {
|
|
||||||
Date before = new Date();
|
|
||||||
if(this.cacheFolder == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
File cacheFile = this.cacheFolder.resolve(FRAGMENT_CACHE_FILE).toFile();
|
|
||||||
try {
|
|
||||||
PrintStream fragmentFilePrint = new PrintStream(cacheFile);
|
|
||||||
for(String signature : this.bestFragmentCache.keySet()) {
|
|
||||||
AsmFragmentTemplate fragmentTemplate = this.bestFragmentCache.get(signature);
|
|
||||||
fragmentFilePrint.println("//FRAGMENT " + signature);
|
|
||||||
if(fragmentTemplate.getBody() != null)
|
|
||||||
fragmentFilePrint.println(fragmentTemplate.getBody());
|
|
||||||
}
|
|
||||||
fragmentFilePrint.close();
|
|
||||||
final Date after = new Date();
|
|
||||||
final long millis = after.getTime() - before.getTime();
|
|
||||||
if(log.isVerboseFragmentLog())
|
|
||||||
log.append("Saved cached fragments " + this.bestFragmentCache.size() + " to " + cacheFile.getPath() + " in " + millis + "ms");
|
|
||||||
} catch(IOException e) {
|
|
||||||
throw new RuntimeException("Error saving fragment cache file " + cacheFile, e);
|
|
||||||
} catch(StringIndexOutOfBoundsException e) {
|
|
||||||
throw new RuntimeException("Problem saving fragment file " + cacheFile, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the best fragment templates for a signature.
|
* Get the best fragment templates for a signature.
|
||||||
@ -262,7 +172,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*
|
*
|
||||||
* @param signature The signature of the fragment template to load/synthesize
|
* @param signature The signature of the fragment template to load/synthesize
|
||||||
*/
|
*/
|
||||||
public AsmFragmentSynthesis(String signature) {
|
AsmFragmentSynthesis(String signature) {
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.bestTemplates = new LinkedHashMap<>();
|
this.bestTemplates = new LinkedHashMap<>();
|
||||||
this.synthesisOptions = new LinkedHashSet<>();
|
this.synthesisOptions = new LinkedHashSet<>();
|
||||||
@ -276,7 +186,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*
|
*
|
||||||
* @param synthesisOption The option to add
|
* @param synthesisOption The option to add
|
||||||
*/
|
*/
|
||||||
public void addSynthesisOption(AsmFragmentSynthesisOption synthesisOption) {
|
void addSynthesisOption(AsmFragmentSynthesisOption synthesisOption) {
|
||||||
this.synthesisOptions.add(synthesisOption);
|
this.synthesisOptions.add(synthesisOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +195,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*
|
*
|
||||||
* @return The options
|
* @return The options
|
||||||
*/
|
*/
|
||||||
public Collection<AsmFragmentSynthesisOption> getSynthesisOptions() {
|
Collection<AsmFragmentSynthesisOption> getSynthesisOptions() {
|
||||||
return synthesisOptions;
|
return synthesisOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,15 +204,15 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*
|
*
|
||||||
* @param synthesisOption Thew parent option to add
|
* @param synthesisOption Thew parent option to add
|
||||||
*/
|
*/
|
||||||
public void addParentOption(AsmFragmentSynthesisOption synthesisOption) {
|
void addParentOption(AsmFragmentSynthesisOption synthesisOption) {
|
||||||
this.parentOptions.add(synthesisOption);
|
this.parentOptions.add(synthesisOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFileTemplate(AsmFragmentTemplate fileTemplate) {
|
void addFileTemplate(AsmFragmentTemplate fileTemplate) {
|
||||||
this.fileTemplates.add(fileTemplate);
|
this.fileTemplates.add(fileTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AsmFragmentTemplate> getFileTemplates() {
|
List<AsmFragmentTemplate> getFileTemplates() {
|
||||||
return fileTemplates;
|
return fileTemplates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +223,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
* @param candidate The template candidate to examine
|
* @param candidate The template candidate to examine
|
||||||
* @return true if the best template was updated
|
* @return true if the best template was updated
|
||||||
*/
|
*/
|
||||||
public boolean bestTemplateCandidate(AsmFragmentTemplate candidate) {
|
boolean bestTemplateCandidate(AsmFragmentTemplate candidate) {
|
||||||
AsmFragmentClobber candidateClobber = candidate.getClobber();
|
AsmFragmentClobber candidateClobber = candidate.getClobber();
|
||||||
double candidateCycles = candidate.getCycles();
|
double candidateCycles = candidate.getCycles();
|
||||||
|
|
||||||
@ -370,7 +280,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*
|
*
|
||||||
* @return The parent options.
|
* @return The parent options.
|
||||||
*/
|
*/
|
||||||
public Set<AsmFragmentSynthesisOption> getParentOptions() {
|
Set<AsmFragmentSynthesisOption> getParentOptions() {
|
||||||
return parentOptions;
|
return parentOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +290,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
*
|
*
|
||||||
* @return The best templates of the synthesis.
|
* @return The best templates of the synthesis.
|
||||||
*/
|
*/
|
||||||
public Collection<AsmFragmentTemplate> getBestTemplates() {
|
Collection<AsmFragmentTemplate> getBestTemplates() {
|
||||||
return bestTemplates.values();
|
return bestTemplates.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +317,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
* @param signature he signature of the fragment template being synthesized.
|
* @param signature he signature of the fragment template being synthesized.
|
||||||
* @param rule The synthesis rule capable of synthesizing this template from the sub-fragment.
|
* @param rule The synthesis rule capable of synthesizing this template from the sub-fragment.
|
||||||
*/
|
*/
|
||||||
public AsmFragmentSynthesisOption(String signature, AsmFragmentTemplateSynthesisRule rule) {
|
AsmFragmentSynthesisOption(String signature, AsmFragmentTemplateSynthesisRule rule) {
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.rule = rule;
|
this.rule = rule;
|
||||||
this.subSignature = rule.getSubSignature(signature);
|
this.subSignature = rule.getSubSignature(signature);
|
||||||
@ -417,11 +327,11 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSubSignature() {
|
String getSubSignature() {
|
||||||
return subSignature;
|
return subSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsmFragmentTemplateSynthesisRule getRule() {
|
AsmFragmentTemplateSynthesisRule getRule() {
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,20 +339,15 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if(this == o) return true;
|
if(this == o) return true;
|
||||||
if(o == null || getClass() != o.getClass()) return false;
|
if(o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
AsmFragmentSynthesisOption that = (AsmFragmentSynthesisOption) o;
|
AsmFragmentSynthesisOption that = (AsmFragmentSynthesisOption) o;
|
||||||
|
return Objects.equals(signature, that.signature) &&
|
||||||
if(signature != null ? !signature.equals(that.signature) : that.signature != null) return false;
|
Objects.equals(subSignature, that.subSignature) &&
|
||||||
if(subSignature != null ? !subSignature.equals(that.subSignature) : that.subSignature != null) return false;
|
Objects.equals(rule, that.rule);
|
||||||
return rule != null ? rule.equals(that.rule) : that.rule == null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = signature != null ? signature.hashCode() : 0;
|
return Objects.hash(signature, subSignature, rule);
|
||||||
result = 31 * result + (subSignature != null ? subSignature.hashCode() : 0);
|
|
||||||
result = 31 * result + (rule != null ? rule.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,13 +394,11 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
synthesisGraph.put(signature, synthesis);
|
synthesisGraph.put(signature, synthesis);
|
||||||
queueUpdateBestTemplate(synthesis);
|
queueUpdateBestTemplate(synthesis);
|
||||||
// Load the template from file - if it exists
|
// Load the template from file - if it exists
|
||||||
List<AsmFragmentTemplate> fileTemplates = loadFragmentTemplates(signature, log);
|
List<AsmFragmentTemplate> fileTemplates = loadFragmentTemplates(signature);
|
||||||
if(fileTemplates != null) {
|
for(AsmFragmentTemplate fileTemplate : fileTemplates) {
|
||||||
for(AsmFragmentTemplate fileTemplate : fileTemplates) {
|
synthesis.addFileTemplate(fileTemplate);
|
||||||
synthesis.addFileTemplate(fileTemplate);
|
if(log.isVerboseFragmentLog()) {
|
||||||
if(log.isVerboseFragmentLog()) {
|
log.append("New fragment synthesis " + signature + " - Successfully loaded " + signature + ".asm");
|
||||||
log.append("New fragment synthesis " + signature + " - Successfully loaded " + signature + ".asm");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Populate with synthesis options
|
// Populate with synthesis options
|
||||||
@ -535,7 +438,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
* During the update more items can be added to the work queue.
|
* During the update more items can be added to the work queue.
|
||||||
* Returns when the work queue is empty.
|
* Returns when the work queue is empty.
|
||||||
*/
|
*/
|
||||||
void updateBestTemplates(CompileLog log) {
|
private void updateBestTemplates(CompileLog log) {
|
||||||
while(!bestTemplateUpdate.isEmpty()) {
|
while(!bestTemplateUpdate.isEmpty()) {
|
||||||
AsmFragmentSynthesis synthesis = bestTemplateUpdate.pop();
|
AsmFragmentSynthesis synthesis = bestTemplateUpdate.pop();
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
@ -591,10 +494,9 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
* Attempt to load a fragment template from disk. Also searches relevant fragment sub-folders specified by CPU and other options.
|
* Attempt to load a fragment template from disk. Also searches relevant fragment sub-folders specified by CPU and other options.
|
||||||
*
|
*
|
||||||
* @param signature The signature
|
* @param signature The signature
|
||||||
* @param log The compile log
|
|
||||||
* @return The fragment template from a file. null if the template is not found as a file.
|
* @return The fragment template from a file. null if the template is not found as a file.
|
||||||
*/
|
*/
|
||||||
private List<AsmFragmentTemplate> loadFragmentTemplates(String signature, CompileLog log) {
|
private List<AsmFragmentTemplate> loadFragmentTemplates(String signature) {
|
||||||
ArrayList<AsmFragmentTemplate> fileTemplates = new ArrayList<>();
|
ArrayList<AsmFragmentTemplate> fileTemplates = new ArrayList<>();
|
||||||
List<TargetCpu.Feature> cpuFeatures = cpu.getFeatures();
|
List<TargetCpu.Feature> cpuFeatures = cpu.getFeatures();
|
||||||
for(TargetCpu.Feature cpuFeature : cpuFeatures) {
|
for(TargetCpu.Feature cpuFeature : cpuFeatures) {
|
||||||
@ -643,7 +545,7 @@ public class AsmFragmentTemplateSynthesizer {
|
|||||||
* @param body The body
|
* @param body The body
|
||||||
* @return The body with fixed newlines
|
* @return The body with fixed newlines
|
||||||
*/
|
*/
|
||||||
private String fixNewlines(String body) {
|
static String fixNewlines(String body) {
|
||||||
body = body.replace("\r", "");
|
body = body.replace("\r", "");
|
||||||
while(body.length() > 0 && body.charAt(body.length() - 1) == '\n') {
|
while(body.length() > 0 && body.charAt(body.length() - 1) == '\n') {
|
||||||
body = body.substring(0, body.length() - 1);
|
body = body.substring(0, body.length() - 1);
|
||||||
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.model;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.CompileLog;
|
import dk.camelot64.kickc.CompileLog;
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateMasterSynthesizer;
|
||||||
import dk.camelot64.kickc.model.statements.Statement;
|
import dk.camelot64.kickc.model.statements.Statement;
|
||||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
import dk.camelot64.kickc.model.values.LabelRef;
|
import dk.camelot64.kickc.model.values.LabelRef;
|
||||||
@ -38,7 +38,7 @@ public class Program {
|
|||||||
/** Cache folder for finding ASM fragment files. (STATIC) */
|
/** Cache folder for finding ASM fragment files. (STATIC) */
|
||||||
private Path asmFragmentCacheFolder;
|
private Path asmFragmentCacheFolder;
|
||||||
/** The ASM fragment synthesizer responsible for loading/synthesizing ASM fragments. Depends on the target CPU. (STATIC) */
|
/** The ASM fragment synthesizer responsible for loading/synthesizing ASM fragments. Depends on the target CPU. (STATIC) */
|
||||||
private AsmFragmentTemplateSynthesizer asmFragmentSynthesizer;
|
private AsmFragmentTemplateMasterSynthesizer asmFragmentMasterSynthesizer;
|
||||||
|
|
||||||
/** Missing fragments produce a warning instead of an error (STATIC) */
|
/** Missing fragments produce a warning instead of an error (STATIC) */
|
||||||
private boolean warnFragmentMissing = false;
|
private boolean warnFragmentMissing = false;
|
||||||
@ -208,16 +208,12 @@ public class Program {
|
|||||||
this.asmFragmentBaseFolder = asmFragmentBaseFolder;
|
this.asmFragmentBaseFolder = asmFragmentBaseFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsmFragmentTemplateSynthesizer getAsmFragmentSynthesizer() {
|
public AsmFragmentTemplateMasterSynthesizer getAsmFragmentMasterSynthesizer() {
|
||||||
return asmFragmentSynthesizer;
|
return asmFragmentMasterSynthesizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initAsmFragmentSynthesizer() {
|
public void initAsmFragmentMasterSynthesizer() {
|
||||||
this.asmFragmentSynthesizer = new AsmFragmentTemplateSynthesizer(asmFragmentBaseFolder, targetPlatform.getCpu(), asmFragmentCacheFolder, getLog());
|
this.asmFragmentMasterSynthesizer = new AsmFragmentTemplateMasterSynthesizer(asmFragmentBaseFolder, asmFragmentCacheFolder, getLog());
|
||||||
}
|
|
||||||
|
|
||||||
public void initAsmFragmentSynthesizer(AsmFragmentTemplateSynthesizer synthesizer) {
|
|
||||||
this.asmFragmentSynthesizer = synthesizer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetPlatform getTargetPlatform() {
|
public TargetPlatform getTargetPlatform() {
|
||||||
|
@ -246,8 +246,6 @@ public class CParser {
|
|||||||
define(macroName, program.getTargetPlatform().getDefines().get(macroName));
|
define(macroName, program.getTargetPlatform().getDefines().get(macroName));
|
||||||
// Add reserved ZP's from new platform
|
// Add reserved ZP's from new platform
|
||||||
program.addReservedZps(program.getTargetPlatform().getReservedZps());
|
program.addReservedZps(program.getTargetPlatform().getReservedZps());
|
||||||
// Re-initialize ASM fragment synthesizer
|
|
||||||
program.initAsmFragmentSynthesizer();
|
|
||||||
} else {
|
} else {
|
||||||
StringBuilder supported = new StringBuilder();
|
StringBuilder supported = new StringBuilder();
|
||||||
final List<File> platformFiles = SourceLoader.listFiles(currentPath, program.getTargetPlatformPaths(), CTargetPlatformParser.FILE_EXTENSION);
|
final List<File> platformFiles = SourceLoader.listFiles(currentPath, program.getTargetPlatformPaths(), CTargetPlatformParser.FILE_EXTENSION);
|
||||||
|
@ -188,7 +188,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
final String cpuName = ctx.NAME().getText();
|
final String cpuName = ctx.NAME().getText();
|
||||||
TargetCpu cpu = TargetCpu.getTargetCpu(cpuName, false);
|
TargetCpu cpu = TargetCpu.getTargetCpu(cpuName, false);
|
||||||
program.getTargetPlatform().setCpu(cpu);
|
program.getTargetPlatform().setCpu(cpu);
|
||||||
program.initAsmFragmentSynthesizer();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,7 +958,8 @@ public class Pass4CodeGeneration {
|
|||||||
StringBuilder fragmentVariationsTried = new StringBuilder();
|
StringBuilder fragmentVariationsTried = new StringBuilder();
|
||||||
while(fragmentInstance == null) {
|
while(fragmentInstance == null) {
|
||||||
try {
|
try {
|
||||||
fragmentInstance = program.getAsmFragmentSynthesizer().getFragmentInstance(fragmentInstanceSpec, program.getLog());
|
final AsmFragmentTemplateSynthesizer cpuSynthesizer = program.getAsmFragmentMasterSynthesizer().getSynthesizer(program.getTargetCpu());
|
||||||
|
fragmentInstance = cpuSynthesizer.getFragmentInstance(fragmentInstanceSpec, program.getLog());
|
||||||
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
|
} catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) {
|
||||||
// Unknown fragment - keep looking through alternative ASM fragment instance specs until we have tried them all
|
// Unknown fragment - keep looking through alternative ASM fragment instance specs until we have tried them all
|
||||||
String signature = fragmentInstanceSpec.getSignature();
|
String signature = fragmentInstanceSpec.getSignature();
|
||||||
|
@ -7,7 +7,6 @@ import dk.camelot64.kickc.asm.AsmProgram;
|
|||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.TargetCpu;
|
|
||||||
import dk.camelot64.kickc.model.TargetPlatform;
|
import dk.camelot64.kickc.model.TargetPlatform;
|
||||||
import dk.camelot64.kickc.parser.CTargetPlatformParser;
|
import dk.camelot64.kickc.parser.CTargetPlatformParser;
|
||||||
import kickass.KickAssembler;
|
import kickass.KickAssembler;
|
||||||
@ -4307,9 +4306,9 @@ public class TestPrograms {
|
|||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() {
|
public static void setUp() {
|
||||||
Path asmFragmentBaseFolder = new File("src/main/fragment/").toPath();
|
//Path asmFragmentBaseFolder = new File("src/main/fragment/").toPath();
|
||||||
// Path asmFragmentCacheFolder = new File("src/main/fragment/cache").toPath();
|
//Path asmFragmentCacheFolder = new File("src/main/fragment/cache").toPath();
|
||||||
asmFragmentSynthesizer = new AsmFragmentTemplateSynthesizer(asmFragmentBaseFolder, TargetCpu.MOS6502X, null, new CompileLog());
|
//asmFragmentSynthesizer = new AsmFragmentTemplateSynthesizer(asmFragmentBaseFolder, TargetCpu.MOS6502X, asmFragmentCacheFolder, new CompileLog());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
@ -4403,7 +4402,7 @@ public class TestPrograms {
|
|||||||
Compiler compiler = new Compiler();
|
Compiler compiler = new Compiler();
|
||||||
compiler.setWarnFragmentMissing(true);
|
compiler.setWarnFragmentMissing(true);
|
||||||
compiler.setAsmFragmentBaseFolder(new File("src/main/fragment/").toPath());
|
compiler.setAsmFragmentBaseFolder(new File("src/main/fragment/").toPath());
|
||||||
compiler.setAsmFragmentCacheFolder(null);
|
compiler.setAsmFragmentCacheFolder(new File("src/main/fragment/cache/").toPath());
|
||||||
if(compileLog != null) {
|
if(compileLog != null) {
|
||||||
compiler.setLog(compileLog);
|
compiler.setLog(compileLog);
|
||||||
}
|
}
|
||||||
@ -4418,11 +4417,11 @@ public class TestPrograms {
|
|||||||
final Path filePath = Paths.get(fileName);
|
final Path filePath = Paths.get(fileName);
|
||||||
files.add(filePath);
|
files.add(filePath);
|
||||||
Program program = compiler.getProgram();
|
Program program = compiler.getProgram();
|
||||||
|
// Initialize the master ASM fragment synthesizer
|
||||||
|
program.initAsmFragmentMasterSynthesizer();
|
||||||
final File platformFile = SourceLoader.loadFile(TargetPlatform.DEFAULT_NAME + "." + CTargetPlatformParser.FILE_EXTENSION, filePath, program.getTargetPlatformPaths());
|
final File platformFile = SourceLoader.loadFile(TargetPlatform.DEFAULT_NAME + "." + CTargetPlatformParser.FILE_EXTENSION, filePath, program.getTargetPlatformPaths());
|
||||||
final TargetPlatform targetPlatform = CTargetPlatformParser.parseTargetPlatformFile(TargetPlatform.DEFAULT_NAME, platformFile, filePath, program.getTargetPlatformPaths());
|
final TargetPlatform targetPlatform = CTargetPlatformParser.parseTargetPlatformFile(TargetPlatform.DEFAULT_NAME, platformFile, filePath, program.getTargetPlatformPaths());
|
||||||
program.setTargetPlatform(targetPlatform);
|
program.setTargetPlatform(targetPlatform);
|
||||||
compiler.initAsmFragmentSynthesizer(asmFragmentSynthesizer);
|
|
||||||
program.addReservedZps(program.getTargetPlatform().getReservedZps());
|
program.addReservedZps(program.getTargetPlatform().getReservedZps());
|
||||||
compiler.compile(files, program.getTargetPlatform().getDefines());
|
compiler.compile(files, program.getTargetPlatform().getDefines());
|
||||||
compileAsm(fileName, program);
|
compileAsm(fileName, program);
|
||||||
@ -4438,8 +4437,8 @@ public class TestPrograms {
|
|||||||
//System.out.println(program.getLog().toString());
|
//System.out.println(program.getLog().toString());
|
||||||
fail("Output does not match reference!");
|
fail("Output does not match reference!");
|
||||||
}
|
}
|
||||||
|
// Save the ASM fragment caches (if there are any changes)
|
||||||
compiler.getAsmFragmentSynthesizer().finalize(program.getLog());
|
compiler.getAsmFragmentMasterSynthesizer().finalize(program.getLog());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void compileAsm(String fileName, Program program) throws IOException {
|
private void compileAsm(String fileName, Program program) throws IOException {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user