diff --git a/src/main/fragment/_deref__deref_pptc1=vbuaa.asm b/src/main/fragment/_deref__deref_pptc1=vbuaa.asm new file mode 100644 index 000000000..a674d8937 --- /dev/null +++ b/src/main/fragment/_deref__deref_pptc1=vbuaa.asm @@ -0,0 +1,2 @@ +ldy #0 +sta ({c1}),y diff --git a/src/main/fragment/_deref__deref_pptz1=pbuc1_derefidx_vbuxx.asm b/src/main/fragment/_deref__deref_pptz1=pbuc1_derefidx_vbuxx.asm new file mode 100644 index 000000000..1d22175ee --- /dev/null +++ b/src/main/fragment/_deref__deref_pptz1=pbuc1_derefidx_vbuxx.asm @@ -0,0 +1,5 @@ +ldy #0 +lda {z1} +sta !+ +1 +lda {c1},x +!: sta ($ff),y diff --git a/src/main/fragment/_deref__deref_pptz1=vbuaa.asm b/src/main/fragment/_deref__deref_pptz1=vbuaa.asm new file mode 100644 index 000000000..6516b7db1 --- /dev/null +++ b/src/main/fragment/_deref__deref_pptz1=vbuaa.asm @@ -0,0 +1,4 @@ +ldy {z1} +sty !+ +1 +ldy #0 +!: sta ($ff),y diff --git a/src/main/fragment/_deref_pduc1=vduz1.asm b/src/main/fragment/_deref_pduc1=vduz1.asm new file mode 100644 index 000000000..7b88fe56a --- /dev/null +++ b/src/main/fragment/_deref_pduc1=vduz1.asm @@ -0,0 +1,8 @@ +lda {z1} +sta {c1} +lda {z1}+1 +sta {c1}+1 +lda {z1}+2 +sta {c1}+2 +lda {z1}+3 +sta {c1}+3 diff --git a/src/main/fragment/_deref_pptc1=_inc__deref_pptc1.asm b/src/main/fragment/_deref_pptc1=_inc__deref_pptc1.asm new file mode 100644 index 000000000..39191f06b --- /dev/null +++ b/src/main/fragment/_deref_pptc1=_inc__deref_pptc1.asm @@ -0,0 +1,4 @@ +inc {c1} +bne !+ +inc {c1}+1 +!: \ No newline at end of file diff --git a/src/main/fragment/_deref_pptc1=pbuz1.asm b/src/main/fragment/_deref_pptc1=pbuz1.asm new file mode 100644 index 000000000..0e0382e79 --- /dev/null +++ b/src/main/fragment/_deref_pptc1=pbuz1.asm @@ -0,0 +1,4 @@ +lda {z1} +sta {c1} +lda {z1}+1 +sta {c1}+1 \ No newline at end of file diff --git a/src/main/fragment/_deref_pptz1=_inc__deref_pptz1.asm b/src/main/fragment/_deref_pptz1=_inc__deref_pptz1.asm new file mode 100644 index 000000000..d066e7dc9 --- /dev/null +++ b/src/main/fragment/_deref_pptz1=_inc__deref_pptz1.asm @@ -0,0 +1,5 @@ +ldy #0 +lda ({z1}),y +clc +adc #1 +sta ({z1}),y \ No newline at end of file diff --git a/src/main/fragment/pbuz1=_ptr_vwuz2.asm b/src/main/fragment/pbuz1=_ptr_vwuz2.asm new file mode 100644 index 000000000..5b8ff5c26 --- /dev/null +++ b/src/main/fragment/pbuz1=_ptr_vwuz2.asm @@ -0,0 +1,4 @@ +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 diff --git a/src/main/fragment/pptz1_derefidx_vbuc1=pbuz2.asm b/src/main/fragment/pptz1_derefidx_vbuc1=pbuz2.asm new file mode 100644 index 000000000..d59fe6a79 --- /dev/null +++ b/src/main/fragment/pptz1_derefidx_vbuc1=pbuz2.asm @@ -0,0 +1,6 @@ +ldy #{c1} +lda {z2} +sta ({z1}),y +iny +lda {z2}+1 +sta ({z1}),y diff --git a/src/main/fragment/pptz1_derefidx_vbuc1=pwuz2.asm b/src/main/fragment/pptz1_derefidx_vbuc1=pwuz2.asm new file mode 100644 index 000000000..d59fe6a79 --- /dev/null +++ b/src/main/fragment/pptz1_derefidx_vbuc1=pwuz2.asm @@ -0,0 +1,6 @@ +ldy #{c1} +lda {z2} +sta ({z1}),y +iny +lda {z2}+1 +sta ({z1}),y diff --git a/src/main/fragment/pptz1_derefidx_vbuyy=pbuz2.asm b/src/main/fragment/pptz1_derefidx_vbuyy=pbuz2.asm new file mode 100644 index 000000000..54ae1d53c --- /dev/null +++ b/src/main/fragment/pptz1_derefidx_vbuyy=pbuz2.asm @@ -0,0 +1,5 @@ +lda {z2} +sta ({z1}),y +iny +lda {z2}+1 +sta ({z1}),y \ No newline at end of file diff --git a/src/main/fragment/pptz1_derefidx_vbuyy=pwuz2.asm b/src/main/fragment/pptz1_derefidx_vbuyy=pwuz2.asm new file mode 100644 index 000000000..54ae1d53c --- /dev/null +++ b/src/main/fragment/pptz1_derefidx_vbuyy=pwuz2.asm @@ -0,0 +1,5 @@ +lda {z2} +sta ({z1}),y +iny +lda {z2}+1 +sta ({z1}),y \ No newline at end of file diff --git a/src/main/fragment/pssc1_derefidx_vbuxx_mbr_0=vbuaa.asm b/src/main/fragment/pssc1_derefidx_vbuxx_mbr_0=vbuaa.asm new file mode 100644 index 000000000..916e765e0 --- /dev/null +++ b/src/main/fragment/pssc1_derefidx_vbuxx_mbr_0=vbuaa.asm @@ -0,0 +1,2 @@ +sta {c1},x + diff --git a/src/main/fragment/pssc1_derefidx_vbuxx_mbr_1=vbuaa.asm b/src/main/fragment/pssc1_derefidx_vbuxx_mbr_1=vbuaa.asm new file mode 100644 index 000000000..778da5aff --- /dev/null +++ b/src/main/fragment/pssc1_derefidx_vbuxx_mbr_1=vbuaa.asm @@ -0,0 +1,2 @@ +sta {c1}+1,x + diff --git a/src/main/fragment/pssc1_derefidx_vbuyy_mbr_0=vbuaa.asm b/src/main/fragment/pssc1_derefidx_vbuyy_mbr_0=vbuaa.asm new file mode 100644 index 000000000..64fd3eaf2 --- /dev/null +++ b/src/main/fragment/pssc1_derefidx_vbuyy_mbr_0=vbuaa.asm @@ -0,0 +1,2 @@ +sta {c1},y + diff --git a/src/main/fragment/pssc1_derefidx_vbuyy_mbr_1=vbuaa.asm b/src/main/fragment/pssc1_derefidx_vbuyy_mbr_1=vbuaa.asm new file mode 100644 index 000000000..91a797b27 --- /dev/null +++ b/src/main/fragment/pssc1_derefidx_vbuyy_mbr_1=vbuaa.asm @@ -0,0 +1,2 @@ +sta {c1}+1,y + diff --git a/src/main/fragment/pwsc1_derefidx_vbuxx=pwsc1_derefidx_vbuxx_minus_vwsz1.asm b/src/main/fragment/pwsc1_derefidx_vbuxx=pwsc1_derefidx_vbuxx_minus_vwsz1.asm new file mode 100644 index 000000000..574b6dc27 --- /dev/null +++ b/src/main/fragment/pwsc1_derefidx_vbuxx=pwsc1_derefidx_vbuxx_minus_vwsz1.asm @@ -0,0 +1,7 @@ +lda {c1},x +sec +sbc {z1} +sta {c1},x +lda {c1}+1,x +sbc {z1}+1 +sta {c1}+1,x \ No newline at end of file diff --git a/src/main/fragment/pwsc1_derefidx_vbuxx=vwsz1.asm b/src/main/fragment/pwsc1_derefidx_vbuxx=vwsz1.asm new file mode 100644 index 000000000..dcb4c0bff --- /dev/null +++ b/src/main/fragment/pwsc1_derefidx_vbuxx=vwsz1.asm @@ -0,0 +1,4 @@ +lda {z1} +sta {c1},x +lda {z1}+1 +sta {c1}+1,x \ No newline at end of file diff --git a/src/main/fragment/pwsc1_derefidx_vbuyy=pwsc1_derefidx_vbuyy_minus_vwsz1.asm b/src/main/fragment/pwsc1_derefidx_vbuyy=pwsc1_derefidx_vbuyy_minus_vwsz1.asm new file mode 100644 index 000000000..856be16de --- /dev/null +++ b/src/main/fragment/pwsc1_derefidx_vbuyy=pwsc1_derefidx_vbuyy_minus_vwsz1.asm @@ -0,0 +1,7 @@ +lda {c1},y +sec +sbc {z1} +sta {c1},y +lda {c1}+1,y +sbc {z1}+1 +sta {c1}+1,y \ No newline at end of file diff --git a/src/main/fragment/pwsc1_derefidx_vbuyy=vwsz1.asm b/src/main/fragment/pwsc1_derefidx_vbuyy=vwsz1.asm new file mode 100644 index 000000000..95167d258 --- /dev/null +++ b/src/main/fragment/pwsc1_derefidx_vbuyy=vwsz1.asm @@ -0,0 +1,4 @@ +lda {z1} +sta {c1},y +lda {z1}+1 +sta {c1}+1,y \ No newline at end of file diff --git a/src/main/fragment/pwuc1_derefidx_vbuaa=_word_vbuxx.asm b/src/main/fragment/pwuc1_derefidx_vbuaa=vbuxx.asm similarity index 100% rename from src/main/fragment/pwuc1_derefidx_vbuaa=_word_vbuxx.asm rename to src/main/fragment/pwuc1_derefidx_vbuaa=vbuxx.asm diff --git a/src/main/fragment/pwuc1_derefidx_vbuxx=_word_vbuaa.asm b/src/main/fragment/pwuc1_derefidx_vbuxx=vbuaa.asm similarity index 100% rename from src/main/fragment/pwuc1_derefidx_vbuxx=_word_vbuaa.asm rename to src/main/fragment/pwuc1_derefidx_vbuxx=vbuaa.asm diff --git a/src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm b/src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm new file mode 100644 index 000000000..ef873ab36 --- /dev/null +++ b/src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm @@ -0,0 +1,8 @@ +lda {c1}+1,x +cmp {z1}+1 +bne !+ +lda {c1},x +cmp {z1} +beq {la1} +!: +bcc {la1} diff --git a/src/main/fragment/pwuc1_derefidx_vbuyy=vbuaa.asm b/src/main/fragment/pwuc1_derefidx_vbuyy=vbuaa.asm new file mode 100644 index 000000000..355a5914f --- /dev/null +++ b/src/main/fragment/pwuc1_derefidx_vbuyy=vbuaa.asm @@ -0,0 +1,3 @@ +sta {c1},y +lda #0 +sta {c1}+1,y diff --git a/src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm b/src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm new file mode 100644 index 000000000..427b691bd --- /dev/null +++ b/src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm @@ -0,0 +1,8 @@ +lda {c1}+1,y +cmp {z1}+1 +bne !+ +lda {c1},y +cmp {z1} +beq {la1} +!: +bcc {la1} diff --git a/src/main/fragment/vbsaa=_neg__sbyte_vbuaa.asm b/src/main/fragment/vbsaa=_neg__sbyte_vbuaa.asm new file mode 100644 index 000000000..9c8b937fb --- /dev/null +++ b/src/main/fragment/vbsaa=_neg__sbyte_vbuaa.asm @@ -0,0 +1,3 @@ +eor #$ff +clc +adc #$01 \ No newline at end of file diff --git a/src/main/fragment/vbsaa_lt_vbsc1_then_la1.asm b/src/main/fragment/vbsaa_lt_vbsc1_then_la1.asm new file mode 100644 index 000000000..92a07250f --- /dev/null +++ b/src/main/fragment/vbsaa_lt_vbsc1_then_la1.asm @@ -0,0 +1,6 @@ +sec +sbc #{c1} +bvc !+ +eor #$80 +!: +bmi {la1} diff --git a/src/main/fragment/vbuaa=_deref_pssc1_mbr_0.asm b/src/main/fragment/vbuaa=_deref_pssc1_mbr_0.asm new file mode 100644 index 000000000..bee08251a --- /dev/null +++ b/src/main/fragment/vbuaa=_deref_pssc1_mbr_0.asm @@ -0,0 +1 @@ +lda {c1} \ No newline at end of file diff --git a/src/main/fragment/vbuaa=_deref_pssc1_mbr_1.asm b/src/main/fragment/vbuaa=_deref_pssc1_mbr_1.asm new file mode 100644 index 000000000..a836deba0 --- /dev/null +++ b/src/main/fragment/vbuaa=_deref_pssc1_mbr_1.asm @@ -0,0 +1 @@ +lda {c1}+1 \ No newline at end of file diff --git a/src/main/fragment/vbuaa=pssc1_derefidx_vbuxx_mbr_0.asm b/src/main/fragment/vbuaa=pssc1_derefidx_vbuxx_mbr_0.asm new file mode 100644 index 000000000..7454fa763 --- /dev/null +++ b/src/main/fragment/vbuaa=pssc1_derefidx_vbuxx_mbr_0.asm @@ -0,0 +1 @@ +lda {c1},x \ No newline at end of file diff --git a/src/main/fragment/vbuaa=pssc1_derefidx_vbuxx_mbr_1.asm b/src/main/fragment/vbuaa=pssc1_derefidx_vbuxx_mbr_1.asm new file mode 100644 index 000000000..66ef35236 --- /dev/null +++ b/src/main/fragment/vbuaa=pssc1_derefidx_vbuxx_mbr_1.asm @@ -0,0 +1 @@ +lda {c1}+1,x \ No newline at end of file diff --git a/src/main/fragment/vbuaa=pssc1_derefidx_vbuyy_mbr_0.asm b/src/main/fragment/vbuaa=pssc1_derefidx_vbuyy_mbr_0.asm new file mode 100644 index 000000000..b2b867b05 --- /dev/null +++ b/src/main/fragment/vbuaa=pssc1_derefidx_vbuyy_mbr_0.asm @@ -0,0 +1 @@ +lda {c1},y \ No newline at end of file diff --git a/src/main/fragment/vbuaa=pssc1_derefidx_vbuyy_mbr_1.asm b/src/main/fragment/vbuaa=pssc1_derefidx_vbuyy_mbr_1.asm new file mode 100644 index 000000000..5c24499d4 --- /dev/null +++ b/src/main/fragment/vbuaa=pssc1_derefidx_vbuyy_mbr_1.asm @@ -0,0 +1 @@ +lda {c1}+1,y \ No newline at end of file diff --git a/src/main/fragment/vbuaa_le_0_then_la1.asm b/src/main/fragment/vbuaa_le_0_then_la1.asm new file mode 100644 index 000000000..118295957 --- /dev/null +++ b/src/main/fragment/vbuaa_le_0_then_la1.asm @@ -0,0 +1,2 @@ +cmp #0 +beq {la1} \ No newline at end of file diff --git a/src/main/fragment/vbuxx_le_0_then_la1.asm b/src/main/fragment/vbuxx_le_0_then_la1.asm new file mode 100644 index 000000000..d1d800f7b --- /dev/null +++ b/src/main/fragment/vbuxx_le_0_then_la1.asm @@ -0,0 +1,2 @@ +cpx #0 +beq {la1} \ No newline at end of file diff --git a/src/main/fragment/vbuyy_le_0_then_la1.asm b/src/main/fragment/vbuyy_le_0_then_la1.asm new file mode 100644 index 000000000..9af1697e9 --- /dev/null +++ b/src/main/fragment/vbuyy_le_0_then_la1.asm @@ -0,0 +1,2 @@ +cpy #0 +beq {la1} \ No newline at end of file diff --git a/src/main/fragment/vduz1=_dword_vbuaa.asm b/src/main/fragment/vduz1=_dword_vbuaa.asm new file mode 100644 index 000000000..e1a56bd93 --- /dev/null +++ b/src/main/fragment/vduz1=_dword_vbuaa.asm @@ -0,0 +1,5 @@ +sta {z1} +lda #0 +sta {z1}+1 +sta {z1}+2 +sta {z1}+3 diff --git a/src/main/fragment/vduz1=vduc1_plus_vduz2.asm b/src/main/fragment/vduz1=vduc1_plus_vduz2.asm new file mode 100644 index 000000000..aee9842f5 --- /dev/null +++ b/src/main/fragment/vduz1=vduc1_plus_vduz2.asm @@ -0,0 +1,13 @@ +lda {z2} +clc +adc #<{c1} +sta {z1} +lda {z2}+1 +adc #>{c1} +sta {z1}+1 +lda {z2}+2 +adc #0 +sta {z1}+2 +lda {z2}+3 +adc #0 +sta {z1}+3 \ No newline at end of file diff --git a/src/main/fragment/vduz1=vduz1_plus_vduz2.asm b/src/main/fragment/vduz1=vduz1_plus_vduz2.asm index 3574d1e24..973a718d1 100644 --- a/src/main/fragment/vduz1=vduz1_plus_vduz2.asm +++ b/src/main/fragment/vduz1=vduz1_plus_vduz2.asm @@ -10,5 +10,4 @@ adc {z2}+2 sta {z1}+2 lda {z1}+3 adc {z2}+3 -sta {z1}+3 - +sta {z1}+3 \ No newline at end of file diff --git a/src/main/fragment/vduz1=vduz2_plus_vwuc1.asm b/src/main/fragment/vduz1=vduz2_plus_vwuc1.asm index ff2fb6d2d..aee9842f5 100644 --- a/src/main/fragment/vduz1=vduz2_plus_vwuc1.asm +++ b/src/main/fragment/vduz1=vduz2_plus_vwuc1.asm @@ -10,5 +10,4 @@ adc #0 sta {z1}+2 lda {z2}+3 adc #0 -sta {z1}+3 - +sta {z1}+3 \ No newline at end of file diff --git a/src/main/fragment/vduz1=vwuz2.asm b/src/main/fragment/vduz1=vwuz2.asm new file mode 100644 index 000000000..7d25095ee --- /dev/null +++ b/src/main/fragment/vduz1=vwuz2.asm @@ -0,0 +1,7 @@ +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 +lda #0 +sta {z1}+2 +sta {z1}+3 \ No newline at end of file diff --git a/src/main/fragment/vduz1=vwuz2_dword_vbuc1.asm b/src/main/fragment/vduz1=vwuz2_dword_vbuc1.asm index a704a0e79..ee4169530 100644 --- a/src/main/fragment/vduz1=vwuz2_dword_vbuc1.asm +++ b/src/main/fragment/vduz1=vwuz2_dword_vbuc1.asm @@ -1,8 +1,8 @@ -lda #<{c1} -sta {z1} -lda #>{c1} -sta {z1}+1 lda {z2} sta {z1}+2 lda {z2}+1 sta {z1}+3 +lda #{c1} +sta {z1} +lda #0 +sta {z1}+1 diff --git a/src/main/fragment/vduz1=vwuz2_dword_vwuc1.asm b/src/main/fragment/vduz1=vwuz2_dword_vwuc1.asm new file mode 100644 index 000000000..a704a0e79 --- /dev/null +++ b/src/main/fragment/vduz1=vwuz2_dword_vwuc1.asm @@ -0,0 +1,8 @@ +lda #<{c1} +sta {z1} +lda #>{c1} +sta {z1}+1 +lda {z2} +sta {z1}+2 +lda {z2}+1 +sta {z1}+3 diff --git a/src/main/fragment/vssz1=vssf2.asm b/src/main/fragment/vssz1=vssf2.asm new file mode 100644 index 000000000..5a5c14b91 --- /dev/null +++ b/src/main/fragment/vssz1=vssf2.asm @@ -0,0 +1,3 @@ +lda #0 +sta {z1} +sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/vssz1=vssz2.asm b/src/main/fragment/vssz1=vssz2.asm new file mode 100644 index 000000000..113613e13 --- /dev/null +++ b/src/main/fragment/vssz1=vssz2.asm @@ -0,0 +1,4 @@ +lda {z2} +sta {z1} +lda {z2}+1 +sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/vwsz1=_sword_vbuaa.asm b/src/main/fragment/vwsz1=_sword_vbuaa.asm new file mode 100644 index 000000000..e87d75da4 --- /dev/null +++ b/src/main/fragment/vwsz1=_sword_vbuaa.asm @@ -0,0 +1,3 @@ +sta {z1} +lda #0 +sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/vwsz1=vbsaa_plus_vwsc1.asm b/src/main/fragment/vwsz1=vbsaa_plus_vwsc1.asm new file mode 100644 index 000000000..1d0b489df --- /dev/null +++ b/src/main/fragment/vwsz1=vbsaa_plus_vwsc1.asm @@ -0,0 +1,11 @@ +tax +clc +adc #<{c1} +sta {z1} +txa +ora #$7f +bmi !+ +lda #0 +!: +adc #>{c1} +sta {z1}+1 diff --git a/src/main/fragment/vwsz1=vwsz2_minus_vbsc1.asm b/src/main/fragment/vwsz1=vwsz2_minus_vbsc1.asm new file mode 100644 index 000000000..fb2471179 --- /dev/null +++ b/src/main/fragment/vwsz1=vwsz2_minus_vbsc1.asm @@ -0,0 +1,7 @@ +lda {z2} +sec +sbc #{c1} +sta {z1} +lda {z2}+1 +sbc #>{c1} +sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/vwuz1=vbuaa_rol_1.asm b/src/main/fragment/vwuz1=vbuaa_rol_1.asm new file mode 100644 index 000000000..9c3c7c279 --- /dev/null +++ b/src/main/fragment/vwuz1=vbuaa_rol_1.asm @@ -0,0 +1,5 @@ +asl +sta {z1} +lda #0 +rol +sta {z1}+1 \ No newline at end of file diff --git a/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm new file mode 100644 index 000000000..0b9a494d5 --- /dev/null +++ b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm @@ -0,0 +1,7 @@ +sec +lda {z1} +sbc {c1},x +sta {z1} +lda {z1}+1 +sbc {c1}+1,x +sta {z1}+1 diff --git a/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm new file mode 100644 index 000000000..001c5e74d --- /dev/null +++ b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm @@ -0,0 +1,7 @@ +sec +lda {z1} +sbc {c1},y +sta {z1} +lda {z1}+1 +sbc {c1}+1,y +sta {z1}+1 diff --git a/src/main/fragment/vwuz1_eq_vwuc1_then_la1.asm b/src/main/fragment/vwuz1_eq_vwuc1_then_la1.asm new file mode 100644 index 000000000..5afd41846 --- /dev/null +++ b/src/main/fragment/vwuz1_eq_vwuc1_then_la1.asm @@ -0,0 +1,7 @@ +lda {z1} +cmp #<{c1} +bne !+ +lda {z1}+1 +cmp #>{c1} +beq {la1} +!: \ No newline at end of file diff --git a/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm b/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm index 54a02388d..cc7e71a71 100644 --- a/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm +++ b/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm @@ -3,6 +3,6 @@ cmp {z2}+1 bne !+ lda {z1} cmp {z2} +beq {la1} !: bcc {la1} -beq {la1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/CompileLog.java b/src/main/java/dk/camelot64/kickc/CompileLog.java index 2b82efc32..545d45140 100644 --- a/src/main/java/dk/camelot64/kickc/CompileLog.java +++ b/src/main/java/dk/camelot64/kickc/CompileLog.java @@ -192,7 +192,7 @@ public class CompileLog { return verboseSSAOptimize; } - public CompileLog setVerboseSSAOptimize() { + public CompileLog verboseSSAOptimize() { setVerboseSSAOptimize(true); return this; } diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index cb8d88400..02f2794ae 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -153,18 +153,19 @@ public class Compiler { new Pass1GenerateControlFlowGraph(program).execute(); new Pass1ResolveForwardReferences(program).execute(); new Pass1UnwindBlockScopes(program).execute(); - new Pass1TypeInference(program).execute(); - new Pass1TypeIdSimplification(program).execute(); + new Pass1Procedures(program).execute(); + new PassNTypeInference(program).execute(); + new PassNTypeIdSimplification(program).execute(); if(getLog().isVerbosePass1CreateSsa()) { getLog().append("SYMBOLS"); - getLog().append(program.getScope().getSymbolTableContents(program)); + getLog().append(program.getScope().toString(program, null)); } new Pass1FixLValuesLoHi(program).execute(); new Pass1AssertNoLValueIntermediate(program).execute(); new Pass1PointerSizeofFix(program).execute(); - new Pass1AddTypePromotions(program).execute(); + new PassNAddTypeConversionAssignment(program).execute(); new Pass1EarlyConstantIdentification(program).execute(); new PassNStatementIndices(program).step(); new PassNCallGraphAnalysis(program).step(); @@ -182,7 +183,7 @@ public class Compiler { new Pass1EliminateUncalledProcedures(program).execute(); new PassNEliminateUnusedVars(program, false).execute(); new Pass1ExtractInlineStrings(program).execute(); - new Pass1EliminateEmptyBlocks(program).execute(); + new PassNCullEmptyBlocks(program).execute(); new Pass1ModifiedVarsAnalysis(program).execute(); if(getLog().isVerbosePass1CreateSsa()) { @@ -205,7 +206,7 @@ public class Compiler { getLog().append(program.getGraph().toString(program)); getLog().append("SYMBOL TABLE SSA"); - getLog().append(program.getScope().getSymbolTableContents(program)); + getLog().append(program.getScope().toString(program, null)); return program; } @@ -228,37 +229,50 @@ public class Compiler { } } - private void pass2Optimize() { + private List getPass2Optimizations() { List optimizations = new ArrayList<>(); - optimizations.add(new Pass2CullEmptyBlocks(program)); + optimizations.add(new Pass2FixInlineConstructorsNew(program)); + + optimizations.add(new PassNAddNumberTypeConversions(program)); + optimizations.add(new PassNAddArrayNumberTypeConversions(program)); + optimizations.add(new Pass2InlineCast(program)); + //optimizations.add(new Pass2NopCastInlining(program)); + optimizations.add(new PassNCastSimplification(program)); + optimizations.add(new PassNFinalizeNumberTypeConversions(program)); + optimizations.add(new PassNTypeInference(program)); + optimizations.add(new PassNAddTypeConversionAssignment(program)); + + optimizations.add(new PassNTypeIdSimplification(program)); + optimizations.add(new Pass2SizeOfSimplification(program)); optimizations.add(new PassNStatementIndices(program)); optimizations.add(new PassNVariableReferenceInfos(program)); optimizations.add(new Pass2UnaryNotSimplification(program)); optimizations.add(new Pass2AliasElimination(program)); optimizations.add(new Pass2SelfPhiElimination(program)); - optimizations.add(new Pass2RedundantPhiElimination(program)); optimizations.add(new Pass2IdenticalPhiElimination(program)); + optimizations.add(new Pass2DuplicateRValueIdentification(program)); optimizations.add(new Pass2ConditionalJumpSimplification(program)); optimizations.add(new Pass2ConditionalAndOrRewriting(program)); + optimizations.add(new Pass2ConditionalJumpSequenceImprovement(program)); + optimizations.add(new Pass2ConstantRValueConsolidation(program)); optimizations.add(new Pass2ConstantIdentification(program)); - optimizations.add(new PassNStatementIndices(program)); - optimizations.add(new PassNVariableReferenceInfos(program)); - optimizations.add(new Pass2ConstantAdditionElimination(program)); + optimizations.add(new Pass2ConstantValues(program)); + optimizations.add(new Pass2ConstantCallPointerIdentification(program)); optimizations.add(new Pass2ConstantIfs(program)); optimizations.add(new Pass2ConstantStringConsolidation(program)); - optimizations.add(new Pass2FixInlineConstructors(program)); - optimizations.add(new Pass2TypeInference(program)); - optimizations.add(new PassNEliminateUnusedVars(program, true)); - optimizations.add(new Pass2EliminateRedundantCasts(program)); - optimizations.add(new Pass2NopCastElimination(program)); - optimizations.add(new Pass2EliminateUnusedBlocks(program)); optimizations.add(new Pass2RangeResolving(program)); optimizations.add(new Pass2ComparisonOptimization(program)); - optimizations.add(new Pass2ConstantCallPointerIdentification(program)); - optimizations.add(new Pass2MultiplyToShiftRewriting(program)); - optimizations.add(new Pass2SizeOfSimplification(program)); optimizations.add(new Pass2InlineDerefIdx(program)); optimizations.add(new Pass2DeInlineWordDerefIdx(program)); + optimizations.add(new PassNSimplifyConstantZero(program)); + optimizations.add(new PassNSimplifyExpressionWithZero(program)); + optimizations.add(new PassNEliminateUnusedVars(program, true)); + optimizations.add(new Pass2EliminateUnusedBlocks(program)); + return optimizations; + } + + private void pass2Optimize() { + List optimizations = getPass2Optimizations(); pass2Execute(optimizations); } @@ -291,13 +305,13 @@ public class Compiler { private void pass2InlineConstants() { // Constant inlining optimizations - as the last step to ensure that constant identification has been completed List constantOptimizations = new ArrayList<>(); + constantOptimizations.add(new PassNStatementIndices(program)); + constantOptimizations.add(new PassNVariableReferenceInfos(program)); + constantOptimizations.add(new Pass2MultiplyToShiftRewriting(program)); constantOptimizations.add(new Pass2ConstantInlining(program)); - constantOptimizations.add(new Pass2ConstantStringConsolidation(program)); - constantOptimizations.add(new Pass2IdenticalPhiElimination(program)); - constantOptimizations.add(new Pass2ConstantIdentification(program)); constantOptimizations.add(new Pass2ConstantAdditionElimination(program)); constantOptimizations.add(new Pass2ConstantSimplification(program)); - constantOptimizations.add(new Pass2ConstantIfs(program)); + constantOptimizations.addAll(getPass2Optimizations()); pass2Execute(constantOptimizations); } @@ -351,11 +365,12 @@ public class Compiler { } private void pass3Analysis() { + new Pass3AssertNoTypeId(program).check(); new Pass3AssertRValues(program).check(); + new Pass3AssertNoNumbers(program).check(); new Pass3AssertConstants(program).check(); new Pass3AssertArrayLengths(program).check(); new Pass3AssertNoMulDivMod(program).check(); - new PassNBlockSequencePlanner(program).step(); // Phi lifting ensures that all variables in phi-blocks are in different live range equivalence classes new Pass3PhiLifting(program).perform(); new PassNBlockSequencePlanner(program).step(); @@ -382,7 +397,7 @@ public class Compiler { // Phi mem coalesce removes as many variables introduced by phi lifting as possible - as long as their live ranges do not overlap new Pass3PhiMemCoalesce(program).step(); - new Pass2CullEmptyBlocks(program).step(); + new PassNCullEmptyBlocks(program).step(); new PassNRenumberLabels(program).execute(); new PassNBlockSequencePlanner(program).step(); new Pass3AddNopBeforeCallOns(program).generate(); @@ -516,7 +531,7 @@ public class Compiler { new Pass5FixLongBranches(program).optimize(); getLog().append("\nFINAL SYMBOL TABLE"); - getLog().append(program.getScope().getSymbolTableContents(program)); + getLog().append(program.getScope().toString(program, null)); getLog().append("\nFINAL ASSEMBLER"); getLog().append("Score: " + Pass4RegisterUpliftCombinations.getAsmScore(program) + "\n"); diff --git a/src/main/java/dk/camelot64/kickc/NumberParser.java b/src/main/java/dk/camelot64/kickc/NumberParser.java index 5465bad9a..e72a28df8 100644 --- a/src/main/java/dk/camelot64/kickc/NumberParser.java +++ b/src/main/java/dk/camelot64/kickc/NumberParser.java @@ -1,38 +1,61 @@ package dk.camelot64.kickc; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.values.ConstantInteger; + /** Parser for converting literal numbers to the corresponding Java Integer/Double */ public class NumberParser { - public static Number parseLiteral(String literal) { - boolean isInt = !literal.contains("."); + public static ConstantInteger parseIntegerLiteral(String literal) { - if(isInt) { - if(literal.startsWith("0x")) { - return parseHexInt(literal.substring(2)); - } else if(literal.startsWith("$")) { - return parseHexInt(literal.substring(1)); - } else if(literal.startsWith("0b")) { - return parseBinInt(literal.substring(2)); - } else if(literal.startsWith("%")) { - return parseBinInt(literal.substring(1)); - } else { - return parseDecInt(literal); - } - } else { + boolean isInt = !literal.contains("."); + if(!isInt) { throw new NumberFormatException("Not Implemented: non-integer parsing. " + literal); } + + SymbolType type = SymbolType.NUMBER; + if(literal.endsWith("ub") || literal.endsWith("uc")) { + type = SymbolType.BYTE; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("sb") || literal.endsWith("sc")) { + type = SymbolType.SBYTE; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("uw") || literal.endsWith("ui")|| literal.endsWith("us")) { + type = SymbolType.WORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("sw") || literal.endsWith("si")|| literal.endsWith("ss")) { + type = SymbolType.SWORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("ud") || literal.endsWith("ul")) { + type = SymbolType.DWORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("sd") || literal.endsWith("sl")) { + type = SymbolType.SDWORD; + literal = literal.substring(0, literal.length()-2); + } else if(literal.endsWith("l")) { + type = SymbolType.SDWORD; + literal = literal.substring(0, literal.length()-1); + } + + Long value; + if(literal.startsWith("0x")) { + value = Long.parseLong(literal.substring(2), 16); + } else if(literal.startsWith("$")) { + value = Long.parseLong(literal.substring(1), 16); + } else if(literal.startsWith("0b")) { + value = Long.parseLong(literal.substring(2), 2); + } else if(literal.startsWith("%")) { + value = Long.parseLong(literal.substring(1), 2); + } else { + value = Long.parseLong(literal); + } + return new ConstantInteger(value, type); + } - private static Long parseHexInt(String literal) { - return Long.parseLong(literal, 16); - } - - private static Long parseBinInt(String literal) { - return Long.parseLong(literal, 2); - } - - private static Long parseDecInt(String literal) { - return Long.parseLong(literal); + public static Number parseLiteral(String literal) { + ConstantInteger constantInteger = parseIntegerLiteral(literal); + return constantInteger.getValue(); } diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java index 28f28111f..edd3e0899 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFormat.java @@ -7,9 +7,7 @@ import dk.camelot64.kickc.model.symbols.ConstantVar; import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.Variable; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypePointer; +import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.*; /** Formatting of numbers, constants, names and more for KickAssembler */ @@ -61,7 +59,7 @@ public class AsmFormat { } else if(symbol instanceof Procedure) { return getAsmParamName((Procedure) symbol, codeScope); } else { - throw new RuntimeException("Unhandled symbol type "+symbol); + throw new RuntimeException("Unhandled symbol type " + symbol); } } else if(value instanceof ConstantCastValue) { ConstantCastValue castValue = (ConstantCastValue) value; @@ -75,6 +73,7 @@ public class AsmFormat { /** * Get ASM for a binary constant expression + * * @param program The program * @param left The left operand of the expression * @param operator The binary operator @@ -85,12 +84,12 @@ public class AsmFormat { private static String getAsmConstantBinary(Program program, ConstantValue left, OperatorBinary operator, ConstantValue right, ScopeRef codeScope) { if(Operators.MODULO.equals(operator)) { // Remainder operator % not supported by KickAss - use modulo function instead - return "mod("+ + return "mod(" + getAsmConstant(program, left, operator.getPrecedence(), codeScope) + "," + - getAsmConstant(program, right, operator.getPrecedence(), codeScope)+ + getAsmConstant(program, right, operator.getPrecedence(), codeScope) + ")"; - } else { + } else { return getAsmConstant(program, left, operator.getPrecedence(), codeScope) + operator.getOperator() + getAsmConstant(program, right, operator.getPrecedence(), codeScope); @@ -109,64 +108,95 @@ public class AsmFormat { private static String getAsmConstantUnary(Program program, ScopeRef codeScope, Operator operator, ConstantValue operand, int outerPrecedence) { if(Operators.CAST_BYTE.equals(operator) || Operators.CAST_SBYTE.equals(operator)) { SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); - if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) { + if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { // No cast needed return getAsmConstant(program, operand, outerPrecedence, codeScope); - } else { - return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xff), Operators.BOOL_AND, operand), outerPrecedence, codeScope); } - } else if(operator instanceof OperatorCastPtr || Operators.CAST_WORD.equals(operator) || Operators.CAST_SWORD.equals(operator) ) { + ConstantLiteral constantLiteral = operand.calculateLiteral(program.getScope()); + if(constantLiteral instanceof ConstantInteger && Operators.CAST_BYTE.equals(operator) && SymbolType.BYTE.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + if(constantLiteral instanceof ConstantInteger && Operators.CAST_SBYTE.equals(operator) && SymbolType.SBYTE.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + // Cast is needed + return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) 0xff), Operators.BOOL_AND, operand), outerPrecedence, codeScope); + } else if(operator instanceof OperatorCastPtr || Operators.CAST_WORD.equals(operator) || Operators.CAST_SWORD.equals(operator)) { SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); - if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || SymbolType.isByte(operandType) || SymbolType.isSByte(operandType) || operandType instanceof SymbolTypePointer) { + if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType) || operandType instanceof SymbolTypePointer) { // No cast needed return getAsmConstant(program, operand, outerPrecedence, codeScope); - } else { - return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xffff), Operators.BOOL_AND, operand), outerPrecedence, codeScope); } + ConstantLiteral constantLiteral = operand.calculateLiteral(program.getScope()); + if(constantLiteral instanceof ConstantInteger && Operators.CAST_WORD.equals(operator)&& SymbolType.WORD.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + if(constantLiteral instanceof ConstantInteger && Operators.CAST_SWORD.equals(operator)&& SymbolType.SWORD.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + if(constantLiteral instanceof ConstantInteger && (operator instanceof OperatorCastPtr) && SymbolType.WORD.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + // Cast is needed + return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) 0xffff), Operators.BOOL_AND, operand), outerPrecedence, codeScope); } else if(Operators.CAST_DWORD.equals(operator) || Operators.CAST_SDWORD.equals(operator)) { SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); - if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { + if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType) || SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType) || operandType instanceof SymbolTypePointer) { // No cast needed return getAsmConstant(program, operand, outerPrecedence, codeScope); - } else { - return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)0xffffffffL), Operators.BOOL_AND, operand), outerPrecedence, codeScope); } + ConstantLiteral constantLiteral = operand.calculateLiteral(program.getScope()); + if(constantLiteral instanceof ConstantInteger && Operators.CAST_DWORD.equals(operator)&& SymbolType.DWORD.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + if(constantLiteral instanceof ConstantInteger && Operators.CAST_SDWORD.equals(operator)&& SymbolType.SDWORD.contains(((ConstantInteger) constantLiteral).getValue())) { + // No cast needed + return getAsmConstant(program, operand, outerPrecedence, codeScope); + } + // Cast is needed + return getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) 0xffffffffL), Operators.BOOL_AND, operand), outerPrecedence, codeScope); } else if(Operators.LOWBYTE.equals(operator)) { SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); - if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) { + if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { return getAsmConstant(program, operand, outerPrecedence, codeScope); - } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) { + } else if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) { return "<" + getAsmConstant(program, operand, outerPrecedence, codeScope); - } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_AND, new ConstantInteger((long)0xffff)), outerPrecedence, codeScope); + } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { + return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_AND, new ConstantInteger((long) 0xffff)), outerPrecedence, codeScope); } else { - throw new CompileError("Unhandled type "+operand); + throw new CompileError("Unhandled type " + operand); } } else if(Operators.HIBYTE.equals(operator)) { SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); - if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) { + if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { return getAsmConstant(program, new ConstantInteger(0l), outerPrecedence, codeScope); - } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) { + } else if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) { return ">" + getAsmConstant(program, operand, outerPrecedence, codeScope); - } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.SHIFT_RIGHT, new ConstantInteger((long)16)), outerPrecedence, codeScope); + } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { + return getAsmConstant(program, new ConstantBinary(operand, Operators.SHIFT_RIGHT, new ConstantInteger((long) 16)), outerPrecedence, codeScope); } else { - throw new CompileError("Unhandled type "+operand); + throw new CompileError("Unhandled type " + operand); } } else if(Operators.INCREMENT.equals(operator)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.PLUS, new ConstantInteger((long)1)), outerPrecedence, codeScope); + return getAsmConstant(program, new ConstantBinary(operand, Operators.PLUS, new ConstantInteger((long) 1)), outerPrecedence, codeScope); } else if(Operators.DECREMENT.equals(operator)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.MINUS, new ConstantInteger((long)1)), outerPrecedence, codeScope); + return getAsmConstant(program, new ConstantBinary(operand, Operators.MINUS, new ConstantInteger((long) 1)), outerPrecedence, codeScope); } else if(Operators.BOOL_NOT.equals(operator)) { SymbolType operandType = SymbolTypeInference.inferType(program.getScope(), operand); - if(SymbolType.isByte(operandType) || SymbolType.isSByte(operandType)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long)0xff)), outerPrecedence, codeScope); - } else if(SymbolType.isWord(operandType) || SymbolType.isSWord(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long)0xffff)), outerPrecedence, codeScope); - } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { - return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long)0xffffffff)), outerPrecedence, codeScope); + if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { + return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long) 0xff)), outerPrecedence, codeScope); + } else if(SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType) || operandType instanceof SymbolTypePointer || SymbolType.STRING.equals(operandType)) { + return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long) 0xffff)), outerPrecedence, codeScope); + } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { + return getAsmConstant(program, new ConstantBinary(operand, Operators.BOOL_XOR, new ConstantInteger((long) 0xffffffff)), outerPrecedence, codeScope); } else { - throw new CompileError("Unhandled type "+operand); + throw new CompileError("Unhandled type " + operand); } } else { return operator.getOperator() + @@ -200,7 +230,11 @@ public class AsmFormat { if(number.longValue() >= 0L && number.longValue() <= 255L) { return SHORT_ASM_NUMBERS[number.intValue()]; } else { - return String.format("$%x", number.longValue()); + if(number.longValue()<0) { + return "-"+getAsmNumber(-number.longValue()); + } else { + return String.format("$%x", number.longValue()); + } } } throw new RuntimeException("Unsupported number type " + number); @@ -208,6 +242,7 @@ public class AsmFormat { /** * Get the ASM code for a boolean value + * * @param bool the boolean vallue * @return "0" / "1" */ diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java index 9a34ffe2a..92ff9d606 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstance.java @@ -3,14 +3,12 @@ package dk.camelot64.kickc.fragment; import dk.camelot64.kickc.NumberParser; import dk.camelot64.kickc.asm.*; import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.values.ConstantInteger; -import dk.camelot64.kickc.model.values.ConstantValue; +import dk.camelot64.kickc.model.symbols.StructDefinition; +import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.symbols.ConstantVar; import dk.camelot64.kickc.model.symbols.Label; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.values.ScopeRef; -import dk.camelot64.kickc.model.values.Value; import dk.camelot64.kickc.parser.KickCBaseVisitor; import dk.camelot64.kickc.parser.KickCParser; @@ -97,6 +95,16 @@ public class AsmFragmentInstance { } else if(boundValue instanceof Label) { String param = ((Label) boundValue).getLocalName().replace('@', 'b').replace(':', '_').replace("$", "_"); return new AsmParameter(param, false); + } else if(boundValue instanceof StructMemberRef) { + StructMemberRef structMemberRef = (StructMemberRef) boundValue; + StructDefinition structDefinition = program.getScope().getStructDefinition(structMemberRef); + Variable structMember = structDefinition.getMember(structMemberRef.getMemberName()); + int memberByteOffset = structDefinition.getMemberByteOffset(structMember); + VariableRef struct = (VariableRef) structMemberRef.getStruct(); + Variable structVar = program.getScope().getVariable( struct); + Registers.RegisterZpStruct structRegister = (Registers.RegisterZpStruct) structVar.getAllocation(); + // TODO Use STRUCT_OFFSET constants instead of hardcoded constants + return new AsmParameter(AsmFormat.getAsmParamName(structVar, codeScopeRef)+"+"+memberByteOffset,true); } else { throw new RuntimeException("Bound Value Type not implemented " + boundValue); } @@ -300,8 +308,7 @@ public class AsmFragmentInstance { @Override public AsmParameter visitAsmExprInt(KickCParser.AsmExprIntContext ctx) { Number number = NumberParser.parseLiteral(ctx.NUMBER().getText()); - ConstantInteger intVal = new ConstantInteger(number.longValue()); - boolean isZp = SymbolType.isByte(intVal.getType()) || SymbolType.isSByte(intVal.getType()); + boolean isZp = SymbolType.BYTE.contains(number.longValue()) || SymbolType.SBYTE.contains(number.longValue()); String param = AsmFormat.getAsmNumber(number); return new AsmParameter(param, isZp); } diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java index 539207338..9a003f18b 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java @@ -3,11 +3,8 @@ package dk.camelot64.kickc.fragment; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypeMulti; -import dk.camelot64.kickc.model.values.ConstantValue; -import dk.camelot64.kickc.model.values.ScopeRef; -import dk.camelot64.kickc.model.values.Value; +import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed; +import dk.camelot64.kickc.model.values.*; import java.util.*; @@ -38,6 +35,7 @@ public class AsmFragmentInstanceSpec { /** * Creates an asm fragment instance specification. + * * @param program The symbol table * @param signature The fragment signature. * @param bindings Binding of named values in the fragment to values (constants, variables, ...) @@ -50,6 +48,7 @@ public class AsmFragmentInstanceSpec { this.codeScopeRef = codeScopeRef; } + public String getSignature() { return signature; } @@ -70,7 +69,7 @@ public class AsmFragmentInstanceSpec { private ConstantValue variationConstant; /** When iterating variations this is iterates the potential types for the constant value. */ - private Iterator variationIterator; + private Iterator variationIterator; /** The name of the current variation in the bindings. */ private String variationCurrentName; @@ -82,10 +81,11 @@ public class AsmFragmentInstanceSpec { * Does any more variations of the ASM fragment instance specification exist? * Variations are used for finding the right fragment to use for constant numbers. * For instance the number 1000 can be represented as several different types (unsigned/signed word/dword). + * * @return true if more variations exits */ public boolean hasNextVariation() { - if(variationIterator==null) { + if(variationIterator == null) { // Look for variations // TODO Currently only one iterable constant value is handled - add support for multiple iterable constant values! for(String name : bindings.keySet()) { @@ -93,9 +93,9 @@ public class AsmFragmentInstanceSpec { // Found a constant value that may be multi-typed Value value = bindings.get(name); if(value instanceof ConstantValue) { - SymbolType symbolType = SymbolTypeInference.inferType(program.getScope(), (ConstantValue) value); - if(symbolType instanceof SymbolTypeMulti) { - Collection types = ((SymbolTypeMulti) symbolType).getTypes(); + ConstantLiteral constantLiteral = ((ConstantValue) value).calculateLiteral(program.getScope()); + if(constantLiteral instanceof ConstantInteger) { + List types = getVariationTypes(((ConstantInteger) constantLiteral).getValue()); if(types.size() > 1) { // Found constant value with multiple types variationConstant = (ConstantValue) value; @@ -111,13 +111,29 @@ public class AsmFragmentInstanceSpec { } // If no variations exist add empty iterator if(variationIterator == null) { - List empty = new ArrayList<>(); + List empty = new ArrayList<>(); variationIterator = empty.iterator(); } } return variationIterator.hasNext(); } + /** + * Find any fixed integer types that can contain the passed integer value + * @param value the value to examine + * @return All fixed size integer types capable of representing the passed value + */ + public static List getVariationTypes(Long value) { + ArrayList potentialTypes = new ArrayList<>(); + for(SymbolTypeIntegerFixed typeInteger : SymbolTypeIntegerFixed.getIntegerFixedTypes()) { + if(typeInteger.contains(value)) { + potentialTypes.add(typeInteger); + } + } + return potentialTypes; + } + + /** * Updates the ASM fragment instance specification to the next available variation. * If no more variations exist the ASM fragment instance specification will become unusable. @@ -126,7 +142,7 @@ public class AsmFragmentInstanceSpec { if(hasNextVariation()) { SymbolType nextVariationValue = variationIterator.next(); // Find the next name - String variationConstName = "c"+variationCurrentName.substring(variationCurrentName.length() - 1); + String variationConstName = "c" + variationCurrentName.substring(variationCurrentName.length() - 1); String variationNextName = AsmFragmentInstanceSpecFactory.getTypePrefix(nextVariationValue) + variationConstName; // Update bindings Value constValue = bindings.get(variationCurrentName); @@ -136,7 +152,7 @@ public class AsmFragmentInstanceSpec { this.signature = signature.replace(variationCurrentName, variationNextName); variationCurrentName = variationNextName; variationCurrentValue = nextVariationValue; - } else { + } else { this.signature = "no-more-variations"; this.bindings = new LinkedHashMap<>(); } diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java index 396ec781e..c50725d1b 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpecFactory.java @@ -1,23 +1,17 @@ package dk.camelot64.kickc.fragment; -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.ControlFlowGraph; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.Registers; +import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.operators.Operator; +import dk.camelot64.kickc.model.operators.OperatorUnary; +import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementConditionalJump; -import dk.camelot64.kickc.model.symbols.ConstantVar; -import dk.camelot64.kickc.model.symbols.Label; -import dk.camelot64.kickc.model.symbols.Symbol; -import dk.camelot64.kickc.model.symbols.Variable; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeProcedure; +import dk.camelot64.kickc.model.symbols.*; +import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.*; +import java.lang.InternalError; import java.util.LinkedHashMap; import java.util.Map; @@ -87,6 +81,7 @@ public class AsmFragmentInstanceSpecFactory { /** * Get the created ASM fragment instance specification + * * @return The ASM fragment instance specification */ public AsmFragmentInstanceSpec getAsmFragmentInstanceSpec() { @@ -226,15 +221,56 @@ public class AsmFragmentInstanceSpecFactory { public String bind(Value value, SymbolType castType) { if(value instanceof CastValue) { - CastValue castVal = (CastValue) value; - SymbolType toType = castVal.getToType(); - value = castVal.getValue(); - return bind(value, toType); + CastValue cast = (CastValue) value; + SymbolType toType = cast.getToType(); + OperatorUnary castUnary = Operators.getCastUnary(toType); + RValue castValue = cast.getValue(); + SymbolType castValueType = SymbolTypeInference.inferType(this.program.getScope(), castValue); + if(castValueType.getSizeBytes() == toType.getSizeBytes()) { + return bind(castValue, toType); + } else { + return getOperatorFragmentName(castUnary) + bind(castValue); + } } else if(value instanceof ConstantCastValue) { ConstantCastValue castVal = (ConstantCastValue) value; - SymbolType toType = castVal.getToType(); - value = castVal.getValue(); - return bind(value, toType); + ConstantValue val = castVal.getValue(); + if(castType == null) { + SymbolType toType = castVal.getToType(); + // If value literal not matching cast type then add expression code to transform it into the value space ( eg. value & 0xff ) + + if(toType instanceof SymbolTypeIntegerFixed) { + SymbolTypeIntegerFixed integerFixed = (SymbolTypeIntegerFixed) toType; + ConstantLiteral constantLiteral; + Long integerValue; + try { + constantLiteral = val.calculateLiteral(program.getScope()); + if(constantLiteral instanceof ConstantInteger) { + integerValue = ((ConstantInteger) constantLiteral).getValue(); + } else if(constantLiteral instanceof ConstantPointer) { + integerValue = ((ConstantPointer) constantLiteral).getValue(); + } else { + throw new InternalError("Not implemented " + constantLiteral); + } + } catch(ConstantNotLiteral e) { + // Assume it is a word + integerValue = 0xffffL; + } + + if(!integerFixed.contains(integerValue)) { + if(toType.getSizeBytes() == 1) { + val = new ConstantBinary(new ConstantInteger(0xffL, SymbolType.BYTE), Operators.BOOL_AND, val); + } else if(toType.getSizeBytes() == 2) { + val = new ConstantBinary(new ConstantInteger(0xffffL, SymbolType.WORD), Operators.BOOL_AND, val); + } else { + throw new InternalError("Not implemented " + toType); + } + } + } + + return bind(val, toType); + } else { + return bind(val, castType); + } } else if(value instanceof PointerDereference) { PointerDereference deref = (PointerDereference) value; SymbolType ptrType = null; @@ -267,6 +303,27 @@ public class AsmFragmentInstanceSpecFactory { String name = "la" + nextLabelIdx++; bind(name, value); return name; + } else if(value instanceof StructZero) { + return "vssf" + ((StructZero) value).getTypeStruct().getSizeBytes(); + } else if(value instanceof StructMemberRef) { + StructMemberRef structMemberRef = (StructMemberRef) value; + StructDefinition structDefinition = program.getScope().getStructDefinition(structMemberRef); + Variable structMember = structDefinition.getMember(structMemberRef.getMemberName()); + int memberByteOffset = structDefinition.getMemberByteOffset(structMember); + + RValue struct = structMemberRef.getStruct(); + if(struct instanceof VariableRef) { + Variable structVar = program.getScope().getVariable((VariableRef) struct); + if(structVar.getAllocation() instanceof Registers.RegisterZpStruct) { + Registers.RegisterZpStruct structRegister = (Registers.RegisterZpStruct) structVar.getAllocation(); + Registers.RegisterZpStructMember memberRegister = structRegister.getMemberRegister(memberByteOffset); + String name = getTypePrefix(structMember.getType()) + getRegisterName(memberRegister); + bind(name, structMemberRef); + return name; + } + } else { + return bind(struct) + "_mbr_" + memberByteOffset; + } } throw new RuntimeException("Binding of value type not supported " + value); } @@ -288,35 +345,37 @@ public class AsmFragmentInstanceSpecFactory { * @return The type name */ static String getTypePrefix(SymbolType type) { - if(SymbolType.isByte(type)) { + if(SymbolType.BYTE.equals(type)) { return "vbu"; - } else if(SymbolType.isSByte(type)) { + } else if(SymbolType.SBYTE.equals(type)) { return "vbs"; - } else if(SymbolType.isWord(type)) { + } else if(SymbolType.WORD.equals(type)) { return "vwu"; - } else if(SymbolType.isSWord(type)) { + } else if(SymbolType.SWORD.equals(type)) { return "vws"; - } else if(SymbolType.isDWord(type)) { + } else if(SymbolType.DWORD.equals(type)) { return "vdu"; - } else if(SymbolType.isSDWord(type)) { + } else if(SymbolType.SDWORD.equals(type)) { return "vds"; } else if(SymbolType.STRING.equals(type)) { return "pbu"; } else if(SymbolType.BOOLEAN.equals(type)) { return "vbo"; + } else if(type instanceof SymbolTypeStruct) { + return "vss"; } else if(type instanceof SymbolTypePointer) { SymbolType elementType = ((SymbolTypePointer) type).getElementType(); - if(SymbolType.isByte(elementType)) { + if(SymbolType.BYTE.equals(elementType)) { return "pbu"; - } else if(SymbolType.isSByte(elementType)) { + } else if(SymbolType.SBYTE.equals(elementType)) { return "pbs"; - } else if(SymbolType.isWord(elementType)) { + } else if(SymbolType.WORD.equals(elementType)) { return "pwu"; - } else if(SymbolType.isSWord(elementType)) { + } else if(SymbolType.SWORD.equals(elementType)) { return "pws"; - } else if(SymbolType.isDWord(elementType)) { + } else if(SymbolType.DWORD.equals(elementType)) { return "pdu"; - } else if(SymbolType.isSDWord(elementType)) { + } else if(SymbolType.SDWORD.equals(elementType)) { return "pds"; } else if(SymbolType.BOOLEAN.equals(elementType)) { return "pbo"; @@ -324,6 +383,8 @@ public class AsmFragmentInstanceSpecFactory { return "ppr"; } else if(elementType instanceof SymbolTypePointer) { return "ppt"; + } else if(elementType instanceof SymbolTypeStruct) { + return "pss"; } else { throw new RuntimeException("Not implemented " + type); } @@ -344,8 +405,9 @@ public class AsmFragmentInstanceSpecFactory { Registers.RegisterType.ZP_BOOL.equals(register.getType()) || Registers.RegisterType.ZP_BYTE.equals(register.getType()) || Registers.RegisterType.ZP_WORD.equals(register.getType()) || - Registers.RegisterType.ZP_DWORD.equals(register.getType()) - ) { + Registers.RegisterType.ZP_DWORD.equals(register.getType()) || + Registers.RegisterType.ZP_STRUCT.equals(register.getType()) + ) { // Examine if the ZP register is already bound Registers.RegisterZp registerZp = (Registers.RegisterZp) register; String zpNameIdx = null; diff --git a/src/main/java/dk/camelot64/kickc/model/InternalError.java b/src/main/java/dk/camelot64/kickc/model/InternalError.java new file mode 100644 index 000000000..abf3ec469 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/InternalError.java @@ -0,0 +1,24 @@ +package dk.camelot64.kickc.model; + +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementSource; + +/** Signals an internal error in the compiler. Should be reported to the author. */ +public class InternalError extends RuntimeException { + + public InternalError(String message) { + super(message); + } + + public InternalError(String message, StatementSource source) { + super(message+"\n"+source.toString()); + } + + public InternalError(String message, Statement statement) { + this(message, statement.getSource()); + } + + public InternalError(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/dk/camelot64/kickc/model/Registers.java b/src/main/java/dk/camelot64/kickc/model/Registers.java index b889d62bd..0b36bb7d9 100644 --- a/src/main/java/dk/camelot64/kickc/model/Registers.java +++ b/src/main/java/dk/camelot64/kickc/model/Registers.java @@ -45,6 +45,7 @@ public class Registers { ZP_BYTE, ZP_WORD, ZP_DWORD, + ZP_STRUCT, ZP_BOOL, CONSTANT } @@ -104,6 +105,7 @@ public class Registers { public int hashCode() { return zp; } + } @@ -150,6 +152,38 @@ public class Registers { } + /** Zero page addresses used as a register for a struct variable. */ + public static class RegisterZpStruct extends RegisterZp { + + public RegisterZpStruct(int zp) { + super(zp); + } + + public RegisterZpStructMember getMemberRegister(int memberByteOffset) { + return new RegisterZpStructMember(getZp()+memberByteOffset); + } + + @Override + public RegisterType getType() { + return RegisterType.ZP_STRUCT; + } + + } + + /** Zero page addresses used as a register for a struct member variable. */ + public static class RegisterZpStructMember extends RegisterZp { + + public RegisterZpStructMember(int zp) { + super(zp); + } + + @Override + public RegisterType getType() { + return RegisterType.ZP_STRUCT; + } + + } + /** A zero page address used as a register for a boolean variable. */ public static class RegisterZpBool extends RegisterZp { diff --git a/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java b/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java index fec6f0316..a799b28bd 100644 --- a/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java +++ b/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java @@ -224,9 +224,11 @@ public class VariableReferenceInfos { public Collection getConstRefStatements(ConstantRef constRef) { Collection refs = symbolVarReferences.get(constRef); LinkedHashSet stmts = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) - .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) + .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + } return stmts; } @@ -239,9 +241,11 @@ public class VariableReferenceInfos { public Collection getVarRefStatements(VariableRef varRef) { Collection refs = symbolVarReferences.get(varRef); LinkedHashSet stmts = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) - .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) + .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + } return stmts; } @@ -254,10 +258,12 @@ public class VariableReferenceInfos { public Collection getVarUseStatements(VariableRef varRef) { Collection refs = symbolVarReferences.get(varRef); LinkedHashSet stmts = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) - .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE == referenceToSymbolVar.getReferenceType()) - .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) + .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE == referenceToSymbolVar.getReferenceType()) + .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + } return stmts; } @@ -271,10 +277,12 @@ public class VariableReferenceInfos { public Collection getSymbolRefConsts(ConstantRef constRef) { Collection refs = symbolVarReferences.get(constRef); LinkedHashSet constRefs = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType())) - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInSymbol) - .forEach(referenceToSymbolVar -> constRefs.add(((ReferenceInSymbol) referenceToSymbolVar).getReferencingSymbol())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType())) + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInSymbol) + .forEach(referenceToSymbolVar -> constRefs.add(((ReferenceInSymbol) referenceToSymbolVar).getReferencingSymbol())); + } return constRefs; } diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpression.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpression.java new file mode 100644 index 000000000..d15faf978 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpression.java @@ -0,0 +1,26 @@ +package dk.camelot64.kickc.model.iterator; + +import dk.camelot64.kickc.model.operators.Operator; +import dk.camelot64.kickc.model.values.Value; + +/** A unary or binary operator expression. + * Iterable using {@link ProgramExpressionIterator}. + * */ +public interface ProgramExpression { + + /** + * Get the operator + * + * @return the operator + */ + Operator getOperator(); + + /** + * Replace the unary/binary expression with a new value. + * + * Throws an exception if replacement is not possible + * + * @param value The new value. + */ + void set(Value value); +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java new file mode 100644 index 000000000..f21ea8348 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java @@ -0,0 +1,406 @@ +package dk.camelot64.kickc.model.iterator; + +import dk.camelot64.kickc.model.Comment; +import dk.camelot64.kickc.model.InternalError; +import dk.camelot64.kickc.model.operators.OperatorBinary; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.statements.StatementConditionalJump; +import dk.camelot64.kickc.model.statements.StatementPhiBlock; +import dk.camelot64.kickc.model.symbols.ProgramScope; +import dk.camelot64.kickc.model.symbols.Scope; +import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.symbols.VariableIntermediate; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.*; + +import java.util.ListIterator; + +/** + * A binary expression in the program being iterated by {@link ProgramExpressionIterator} + */ +public interface ProgramExpressionBinary extends ProgramExpression { + + /** + * Get the left operand + * + * @return The left operand + */ + RValue getLeft(); + + /** + * Get the binary operator + * + * @return the operator + */ + OperatorBinary getOperator(); + + /** + * Get the right operand + * + * @return The right operand + */ + RValue getRight(); + + /** + * Adds a cast to the left operand + * + * @param toType The toType to cast to + */ + void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols); + + /** + * Adds a cast to the right operand + * + * @param toType The toType to cast to + */ + void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols); + + + /** Binary expression assignment rvalue. */ + class ProgramExpressionBinaryAssignmentRValue implements ProgramExpressionBinary { + + private final StatementAssignment assignment; + + ProgramExpressionBinaryAssignmentRValue(StatementAssignment assignment) { + this.assignment = assignment; + } + + @Override + public RValue getLeft() { + return assignment.getrValue1(); + } + + @Override + public OperatorBinary getOperator() { + return (OperatorBinary) assignment.getOperator(); + } + + @Override + public RValue getRight() { + return assignment.getrValue2(); + } + + @Override + public void set(Value value) { + assignment.setrValue2((RValue) value); + assignment.setOperator(null); + assignment.setrValue1(null); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(assignment.getrValue1() instanceof ConstantValue) { + assignment.setrValue1(new ConstantCastValue(toType, (ConstantValue) assignment.getrValue1())); + } else { + Scope blockScope = symbols.getScope(currentScope); + VariableIntermediate tmpVar = blockScope.addVariableIntermediate(); + tmpVar.setTypeInferred(toType); + StatementAssignment newAssignment = new StatementAssignment(tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue1(), assignment.getSource(), Comment.NO_COMMENTS); + assignment.setrValue1(tmpVar.getRef()); + stmtIt.previous(); + stmtIt.add(newAssignment); + stmtIt.next(); + } + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(assignment.getrValue2() instanceof ConstantValue) { + assignment.setrValue2(new ConstantCastValue(toType, (ConstantValue) assignment.getrValue2())); + } else { + Scope blockScope = symbols.getScope(currentScope); + VariableIntermediate tmpVar = blockScope.addVariableIntermediate(); + tmpVar.setTypeInferred(toType); + StatementAssignment newAssignment = new StatementAssignment(tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue2(), assignment.getSource(), Comment.NO_COMMENTS); + assignment.setrValue2(tmpVar.getRef()); + stmtIt.previous(); + stmtIt.add(newAssignment); + stmtIt.next(); + } + } + } + + /** Binary expression - assignment lvalue and the "total" rvalue. */ + class ProgramExpressionBinaryAssignmentLValue implements ProgramExpressionBinary { + private final StatementAssignment assignment; + + ProgramExpressionBinaryAssignmentLValue(StatementAssignment assignment) { + this.assignment = assignment; + } + + @Override + public RValue getLeft() { + return assignment.getlValue(); + } + + @Override + public OperatorBinary getOperator() { + return Operators.ASSIGNMENT; + } + + @Override + public RValue getRight() { + if(assignment.getrValue1() == null && assignment.getOperator() == null) { + return assignment.getrValue2(); + } else { + return new AssignmentRValue(assignment); + } + } + + @Override + public void set(Value value) { + throw new InternalError("Updating an entire assignment is not allowed!"); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(assignment.getlValue() instanceof VariableRef) { + Variable variable = symbols.getVariable((VariableRef) assignment.getlValue()); + if(variable.isInferredType()) + variable.setTypeInferred(toType); + else + throw new InternalError("Cannot cast declared type!" + variable.toString()); + } else { + Scope blockScope = symbols.getScope(currentScope); + VariableIntermediate tmpVar = blockScope.addVariableIntermediate(); + SymbolType rightType = SymbolTypeInference.inferType(symbols, getRight()); + tmpVar.setTypeInferred(rightType); + StatementAssignment newAssignment = new StatementAssignment(assignment.getlValue(), Operators.getCastUnary(toType), tmpVar.getRef(), assignment.getSource(), Comment.NO_COMMENTS); + assignment.setlValue(tmpVar.getRef()); + stmtIt.add(newAssignment); + } + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(assignment.getrValue1() == null && assignment.getOperator() == null) { + assignment.setOperator(Operators.getCastUnary(toType)); + } else { + Scope blockScope = symbols.getScope(currentScope); + VariableIntermediate tmpVar = blockScope.addVariableIntermediate(); + SymbolType rightType = SymbolTypeInference.inferType(symbols, getRight()); + tmpVar.setTypeInferred(rightType); + StatementAssignment newAssignment = new StatementAssignment(assignment.getlValue(), Operators.getCastUnary(toType), tmpVar.getRef(), assignment.getSource(), Comment.NO_COMMENTS); + assignment.setlValue(tmpVar.getRef()); + stmtIt.add(newAssignment); + } + } + + } + + /** Binary expression conditional jump. */ + class ProgramExpressionBinaryConditionalJump implements ProgramExpressionBinary { + private final StatementConditionalJump conditionalJump; + + ProgramExpressionBinaryConditionalJump(StatementConditionalJump assignment) { + this.conditionalJump = assignment; + } + + @Override + public RValue getLeft() { + return conditionalJump.getrValue1(); + } + + @Override + public OperatorBinary getOperator() { + return (OperatorBinary) conditionalJump.getOperator(); + } + + @Override + public RValue getRight() { + return conditionalJump.getrValue2(); + } + + @Override + public void set(Value value) { + conditionalJump.setrValue2((RValue) value); + conditionalJump.setOperator(null); + conditionalJump.setrValue1(null); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(conditionalJump.getrValue1() instanceof ConstantValue) { + conditionalJump.setrValue1(new ConstantCastValue(toType, (ConstantValue) conditionalJump.getrValue1())); + } else { + throw new InternalError("Not implemented!"); + } + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(conditionalJump.getrValue2() instanceof ConstantValue) { + conditionalJump.setrValue2(new ConstantCastValue(toType, (ConstantValue) conditionalJump.getrValue2())); + } else { + throw new InternalError("Not implemented!"); + } + } + + + } + + /** Binary expression as part of a constant expression. */ + class ProgramExpressionBinaryConstant implements ProgramExpressionBinary { + /** A program value containing a {@link ConstantBinary}. */ + private ProgramValue programValue; + + public ProgramExpressionBinaryConstant(ProgramValue programValue) { + this.programValue = programValue; + } + + public ConstantBinary getConstantBinary() { + return (ConstantBinary) programValue.get(); + } + + @Override + public RValue getLeft() { + return getConstantBinary().getLeft(); + } + + @Override + public OperatorBinary getOperator() { + return getConstantBinary().getOperator(); + } + + @Override + public RValue getRight() { + return getConstantBinary().getRight(); + } + + @Override + public void set(Value value) { + programValue.set(value); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + getConstantBinary().setLeft(new ConstantCastValue(toType, getConstantBinary().getLeft())); + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + getConstantBinary().setRight(new ConstantCastValue(toType, getConstantBinary().getRight())); + } + } + + /** Binary expression that is an indexed dereference of a pointer eg. ptr[i] or *(ptr+i). */ + class ProgramExpressionBinaryPointerDereferenceIndexed implements ProgramExpressionBinary { + /** A program value containing a {@link ConstantBinary}. */ + private ProgramValue programValue; + + public ProgramExpressionBinaryPointerDereferenceIndexed(ProgramValue programValue) { + this.programValue = programValue; + } + + public PointerDereferenceIndexed getPointerDereferenceIndexed() { + return (PointerDereferenceIndexed) programValue.get(); + } + + @Override + public RValue getLeft() { + return getPointerDereferenceIndexed().getPointer(); + } + + @Override + public OperatorBinary getOperator() { + return Operators.PLUS; + } + + @Override + public RValue getRight() { + return getPointerDereferenceIndexed().getIndex(); + } + + @Override + public void set(Value value) { + programValue.set(value); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(getPointerDereferenceIndexed().getPointer() instanceof ConstantValue) { + getPointerDereferenceIndexed().setPointer(new ConstantCastValue(toType, (ConstantValue) getPointerDereferenceIndexed().getPointer())); + } else { + // Try to use CastValue - may later have to be supported! + getPointerDereferenceIndexed().setPointer(new CastValue(toType, getPointerDereferenceIndexed().getPointer())); + } + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(getPointerDereferenceIndexed().getIndex() instanceof ConstantValue) { + getPointerDereferenceIndexed().setIndex(new ConstantCastValue(toType, (ConstantValue) getPointerDereferenceIndexed().getIndex())); + } else if( getPointerDereferenceIndexed().getIndex() instanceof VariableRef) { + Variable variable = symbols.getVariable((VariableRef) getPointerDereferenceIndexed().getIndex()); + if(variable.isInferredType()) + variable.setTypeInferred(toType); + else + throw new InternalError("Cannot cast declared type!" + variable.toString()); + + } else { + // Try to use CastValue - may later have to be supported! + getPointerDereferenceIndexed().setIndex(new CastValue(toType, getPointerDereferenceIndexed().getIndex())); + } + } + } + + + /** Assignment of a phi value to a phi variable. */ + class ProgramExpressionBinaryPhiValueAssignemnt implements ProgramExpressionBinary { + + private final StatementPhiBlock.PhiVariable phiVariable; + private final StatementPhiBlock.PhiRValue value; + + public ProgramExpressionBinaryPhiValueAssignemnt(StatementPhiBlock.PhiVariable phiVariable, StatementPhiBlock.PhiRValue value) { + this.phiVariable = phiVariable; + this.value = value; + } + + @Override + public RValue getLeft() { + return phiVariable.getVariable(); + } + + @Override + public OperatorBinary getOperator() { + return Operators.ASSIGNMENT; + } + + @Override + public RValue getRight() { + return value.getrValue(); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + Variable variable = symbols.getVariable(phiVariable.getVariable()); + if(variable.isInferredType()) + variable.setTypeInferred(toType); + else + throw new InternalError("Cannot cast declared type!" + variable.toString()); + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(getRight() instanceof VariableRef) { + Variable variable = symbols.getVariable((VariableRef) getRight()); + if(variable.isInferredType()) + variable.setTypeInferred(toType); + } else if(getRight() instanceof ConstantValue) { + value.setrValue(new ConstantCastValue(toType, (ConstantValue) getRight())); + } else { + value.setrValue(new CastValue(toType, getRight())); + } + } + + @Override + public void set(Value value) { + throw new InternalError("Not supported!"); + } + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionHandler.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionHandler.java new file mode 100644 index 000000000..077eb7cdd --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionHandler.java @@ -0,0 +1,26 @@ +package dk.camelot64.kickc.model.iterator; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.statements.Statement; + +import java.util.ListIterator; + +/** A handler that performs some action for unary/binary expressions in the program. + * A {@link ProgramExpressionIterator} can be used to iterate all unary/binary expressions in a part of the program. + * The Handler then receives all unary/binary expressions one at a time. + * The Handler has the option of modifying the expression. After the handler is executed all sub-values are recursed. + * The execute() method furthermore receives some extra parameters with information about the context of the passed value. + */ +public interface ProgramExpressionHandler { + + /** + * Handle a single expression + * + * @param programExpression The expression + * @param currentStmt The statement iterator - just past the current statement that the value is a part of. Current statment can be retrieved by calling + * @param stmtIt The statement iterator - just past the current statement. Can be used for modifying the control flow block. + * @param currentBlock The current block that the value is a part of + */ + void execute(ProgramExpression programExpression, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock); + +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java new file mode 100644 index 000000000..4411ffd80 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java @@ -0,0 +1,75 @@ +package dk.camelot64.kickc.model.iterator; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.statements.StatementConditionalJump; +import dk.camelot64.kickc.model.statements.StatementPhiBlock; +import dk.camelot64.kickc.model.values.*; + +import java.util.ListIterator; + +/** + * Capable of iterating the different structures of a Program (graph, block, statement, symboltable, symbol). + * Creates appropriate BinaryExpressions and passes them to a ProgramExpressionHandler. + * Iteration might be guided (eg. filtering some types of the structure to iterate at call-time) + */ +public class ProgramExpressionIterator { + + /** + * Execute a handler on all values in the entire program (both in the control flow graph and the symbol table.) + * + * @param program The program + * @param handler The handler to execute + */ + public static void execute(Program program, ProgramExpressionHandler handler) { + // Iterate all symbols + ProgramValueHandler programValueHandler = (programValue, currentStmt, stmtIt, currentBlock) -> { + if(programValue.get() instanceof ConstantBinary) { + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryConstant(programValue), currentStmt, stmtIt, currentBlock); + } else if(programValue.get() instanceof ConstantUnary) { + handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryConstant(programValue), currentStmt, stmtIt, currentBlock); + } else if(programValue.get() instanceof PointerDereferenceIndexed) { + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed(programValue), currentStmt, stmtIt, currentBlock); + } else if(programValue.get() instanceof ConstantCastValue) { + handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryConstantCast(programValue), currentStmt, stmtIt, currentBlock); + } else if(programValue.get() instanceof CastValue) { + handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryCast(programValue), currentStmt, stmtIt, currentBlock); + } + }; + ProgramValueIterator.execute(program.getScope(), programValueHandler); + + // Iterate all blocks/statements + for(ControlFlowBlock block : program.getGraph().getAllBlocks()) { + ListIterator stmtIt = block.getStatements().listIterator(); + while(stmtIt.hasNext()) { + Statement stmt = stmtIt.next(); + if(stmt instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) stmt; + if(assignment.getrValue1() != null && assignment.getOperator() != null && assignment.getrValue2() != null) { + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryAssignmentRValue(assignment), stmt, stmtIt, block); + } else if(assignment.getrValue1() == null && assignment.getOperator() != null && assignment.getrValue2() != null) { + handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryAssignmentRValue(assignment), stmt, stmtIt, block); + } + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryAssignmentLValue(assignment), stmt, stmtIt, block); + } else if(stmt instanceof StatementConditionalJump) { + StatementConditionalJump condJump = (StatementConditionalJump) stmt; + if(condJump.getrValue1() != null && condJump.getOperator() != null && condJump.getrValue2() != null) { + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryConditionalJump(condJump), stmt, stmtIt, block); + } + } else if(stmt instanceof StatementPhiBlock) { + for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) stmt).getPhiVariables()) { + for(StatementPhiBlock.PhiRValue value : phiVariable.getValues()) { + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryPhiValueAssignemnt(phiVariable, value), stmt, stmtIt, block); + } + } + } + // Iterate all statement values + ProgramValueIterator.execute(stmt, programValueHandler, stmtIt, block); + } + } + + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionUnary.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionUnary.java new file mode 100644 index 000000000..5b0fe07d9 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionUnary.java @@ -0,0 +1,146 @@ +package dk.camelot64.kickc.model.iterator; + +import dk.camelot64.kickc.model.operators.OperatorUnary; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.values.*; + +/** + * A binary expression in the program being iterated by {@link ProgramExpressionIterator} + */ +public interface ProgramExpressionUnary extends ProgramExpression { + + /** + * Get the unary operator + * + * @return the operator + */ + OperatorUnary getOperator(); + + /** + * Get the right operand + * + * @return The right operand + */ + RValue getOperand(); + + /** Unary expression assignment rvalue. */ + class ProgramExpressionUnaryAssignmentRValue implements ProgramExpressionUnary { + private final StatementAssignment assignment; + + ProgramExpressionUnaryAssignmentRValue(StatementAssignment assignment) { + this.assignment = assignment; + } + + @Override + public OperatorUnary getOperator() { + return (OperatorUnary) assignment.getOperator(); + } + + @Override + public RValue getOperand() { + return assignment.getrValue2(); + } + + @Override + public void set(Value value) { + assignment.setrValue2((RValue) value); + assignment.setOperator(null); + } + } + + /** Unary expression as part of a constant expression. */ + class ProgramExpressionUnaryConstant implements ProgramExpressionUnary { + + /** A ProgramValue containing a {@link ConstantUnary}. */ + private ProgramValue programValue; + + ProgramExpressionUnaryConstant(ProgramValue programValue) { + this.programValue = programValue; + } + + public ConstantUnary getConstantUnary() { + return (ConstantUnary) programValue.get(); + } + + @Override + public OperatorUnary getOperator() { + return (getConstantUnary()).getOperator(); + } + + @Override + public RValue getOperand() { + return getConstantUnary().getOperand(); + } + + @Override + public void set(Value value) { + programValue.set(value); + } + + } + + /** Unary cast expression {@link ConstantCastValue} as part of a constant expression. */ + class ProgramExpressionUnaryConstantCast implements ProgramExpressionUnary { + + /** A ProgramValue containing a {@link ConstantCastValue}. */ + private ProgramValue programValue; + + ProgramExpressionUnaryConstantCast(ProgramValue programValue) { + this.programValue = programValue; + } + + public ConstantCastValue getConstantUnary() { + return (ConstantCastValue) programValue.get(); + } + + @Override + public OperatorUnary getOperator() { + return Operators.getCastUnary(getConstantUnary().getToType()); + } + + @Override + public RValue getOperand() { + return getConstantUnary().getValue(); + } + + @Override + public void set(Value value) { + programValue.set(value); + } + + } + + /** Unary cast expression {@link CastValue} as part of a constant expression. */ + class ProgramExpressionUnaryCast implements ProgramExpressionUnary { + + /** A ProgramValue containing a {@link CastValue}. */ + private ProgramValue programValue; + + ProgramExpressionUnaryCast(ProgramValue programValue) { + this.programValue = programValue; + } + + public CastValue getConstantUnary() { + return (CastValue) programValue.get(); + } + + @Override + public OperatorUnary getOperator() { + return Operators.getCastUnary(getConstantUnary().getToType()); + } + + @Override + public RValue getOperand() { + return getConstantUnary().getValue(); + } + + @Override + public void set(Value value) { + programValue.set(value); + } + + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java index 9f34e3c20..c6d75927a 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java @@ -7,486 +7,20 @@ import dk.camelot64.kickc.model.types.SymbolTypeArray; import dk.camelot64.kickc.model.values.*; /** - * An RValue in the program being iterated by {@link ProgramValueIterator}. + * Any Value in the program being iterated by {@link ProgramValueIterator}. * - * The RValue can be inspected using get() and replaced inside the model using set(val). + * The Value can be inspected using get() and replaced inside the model using set(val). * - * The context of the RValue can be determined from the sub-class containing it plus the parameters to the ProgramValueHandler. + * The context of the Value can be determined from the sub-class containing it plus the parameters to the ProgramValueHandler. * */ -public abstract class ProgramValue { +public interface ProgramValue { - public abstract Value get(); + Value get(); - public abstract void set(Value value); + void set(Value value); - public static class ConstantVariableValue extends ProgramValue { - private final ConstantVar constantVar; - - ConstantVariableValue(ConstantVar constantVar) { - this.constantVar = constantVar; - } - - @Override - public Value get() { - return constantVar.getValue(); - } - - @Override - public void set(Value val) { - constantVar.setValue((ConstantValue) val); - } - - } - - /** Size inside a fixed size array. */ - public static class TypeArraySize extends ProgramValue { - private final SymbolTypeArray array; - - TypeArraySize(SymbolTypeArray array) { - this.array = array; - } - - @Override - public Value get() { - return array.getSize(); - } - - @Override - public void set(Value val) { - array.setSize((RValue) val); - } - - } - - /** Value inside a array filled expression. */ - public static class ArrayFilledSize extends ProgramValue { - private final ArrayFilled array; - - ArrayFilledSize(ArrayFilled array) { - this.array = array; - } - - @Override - public Value get() { - return array.getSize(); - } - - @Override - public void set(Value val) { - array.setSize((RValue) val); - } - - } - - /** Value inside an intermediate LValue. */ - public static class LValueIntermediateVariable extends ProgramValue { - private final LvalueIntermediate intermediate; - - LValueIntermediateVariable(LvalueIntermediate intermediate) { - this.intermediate = intermediate; - } - - @Override - public Value get() { - return intermediate.getVariable(); - } - - @Override - public void set(Value val) { - intermediate.setVariable((VariableRef) val); - } - - } - - /** Value inside a constant array filled expression. */ - public static class ConstantArrayFilledSize extends ProgramValue { - private final ConstantArrayFilled array; - - ConstantArrayFilledSize(ConstantArrayFilled array) { - this.array = array; - } - - @Override - public Value get() { - return array.getSize(); - } - - @Override - public void set(Value val) { - array.setSize((ConstantValue) val); - } - - } - - /** Value inside a constant unary expression. */ - public static class ConstantUnaryValue extends ProgramValue { - private final ConstantUnary unary; - - ConstantUnaryValue(ConstantUnary unary) { - this.unary = unary; - } - - @Override - public Value get() { - return unary.getOperand(); - } - - @Override - public void set(Value val) { - unary.setOperand((ConstantValue) val); - } - - } - - /** Left value inside a constant binary expression. */ - public static class ConstantBinaryLeft extends ProgramValue { - private final ConstantBinary binary; - - ConstantBinaryLeft(ConstantBinary binary) { - this.binary = binary; - } - - @Override - public Value get() { - return binary.getLeft(); - } - - @Override - public void set(Value val) { - binary.setLeft((ConstantValue) val); - } - - } - - /** Right value inside a constant binary expression. */ - public static class ConstantBinaryRight extends ProgramValue { - private final ConstantBinary binary; - - ConstantBinaryRight(ConstantBinary range) { - this.binary = range; - } - - @Override - public Value get() { - return binary.getRight(); - } - - @Override - public void set(Value val) { - binary.setRight((ConstantValue) val); - } - - } - - /** - * First value inside a ranged comparison value. - */ - public static class RangeFirst extends ProgramValue { - private final RangeValue range; - - RangeFirst(RangeValue range) { - this.range = range; - } - - @Override - public Value get() { - return range.getRangeFirst(); - } - - @Override - public void set(Value val) { - range.setRangeFirst((RValue) val); - } - - } - - /** - * Last value inside inside a ranged comparison value. - */ - public static class RangeLast extends ProgramValue { - private final RangeValue range; - - RangeLast(RangeValue range) { - this.range = range; - } - - @Override - public Value get() { - return range.getRangeLast(); - } - - @Override - public void set(Value val) { - range.setRangeLast((RValue) val); - } - - } - - /** A variable/constant referenced inside inline ASM. */ - public static class AsmReferenced extends ProgramValue { - private StatementAsm statementAsm; - private String label; - - public AsmReferenced(StatementAsm statementAsm, String label) { - this.statementAsm = statementAsm; - this.label = label; - } - - @Override - public Value get() { - return statementAsm.getReferenced().get(label); - } - - @Override - public void set(Value value) { - statementAsm.getReferenced().put(label, (SymbolVariableRef) value); - } - } - - /** Location inside inline kickasm code. */ - public static class KickAsmLocation extends ProgramValue { - - private StatementKickAsm statementKickAsm; - - KickAsmLocation(StatementKickAsm statementKickAsm) { - super(); - this.statementKickAsm = statementKickAsm; - } - - @Override - public Value get() { - return statementKickAsm.getLocation(); - } - - @Override - public void set(Value value) { - statementKickAsm.setLocation((RValue) value); - } - - } - - /** Bytes inside inline kickasm code. */ - public static class KickAsmBytes extends ProgramValue { - - private StatementKickAsm statementKickAsm; - - KickAsmBytes(StatementKickAsm statementKickAsm) { - super(); - this.statementKickAsm = statementKickAsm; - } - - @Override - public Value get() { - return statementKickAsm.getBytes(); - } - - @Override - public void set(Value value) { - statementKickAsm.setBytes((RValue) value); - } - - } - - /** Cycles inside inline kickasm code. */ - public static class KickAsmCycles extends ProgramValue { - - private StatementKickAsm statementKickAsm; - - KickAsmCycles(StatementKickAsm statementKickAsm) { - super(); - this.statementKickAsm = statementKickAsm; - } - - @Override - public Value get() { - return statementKickAsm.getCycles(); - } - - @Override - public void set(Value value) { - statementKickAsm.setCycles((RValue) value); - } - - } - - /** - * LValue as part of an assignment statement (or a call). - */ - public static class LValue extends ProgramValue { - private final StatementLValue statement; - - public LValue(StatementLValue statement) { - this.statement = statement; - } - - @Override - public Value get() { - return statement.getlValue(); - } - - @Override - public void set(Value value) { - statement.setlValue((dk.camelot64.kickc.model.values.LValue) value); - } - - } - - /** - * Pointer inside a pointer dererence value. - */ - public static class Pointer extends ProgramValue { - private final PointerDereference pointer; - - Pointer(PointerDereference pointer) { - this.pointer = pointer; - } - - @Override - public Value get() { - return pointer.getPointer(); - } - - @Override - public void set(Value val) { - pointer.setPointer((RValue) val); - } - - } - - /** - * Value inside a noop cast. - */ - public static class CastValue extends ProgramValue { - private final dk.camelot64.kickc.model.values.CastValue castValue; - - - public CastValue(dk.camelot64.kickc.model.values.CastValue castValue) { - this.castValue = castValue; - } - - @Override - public Value get() { - return castValue.getValue(); - } - - @Override - public void set(Value val) { - castValue.setValue((RValue) val); - } - - } - - /** - * Value inside a constant noop cast. - */ - public static class ConstantCastValue extends ProgramValue { - private final dk.camelot64.kickc.model.values.ConstantCastValue castValue; - - - ConstantCastValue(dk.camelot64.kickc.model.values.ConstantCastValue castValue) { - this.castValue = castValue; - } - - @Override - public Value get() { - return castValue.getValue(); - } - - @Override - public void set(Value val) { - castValue.setValue((ConstantValue) val); - } - - } - - /** - * Pointer inside a variable pointer. - */ - public static class ConstantSymbolPointerTo extends ProgramValue { - private final ConstantSymbolPointer varPointer; - - - ConstantSymbolPointerTo(ConstantSymbolPointer varPointer) { - this.varPointer = varPointer; - } - - @Override - public Value get() { - return (RValue) varPointer.getToSymbol(); - } - - @Override - public void set(Value val) { - varPointer.setToSymbol((VariableRef) val); - } - - } - - public static class ConstantArrayElement extends ProgramValue { - private final ConstantArrayList arrayList; - private final int idx; - - ConstantArrayElement(ConstantArrayList arrayList, int idx) { - this.arrayList = arrayList; - this.idx = idx; - } - - @Override - public Value get() { - return arrayList.getElements().get(idx); - } - - @Override - public void set(Value value) { - arrayList.getElements().set(idx, (ConstantValue) value); - } - } - - public static class ListElement extends ProgramValue { - private ValueList list; - private int idx; - - ListElement(ValueList list, int idx) { - this.list = list; - this.idx = idx; - } - - @Override - public Value get() { - return list.getList().get(idx); - } - - @Override - public void set(Value value) { - list.getList().set(idx, (RValue) value); - } - - } - - /** - * Pointer index inside a indexed pointer dererence value. - */ - public static class PointerIndex extends ProgramValue { - private final PointerDereferenceIndexed pointer; - - PointerIndex(PointerDereferenceIndexed pointer) { - this.pointer = pointer; - } - - @Override - public Value get() { - return pointer.getIndex(); - } - - @Override - public void set(Value val) { - pointer.setIndex((RValue) val); - } - - } - - public static class RValue1 extends ProgramValue { + class RValue1 implements ProgramValue { private final StatementAssignment statement; public RValue1(StatementAssignment statement) { @@ -504,7 +38,7 @@ public abstract class ProgramValue { } } - public static class RValue2 extends ProgramValue { + class RValue2 implements ProgramValue { private final StatementAssignment statement; public RValue2(StatementAssignment statement) { @@ -522,7 +56,7 @@ public abstract class ProgramValue { } } - public static class CallParameter extends ProgramValue { + class CallParameter implements ProgramValue { private final StatementCall call; private final int i; @@ -542,7 +76,7 @@ public abstract class ProgramValue { } } - public static class CallPointerProcedure extends ProgramValue { + class CallPointerProcedure implements ProgramValue { private final StatementCallPointer call; CallPointerProcedure(StatementCallPointer call) { @@ -560,7 +94,7 @@ public abstract class ProgramValue { } } - public static class CallPointerParameter extends ProgramValue { + class CallPointerParameter implements ProgramValue { private final StatementCallPointer call; private final int i; @@ -580,10 +114,10 @@ public abstract class ProgramValue { } } - public static class CondRValue1 extends ProgramValue { + class CondRValue1 implements ProgramValue { private final StatementConditionalJump statement; - public CondRValue1(StatementConditionalJump statement) { + CondRValue1(StatementConditionalJump statement) { this.statement = statement; } @@ -598,10 +132,10 @@ public abstract class ProgramValue { } } - public static class CondRValue2 extends ProgramValue { + class CondRValue2 implements ProgramValue { private final StatementConditionalJump statement; - public CondRValue2(StatementConditionalJump statement) { + CondRValue2(StatementConditionalJump statement) { this.statement = statement; } @@ -616,10 +150,10 @@ public abstract class ProgramValue { } } - public static class CondLabel extends ProgramValue { + class CondLabel implements ProgramValue { private final StatementConditionalJump statement; - public CondLabel(StatementConditionalJump statement) { + CondLabel(StatementConditionalJump statement) { this.statement = statement; } @@ -634,7 +168,7 @@ public abstract class ProgramValue { } } - public static class Return extends ProgramValue { + class Return implements ProgramValue { private final StatementReturn statement; public Return(StatementReturn statement) { @@ -652,7 +186,7 @@ public abstract class ProgramValue { } } - public static class PhiValue extends ProgramValue { + class PhiValue implements ProgramValue { private final StatementPhiBlock.PhiVariable phiVariable; private final int i; @@ -672,7 +206,7 @@ public abstract class ProgramValue { } } - public static class PhiValuePredecessor extends ProgramValue { + class PhiValuePredecessor implements ProgramValue { private final StatementPhiBlock.PhiVariable phiVariable; private final int i; @@ -695,7 +229,7 @@ public abstract class ProgramValue { /** * LValue as part of an assignment statement (or a call). */ - public static class PhiVariable extends ProgramValue { + class PhiVariable implements ProgramValue { private final StatementPhiBlock.PhiVariable phiVariable; public PhiVariable(StatementPhiBlock.PhiVariable phiVariable) { @@ -715,7 +249,7 @@ public abstract class ProgramValue { } /** A generic Value. */ - public static class GenericValue extends ProgramValue { + class GenericValue implements ProgramValue { private RValue rValue; public GenericValue(RValue rValue) { @@ -734,11 +268,11 @@ public abstract class ProgramValue { } /** A variable used by inline kickasm. */ - public static class KickAsmUses extends ProgramValue { + class KickAsmUses implements ProgramValue { private StatementKickAsm statementKickAsm; private int idx; - public KickAsmUses(StatementKickAsm statementKickAsm, int idx) { + KickAsmUses(StatementKickAsm statementKickAsm, int idx) { this.statementKickAsm = statementKickAsm; this.idx = idx; } @@ -756,7 +290,7 @@ public abstract class ProgramValue { } - public static class BlockLabel extends ProgramValue { + class BlockLabel implements ProgramValue { private final ControlFlowBlock block; @@ -776,7 +310,7 @@ public abstract class ProgramValue { } - public static class BlockDefaultSuccessor extends ProgramValue { + class BlockDefaultSuccessor implements ProgramValue { private final ControlFlowBlock block; @@ -796,7 +330,7 @@ public abstract class ProgramValue { } - public static class BlockConditionalSuccessor extends ProgramValue { + class BlockConditionalSuccessor implements ProgramValue { private final ControlFlowBlock block; @@ -816,7 +350,7 @@ public abstract class ProgramValue { } - public static class BlockCallSuccessor extends ProgramValue { + class BlockCallSuccessor implements ProgramValue { private final ControlFlowBlock block; @@ -836,4 +370,489 @@ public abstract class ProgramValue { } + /** Value inside a array filled expression. */ + class ProgramValueArrayFilledSize implements ProgramValue { + private final ArrayFilled array; + + ProgramValueArrayFilledSize(ArrayFilled array) { + this.array = array; + } + + @Override + public Value get() { + return array.getSize(); + } + + @Override + public void set(Value val) { + array.setSize((RValue) val); + } + + } + + /** A variable/constant referenced inside inline ASM. */ + class ProgramValueAsmReferenced implements ProgramValue { + private StatementAsm statementAsm; + private String label; + + ProgramValueAsmReferenced(StatementAsm statementAsm, String label) { + this.statementAsm = statementAsm; + this.label = label; + } + + @Override + public Value get() { + return statementAsm.getReferenced().get(label); + } + + @Override + public void set(Value value) { + statementAsm.getReferenced().put(label, (SymbolVariableRef) value); + } + } + + /** + * Value inside a noop cast. + */ + class ProgramValueCastValue implements ProgramValue { + private final CastValue castValue; + + + public ProgramValueCastValue(CastValue castValue) { + this.castValue = castValue; + } + + @Override + public Value get() { + return castValue.getValue(); + } + + @Override + public void set(Value val) { + castValue.setValue((RValue) val); + } + + } + + class ProgramValueConstantArrayElement implements ProgramValue { + private final ConstantArrayList arrayList; + private final int idx; + + ProgramValueConstantArrayElement(ConstantArrayList arrayList, int idx) { + this.arrayList = arrayList; + this.idx = idx; + } + + @Override + public Value get() { + return arrayList.getElements().get(idx); + } + + @Override + public void set(Value value) { + arrayList.getElements().set(idx, (ConstantValue) value); + } + } + + /** Value inside a constant array filled expression. */ + class ProgramValueConstantArrayFilledSize implements ProgramValue { + private final ConstantArrayFilled array; + + ProgramValueConstantArrayFilledSize(ConstantArrayFilled array) { + this.array = array; + } + + @Override + public Value get() { + return array.getSize(); + } + + @Override + public void set(Value val) { + array.setSize((ConstantValue) val); + } + + } + + /** Left value inside a constant binary expression. */ + class ProgramValueConstantBinaryLeft implements ProgramValue { + private final ConstantBinary binary; + + ProgramValueConstantBinaryLeft(ConstantBinary binary) { + this.binary = binary; + } + + @Override + public Value get() { + return binary.getLeft(); + } + + @Override + public void set(Value val) { + binary.setLeft((ConstantValue) val); + } + + } + + /** Right value inside a constant binary expression. */ + class ProgramValueConstantBinaryRight implements ProgramValue { + private final ConstantBinary binary; + + ProgramValueConstantBinaryRight(ConstantBinary range) { + this.binary = range; + } + + @Override + public Value get() { + return binary.getRight(); + } + + @Override + public void set(Value val) { + binary.setRight((ConstantValue) val); + } + + } + + /** + * Value inside a constant noop cast. + */ + class ProgramValueConstantCastValue implements ProgramValue { + private final ConstantCastValue castValue; + + + ProgramValueConstantCastValue(ConstantCastValue castValue) { + this.castValue = castValue; + } + + @Override + public Value get() { + return castValue.getValue(); + } + + @Override + public void set(Value val) { + castValue.setValue((ConstantValue) val); + } + + } + + /** + * Pointer inside a variable pointer. + */ + class ProgramValueConstantSymbolPointerTo implements ProgramValue { + private final ConstantSymbolPointer varPointer; + + + ProgramValueConstantSymbolPointerTo(ConstantSymbolPointer varPointer) { + this.varPointer = varPointer; + } + + @Override + public Value get() { + return varPointer.getToSymbol(); + } + + @Override + public void set(Value val) { + varPointer.setToSymbol((VariableRef) val); + } + + } + + /** Value inside a constant unary expression. */ + class ProgramValueConstantUnaryValue implements ProgramValue { + private final ConstantUnary unary; + + ProgramValueConstantUnaryValue(ConstantUnary unary) { + this.unary = unary; + } + + @Override + public Value get() { + return unary.getOperand(); + } + + @Override + public void set(Value val) { + unary.setOperand((ConstantValue) val); + } + + } + + class ProgramValueConstantVar implements ProgramValue { + private final ConstantVar constantVar; + + ProgramValueConstantVar(ConstantVar constantVar) { + this.constantVar = constantVar; + } + + @Override + public Value get() { + return constantVar.getValue(); + } + + @Override + public void set(Value val) { + constantVar.setValue((ConstantValue) val); + } + + } + + /** Bytes inside inline kickasm code. */ + class ProgramValueKickAsmBytes implements ProgramValue { + + private StatementKickAsm statementKickAsm; + + ProgramValueKickAsmBytes(StatementKickAsm statementKickAsm) { + this.statementKickAsm = statementKickAsm; + } + + @Override + public Value get() { + return statementKickAsm.getBytes(); + } + + @Override + public void set(Value value) { + statementKickAsm.setBytes((RValue) value); + } + + } + + /** Cycles inside inline kickasm code. */ + class ProgramValueKickAsmCycles implements ProgramValue { + + private StatementKickAsm statementKickAsm; + + ProgramValueKickAsmCycles(StatementKickAsm statementKickAsm) { + this.statementKickAsm = statementKickAsm; + } + + @Override + public Value get() { + return statementKickAsm.getCycles(); + } + + @Override + public void set(Value value) { + statementKickAsm.setCycles((RValue) value); + } + + } + + /** Location inside inline kickasm code. */ + class ProgramValueKickAsmLocation implements ProgramValue { + + private StatementKickAsm statementKickAsm; + + ProgramValueKickAsmLocation(StatementKickAsm statementKickAsm) { + super(); + this.statementKickAsm = statementKickAsm; + } + + @Override + public Value get() { + return statementKickAsm.getLocation(); + } + + @Override + public void set(Value value) { + statementKickAsm.setLocation((RValue) value); + } + + } + + class ProgramValueListElement implements ProgramValue { + private ValueList list; + private int idx; + + ProgramValueListElement(ValueList list, int idx) { + this.list = list; + this.idx = idx; + } + + @Override + public Value get() { + return list.getList().get(idx); + } + + @Override + public void set(Value value) { + list.getList().set(idx, (RValue) value); + } + + } + + /** + * LValue as part of an assignment statement (or a call). + */ + class ProgramValueLValue implements ProgramValue { + private final StatementLValue statement; + + public ProgramValueLValue(StatementLValue statement) { + this.statement = statement; + } + + @Override + public Value get() { + return statement.getlValue(); + } + + @Override + public void set(Value value) { + statement.setlValue((LValue) value); + } + + } + + /** Value inside an intermediate LValue. */ + class ProgramValueLValueIntermediateVariable implements ProgramValue { + private final LvalueIntermediate intermediate; + + ProgramValueLValueIntermediateVariable(LvalueIntermediate intermediate) { + this.intermediate = intermediate; + } + + @Override + public Value get() { + return intermediate.getVariable(); + } + + @Override + public void set(Value val) { + intermediate.setVariable((VariableRef) val); + } + + } + + /** + * Pointer inside a pointer dererence value. + */ + class ProgramValuePointer implements ProgramValue { + private final PointerDereference pointer; + + ProgramValuePointer(PointerDereference pointer) { + this.pointer = pointer; + } + + @Override + public Value get() { + return pointer.getPointer(); + } + + @Override + public void set(Value val) { + pointer.setPointer((RValue) val); + } + + } + + /** + * Struct expression inside a struct member reference. + */ + class ProgramValueStruct implements ProgramValue { + private final StructMemberRef structMemberRef; + + public ProgramValueStruct(StructMemberRef structMemberRef) { + this.structMemberRef = structMemberRef; + } + + @Override + public Value get() { + return structMemberRef.getStruct(); + } + + @Override + public void set(Value val) { + structMemberRef.setStruct((RValue) val); + } + + } + + /** + * Pointer index inside a indexed pointer dererence value. + */ + class ProgramValuePointerIndex implements ProgramValue { + private final PointerDereferenceIndexed pointer; + + ProgramValuePointerIndex(PointerDereferenceIndexed pointer) { + this.pointer = pointer; + } + + @Override + public Value get() { + return pointer.getIndex(); + } + + @Override + public void set(Value val) { + pointer.setIndex((RValue) val); + } + + } + + /** + * First value inside a ranged comparison value. + */ + class ProgramValueRangeFirst implements ProgramValue { + private final RangeValue range; + + ProgramValueRangeFirst(RangeValue range) { + this.range = range; + } + + @Override + public Value get() { + return range.getRangeFirst(); + } + + @Override + public void set(Value val) { + range.setRangeFirst((RValue) val); + } + + } + + /** + * Last value inside inside a ranged comparison value. + */ + class ProgramValueRangeLast implements ProgramValue { + private final RangeValue range; + + ProgramValueRangeLast(RangeValue range) { + this.range = range; + } + + @Override + public Value get() { + return range.getRangeLast(); + } + + @Override + public void set(Value val) { + range.setRangeLast((RValue) val); + } + + } + + /** Size inside a fixed size array. */ + class ProgramValueTypeArraySize implements ProgramValue { + private final SymbolTypeArray array; + + ProgramValueTypeArraySize(SymbolTypeArray array) { + this.array = array; + } + + @Override + public Value get() { + return array.getSize(); + } + + @Override + public void set(Value val) { + array.setSize((RValue) val); + } + + } } diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java index 7ca0243de..a1984c1a8 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java @@ -50,10 +50,10 @@ public class ProgramValueIterator { */ public static void execute(SymbolVariable symbolVariable, ProgramValueHandler programValueHandler) { if(symbolVariable.getType() instanceof SymbolTypeArray) { - execute(new ProgramValue.TypeArraySize((SymbolTypeArray) symbolVariable.getType()), programValueHandler, null, null, null); + execute(new ProgramValue.ProgramValueTypeArraySize((SymbolTypeArray) symbolVariable.getType()), programValueHandler, null, null, null); } if(symbolVariable instanceof ConstantVar) { - execute(new ProgramValue.ConstantVariableValue((ConstantVar) symbolVariable), programValueHandler, null, null, null); + execute(new ProgramValue.ProgramValueConstantVar((ConstantVar) symbolVariable), programValueHandler, null, null, null); } } @@ -98,7 +98,7 @@ public class ProgramValueIterator { // The sequence RValue1, RValue2, LValue is important - as it is essential for {@link dk.camelot64.kickc.passes.Pass1GenerateSingleStaticAssignmentForm} to create the correct SSA execute(new ProgramValue.RValue1((StatementAssignment) statement), handler, statement, statementsIt, block); execute(new ProgramValue.RValue2((StatementAssignment) statement), handler, statement, statementsIt, block); - execute(new ProgramValue.LValue((StatementLValue) statement), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueLValue((StatementLValue) statement), handler, statement, statementsIt, block); } else if(statement instanceof StatementCall) { StatementCall call = (StatementCall) statement; if(call.getParameters() != null) { @@ -107,7 +107,7 @@ public class ProgramValueIterator { execute(new ProgramValue.CallParameter(call, i), handler, statement, statementsIt, block); } } - execute(new ProgramValue.LValue((StatementLValue) statement), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueLValue((StatementLValue) statement), handler, statement, statementsIt, block); } else if(statement instanceof StatementCallPointer) { StatementCallPointer call = (StatementCallPointer) statement; execute(new ProgramValue.CallPointerProcedure((StatementCallPointer) statement), handler, statement, statementsIt, block); @@ -117,7 +117,7 @@ public class ProgramValueIterator { execute(new ProgramValue.CallPointerParameter(call, i), handler, statement, statementsIt, block); } } - execute(new ProgramValue.LValue((StatementLValue) statement), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueLValue((StatementLValue) statement), handler, statement, statementsIt, block); } else if(statement instanceof StatementConditionalJump) { execute(new ProgramValue.CondRValue1((StatementConditionalJump) statement), handler, statement, statementsIt, block); execute(new ProgramValue.CondRValue2((StatementConditionalJump) statement), handler, statement, statementsIt, block); @@ -137,15 +137,15 @@ public class ProgramValueIterator { StatementKickAsm statementKickAsm = (StatementKickAsm) statement; RValue location = statementKickAsm.getLocation(); if(location!=null) { - execute(new ProgramValue.KickAsmLocation(statementKickAsm), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueKickAsmLocation(statementKickAsm), handler, statement, statementsIt, block); } RValue bytes = statementKickAsm.getLocation(); if(bytes!=null) { - execute(new ProgramValue.KickAsmBytes(statementKickAsm), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueKickAsmBytes(statementKickAsm), handler, statement, statementsIt, block); } RValue cycles = statementKickAsm.getLocation(); if(cycles!=null) { - execute(new ProgramValue.KickAsmCycles(statementKickAsm), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueKickAsmCycles(statementKickAsm), handler, statement, statementsIt, block); } List uses = statementKickAsm.getUses(); for(int i = 0; i < uses.size(); i++) { @@ -155,7 +155,7 @@ public class ProgramValueIterator { StatementAsm statementAsm = (StatementAsm) statement; Map referenced = statementAsm.getReferenced(); for(String label : referenced.keySet()) { - execute(new ProgramValue.AsmReferenced(statementAsm, label), handler, statement, statementsIt, block); + execute(new ProgramValue.ProgramValueAsmReferenced(statementAsm, label), handler, statement, statementsIt, block); } } } @@ -182,47 +182,50 @@ public class ProgramValueIterator { private static Collection getSubValues(Value value) { ArrayList subValues = new ArrayList<>(); if(value instanceof PointerDereferenceIndexed) { - subValues.add(new ProgramValue.Pointer((PointerDereference) value)); - subValues.add(new ProgramValue.PointerIndex((PointerDereferenceIndexed) value)); + subValues.add(new ProgramValue.ProgramValuePointer((PointerDereference) value)); + subValues.add(new ProgramValue.ProgramValuePointerIndex((PointerDereferenceIndexed) value)); } else if(value instanceof PointerDereferenceSimple) { - subValues.add(new ProgramValue.Pointer((PointerDereference) value)); + subValues.add(new ProgramValue.ProgramValuePointer((PointerDereference) value)); + } else if(value instanceof StructMemberRef) { + subValues.add(new ProgramValue.ProgramValueStruct((StructMemberRef) value)); } else if(value instanceof ValueList) { ValueList valueList = (ValueList) value; int size = valueList.getList().size(); for(int i = 0; i < size; i++) { - subValues.add(new ProgramValue.ListElement(valueList, i)); + subValues.add(new ProgramValue.ProgramValueListElement(valueList, i)); } } else if(value instanceof ConstantArrayList) { ConstantArrayList constantArrayList = (ConstantArrayList) value; int size = constantArrayList.getElements().size(); for(int i = 0; i < size; i++) { - subValues.add(new ProgramValue.ConstantArrayElement(constantArrayList, i)); + subValues.add(new ProgramValue.ProgramValueConstantArrayElement(constantArrayList, i)); } } else if(value instanceof CastValue) { - subValues.add(new ProgramValue.CastValue((CastValue) value)); + subValues.add(new ProgramValue.ProgramValueCastValue((CastValue) value)); } else if(value instanceof ConstantCastValue) { - subValues.add(new ProgramValue.ConstantCastValue((ConstantCastValue) value)); + subValues.add(new ProgramValue.ProgramValueConstantCastValue((ConstantCastValue) value)); } else if(value instanceof ConstantSymbolPointer) { - subValues.add(new ProgramValue.ConstantSymbolPointerTo((ConstantSymbolPointer) value)); + subValues.add(new ProgramValue.ProgramValueConstantSymbolPointerTo((ConstantSymbolPointer) value)); } else if(value instanceof RangeValue) { - subValues.add(new ProgramValue.RangeFirst((RangeValue) value)); - subValues.add(new ProgramValue.RangeLast((RangeValue) value)); + subValues.add(new ProgramValue.ProgramValueRangeFirst((RangeValue) value)); + subValues.add(new ProgramValue.ProgramValueRangeLast((RangeValue) value)); } else if(value instanceof ConstantBinary) { - subValues.add(new ProgramValue.ConstantBinaryLeft((ConstantBinary) value)); - subValues.add(new ProgramValue.ConstantBinaryRight((ConstantBinary) value)); + subValues.add(new ProgramValue.ProgramValueConstantBinaryLeft((ConstantBinary) value)); + subValues.add(new ProgramValue.ProgramValueConstantBinaryRight((ConstantBinary) value)); } else if(value instanceof ConstantUnary) { - subValues.add(new ProgramValue.ConstantUnaryValue((ConstantUnary) value)); + subValues.add(new ProgramValue.ProgramValueConstantUnaryValue((ConstantUnary) value)); } else if(value instanceof ArrayFilled) { - subValues.add(new ProgramValue.ArrayFilledSize((ArrayFilled) value)); + subValues.add(new ProgramValue.ProgramValueArrayFilledSize((ArrayFilled) value)); } else if(value instanceof ConstantArrayFilled) { - subValues.add(new ProgramValue.ConstantArrayFilledSize((ConstantArrayFilled) value)); + subValues.add(new ProgramValue.ProgramValueConstantArrayFilledSize((ConstantArrayFilled) value)); } else if(value instanceof LvalueIntermediate) { - subValues.add(new ProgramValue.LValueIntermediateVariable((LvalueIntermediate) value)); + subValues.add(new ProgramValue.ProgramValueLValueIntermediateVariable((LvalueIntermediate) value)); } else if(value == null || value instanceof VariableRef || value instanceof ProcedureRef || value instanceof ConstantLiteral || value instanceof ConstantRef || + value instanceof StructZero || value instanceof LabelRef ) { // No sub values diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorAddressOf.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorAddressOf.java index 5b3c998dd..f0da75fec 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorAddressOf.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorAddressOf.java @@ -4,7 +4,6 @@ import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantLiteral; /** Unary Address-of Operator (&p) */ @@ -20,7 +19,7 @@ public class OperatorAddressOf extends OperatorUnary { } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return new SymbolTypePointer(operandType); } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorAssignment.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorAssignment.java new file mode 100644 index 000000000..9e84e1b3d --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorAssignment.java @@ -0,0 +1,25 @@ +package dk.camelot64.kickc.model.operators; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.values.ConstantLiteral; + +/** Binary assignment operator ( x = y ) */ +public class OperatorAssignment extends OperatorBinary { + + public OperatorAssignment(int precedence) { + super("=", "_assign_", precedence); + } + + @Override + public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) { + throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right); + } + + @Override + public SymbolType inferType(SymbolType left, SymbolType right) { + return left; + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java index 0ae783a25..9a6a79d30 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBinary.java @@ -1,7 +1,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantLiteral; /** A binary expression operator */ @@ -25,6 +24,6 @@ public abstract class OperatorBinary extends Operator { * @param right The type of the right operand * @return The type resulting from applying the operator to the operands */ - public abstract SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right); + public abstract SymbolType inferType(SymbolType left, SymbolType right); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java index af0323d3e..84af74049 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorBitwiseAnd.java @@ -1,10 +1,7 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; +import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -24,7 +21,7 @@ public class OperatorBitwiseAnd extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple type1, SymbolTypeSimple type2) { + public SymbolType inferType(SymbolType type1, SymbolType type2) { // Handle pointers as words if(type1 instanceof SymbolTypePointer) { type1 = SymbolType.WORD; @@ -32,16 +29,12 @@ public class OperatorBitwiseAnd extends OperatorBinary { if(type2 instanceof SymbolTypePointer) { type2 = SymbolType.WORD; } - // Find smallest bitwise type - if(type1 instanceof SymbolTypeInteger && type2 instanceof SymbolTypeInteger) { - - for(SymbolTypeInteger candidate : SymbolType.getIntegerTypes()) { - boolean match1 = ((SymbolTypeInteger) type1).getBits() <= candidate.getBits(); - boolean match2 = ((SymbolTypeInteger) type2).getBits() <= candidate.getBits(); - if(!candidate.isSigned() && (match1 || match2)) { - return candidate; - } - } + // Handle numeric types + if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) { + if(type1.getSizeBytes()>8); - } else if(SymbolType.isDWord(operandInt.getType()) || SymbolType.isSDWord(operandInt.getType())) { + } else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) { return new ConstantInteger(operandInt.getInteger()>>16); + } else if(SymbolType.BYTE.equals(operandInt.getType()) || SymbolType.SBYTE.equals(operandInt.getType())) { + return new ConstantInteger(0L, SymbolType.BYTE); + } else if(SymbolType.NUMBER.equals(operandInt.getType())) { + throw new ConstantNotLiteral("Operand not resolved "+operand); } } else if(operand instanceof ConstantPointer) { return new ConstantInteger(((ConstantPointer) operand).getLocation()>>8); @@ -36,13 +39,21 @@ public class OperatorGetHigh extends OperatorUnary { } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { - if(operandType instanceof SymbolTypePointer || SymbolType.isWord(operandType) || SymbolType.isSWord(operandType)) { + public SymbolType inferType(SymbolType operandType) { + if(operandType instanceof SymbolTypePointer || SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType)) { return SymbolType.BYTE; - } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { + } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { return SymbolType.WORD; + } else if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { + return SymbolType.BYTE; } else if(SymbolType.STRING.equals(operandType)) { return SymbolType.BYTE; + } else if(SymbolType.NUMBER.equals(operandType)) { + return SymbolType.NUMBER; + } else if(SymbolType.UNUMBER.equals(operandType)) { + return SymbolType.UNUMBER; + } else if(SymbolType.SNUMBER.equals(operandType)) { + return SymbolType.UNUMBER; } throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java index bd8d030f3..e162f4d0d 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGetLow.java @@ -5,7 +5,6 @@ import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantPointer; @@ -22,27 +21,39 @@ public class OperatorGetLow extends OperatorUnary { public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) { if(operand instanceof ConstantInteger) { ConstantInteger operandInt = (ConstantInteger) operand; - if(SymbolType.isWord(operandInt.getType()) || SymbolType.isSWord(operandInt.getType())) { + if(SymbolType.WORD.equals(operandInt.getType()) || SymbolType.SWORD.equals(operandInt.getType())) { return new ConstantInteger(operandInt.getInteger()&0xff); - } else if(SymbolType.isDWord(operandInt.getType()) || SymbolType.isSDWord(operandInt.getType())) { + } else if(SymbolType.DWORD.equals(operandInt.getType()) || SymbolType.SDWORD.equals(operandInt.getType())) { return new ConstantInteger(operandInt.getInteger()&0xffff); + } else if(SymbolType.BYTE.equals(operandInt.getType()) || SymbolType.SBYTE.equals(operandInt.getType())) { + return operandInt; + } else if(SymbolType.NUMBER.equals(operandInt.getType())) { + throw new ConstantNotLiteral("Operand not resolved "+operand); } } else if(operand instanceof ConstantPointer) { return new ConstantInteger(((ConstantPointer) operand).getLocation()&0xff); } else if(operand instanceof ConstantString) { throw new ConstantNotLiteral("address of string is not literal"); } - throw new CompileError("Calculation not implemented " + getOperator() + " " + operand ); + throw new ConstantNotLiteral("Calculation not implemented " + getOperator() + " " + operand ); } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { - if(operandType instanceof SymbolTypePointer || SymbolType.isWord(operandType) || SymbolType.isSWord(operandType)) { + public SymbolType inferType(SymbolType operandType) { + if(operandType instanceof SymbolTypePointer || SymbolType.WORD.equals(operandType) || SymbolType.SWORD.equals(operandType)) { return SymbolType.BYTE; - } else if(SymbolType.isDWord(operandType) || SymbolType.isSDWord(operandType)) { + } else if(SymbolType.DWORD.equals(operandType) || SymbolType.SDWORD.equals(operandType)) { return SymbolType.WORD; + } else if(SymbolType.BYTE.equals(operandType) || SymbolType.SBYTE.equals(operandType)) { + return SymbolType.BYTE; } else if(SymbolType.STRING.equals(operandType)) { return SymbolType.BYTE; + } else if(SymbolType.NUMBER.equals(operandType)) { + return SymbolType.NUMBER; + } else if(SymbolType.UNUMBER.equals(operandType)) { + return SymbolType.UNUMBER; + } else if(SymbolType.SNUMBER.equals(operandType)) { + return SymbolType.UNUMBER; } throw new CompileError("Type inference not implemented "+getOperator()+" "+operandType); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThan.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThan.java index fcf503c84..f1614c0be 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThan.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThan.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorGreaterThan extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThanEqual.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThanEqual.java index b195f1e40..2ce48f329 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThanEqual.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorGreaterThanEqual.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorGreaterThanEqual extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorIncrement.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorIncrement.java index 70671914f..bd63496d0 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorIncrement.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorIncrement.java @@ -1,9 +1,8 @@ package dk.camelot64.kickc.model.operators; -import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantPointer; @@ -22,11 +21,11 @@ public class OperatorIncrement extends OperatorUnary { } else if(operand instanceof ConstantPointer) { return new ConstantPointer(((ConstantPointer) operand).getLocation()+1, ((ConstantPointer) operand).getElementType()); } - throw new CompileError("Calculation not implemented " + getOperator() + " " + operand ); + throw new ConstantNotLiteral("Calculation not literal " + getOperator() + " " + operand ); } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return operandType; } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThan.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThan.java index a3d0c379f..ad61da0e8 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThan.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThan.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorLessThan extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThanEqual.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThanEqual.java index af07b0378..cbf042583 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThanEqual.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLessThanEqual.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorLessThanEqual extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java index d755616a3..0088ec944 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicAnd.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -22,7 +21,7 @@ public class OperatorLogicAnd extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java index 740f1ce01..990cab0f1 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicNot.java @@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorLogicNot extends OperatorUnary { } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return operandType; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java index 5c838560a..5d5b92e68 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorLogicOr.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -22,7 +21,7 @@ public class OperatorLogicOr extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java index 3f018c9d5..50c1fb6f7 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorMinus.java @@ -1,10 +1,7 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; +import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.ConstantChar; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -32,17 +29,16 @@ public class OperatorMinus extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple type1, SymbolTypeSimple type2) { + public SymbolType inferType(SymbolType type1, SymbolType type2) { // Handle pointer types if(type1 instanceof SymbolTypePointer && SymbolType.isInteger(type2)) { return new SymbolTypePointer(((SymbolTypePointer) type1).getElementType()); } else if(type1 instanceof SymbolTypePointer && type2 instanceof SymbolTypePointer) { return SymbolType.WORD; } - // Handle numeric types through proper promotion if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) { - return SymbolType.promotedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2); + return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2); } throw new RuntimeException("Type inference case not handled " + type1 + " " + getOperator() + " " + type2); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorModulo.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorModulo.java index c26e36089..7235c3fdc 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorModulo.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorModulo.java @@ -24,10 +24,10 @@ public class OperatorModulo extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { // Handle numeric types through proper promotion if(SymbolType.isInteger(left) && SymbolType.isInteger(right)) { - return SymbolType.promotedMathType((SymbolTypeInteger) left, (SymbolTypeInteger) right); + return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) left, (SymbolTypeInteger) right); } if(left instanceof ConstantPointer && right instanceof ConstantInteger) { return ((ConstantInteger) right).getType(); diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorMultiply.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorMultiply.java index 5da795636..a32595647 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorMultiply.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorMultiply.java @@ -1,9 +1,7 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; +import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,10 +21,17 @@ public class OperatorMultiply extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { + if(left instanceof SymbolTypePointer) { + if(SymbolType.BYTE.equals(right) || SymbolType.WORD.equals(right) || SymbolType.NUMBER.equals(right)) { + return left; + } else { + throw new NoMatchingType("Cannot multiply pointer by "+right.toString()); + } + } // Handle numeric types through proper promotion if(SymbolType.isInteger(left) && SymbolType.isInteger(right)) { - return SymbolType.promotedMathType((SymbolTypeInteger) left, (SymbolTypeInteger) right); + return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) left, (SymbolTypeInteger) right); } throw new RuntimeException("Type inference case not handled " + left + " " + getOperator() + " " + right); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorNeg.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorNeg.java index ce736a9d1..2e777f4f1 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorNeg.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorNeg.java @@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorNeg extends OperatorUnary { } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return operandType; } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorNotEqual.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorNotEqual.java index 8b995c59e..7aba1389b 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorNotEqual.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorNotEqual.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -29,7 +28,7 @@ public class OperatorNotEqual extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { return SymbolType.BOOLEAN; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java index 99556aa2e..1f442721c 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPlus.java @@ -23,7 +23,7 @@ public class OperatorPlus extends OperatorBinary { return new ConstantString(((ConstantString) left).getString() + ((ConstantString) right).getString()); } else if(left instanceof ConstantString && right instanceof ConstantChar) { return new ConstantString(((ConstantString) left).getString() + ((ConstantChar) right).getChar()); - } else if(left instanceof ConstantString && right instanceof ConstantInteger && SymbolType.isByte(((ConstantInteger) right).getType())) { + } else if(left instanceof ConstantString && right instanceof ConstantInteger && SymbolType.BYTE.equals(((ConstantInteger) right).getType())) { Character character = (char) ((ConstantInteger) right).getInteger().byteValue(); return new ConstantString(((ConstantString) left).getString() + character); } else if(left instanceof ConstantPointer && right instanceof ConstantInteger) { @@ -37,54 +37,20 @@ public class OperatorPlus extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple type1, SymbolTypeSimple type2) { + public SymbolType inferType(SymbolType type1, SymbolType type2) { // Handle all non-numeric types - if(type1.equals(SymbolType.STRING) && isStringLike(type2)) { - return SymbolType.STRING; - } else if(isStringLike(type1) && type2.equals(SymbolType.STRING)) { - return SymbolType.STRING; - } else if(type1 instanceof SymbolTypeArray && type2 instanceof SymbolTypeArray) { - SymbolType elemType1 = ((SymbolTypeArray) type1).getElementType(); - SymbolType elemType2 = ((SymbolTypeArray) type2).getElementType(); - if(SymbolTypeInference.typeMatch(elemType1, elemType2)) { - return new SymbolTypeArray(elemType1); - } else if(SymbolTypeInference.typeMatch(elemType2, elemType1)) { - return new SymbolTypeArray(elemType2); - } else { - throw new RuntimeException("Type inference case not handled " + type1 + " " + getOperator() + " " + type2); - } - } else if(SymbolType.isInteger(type1) && type2 instanceof SymbolTypePointer ) { + if(SymbolType.isInteger(type1) && type2 instanceof SymbolTypePointer) { return new SymbolTypePointer(((SymbolTypePointer) type2).getElementType()); } else if(type1 instanceof SymbolTypePointer && SymbolType.isInteger(type2)) { return new SymbolTypePointer(((SymbolTypePointer) type1).getElementType()); - } else if(type1 instanceof SymbolTypePointer && type2 instanceof SymbolTypePointer) { - throw new NoMatchingType("Two pointers cannot be added."); } - // Handle numeric types through proper promotion if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) { - return SymbolType.promotedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2); + return SymbolTypeConversion.convertedMathType( (SymbolTypeInteger) type1, (SymbolTypeInteger)type2); } throw new CompileError("Type inference case not handled " + type1 + " " + getOperator() + " " + type2); } - /** - * Determines if a type is enough like a string to be added to a string to yield a new string. - * This is true for Strings, arrays of bytes and single bytes. - * - * @param type The type to check - * @return true if the type is string like - */ - private boolean isStringLike(SymbolTypeSimple type) { - if(SymbolType.STRING.equals(type)) { - return true; - } else if(SymbolType.isByte(type)) { - return true; - } else if(type instanceof SymbolTypeArray && SymbolType.isByte(((SymbolTypeArray) type).getElementType())) { - return true; - } - return false; - } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPos.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPos.java index 03acd3465..507bba6fc 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorPos.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorPos.java @@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,7 +22,7 @@ public class OperatorPos extends OperatorUnary { } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return operandType; } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java index e5218c3bd..041322a18 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetHigh.java @@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantLiteral; /** Binary SetHighByte Operator ( w hi= b ) */ @@ -19,20 +18,20 @@ public class OperatorSetHigh extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { if(left instanceof SymbolTypePointer) { return left; - } else if(SymbolType.isByte(left)) { + } else if(SymbolType.BYTE.equals(left)) { return SymbolType.WORD; - } else if(SymbolType.isSByte(left)) { + } else if(SymbolType.SBYTE.equals(left)) { return SymbolType.WORD; - } else if(SymbolType.isWord(left)) { + } else if(SymbolType.WORD.equals(left)) { return SymbolType.WORD; - } else if(SymbolType.isSWord(left)) { + } else if(SymbolType.SWORD.equals(left)) { return SymbolType.SWORD; - } else if(SymbolType.isDWord(left)) { + } else if(SymbolType.DWORD.equals(left)) { return SymbolType.DWORD; - } else if(SymbolType.isSDWord(left)) { + } else if(SymbolType.SDWORD.equals(left)) { return SymbolType.SDWORD; } throw new RuntimeException("Type inference case not handled " + left + " " + getOperator() + " " + right); diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java index 12e3d486f..180b4b5bd 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSetLow.java @@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantLiteral; /** Binary SetLowByte Operator ( w lo= b ) */ @@ -19,17 +18,17 @@ public class OperatorSetLow extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { + public SymbolType inferType(SymbolType left, SymbolType right) { if(left instanceof SymbolTypePointer) { return left; } - if(SymbolType.isWord(left)) { + if(SymbolType.WORD.equals(left)) { return SymbolType.WORD; - } else if(SymbolType.isSWord(left)) { + } else if(SymbolType.SWORD.equals(left)) { return SymbolType.SWORD; - } else if(SymbolType.isDWord(left)) { + } else if(SymbolType.DWORD.equals(left)) { return SymbolType.DWORD; - } else if(SymbolType.isSDWord(left)) { + } else if(SymbolType.SDWORD.equals(left)) { return SymbolType.SDWORD; } throw new RuntimeException("Type inference case not handled " + left + " " + getOperator() + " " + right); diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftLeft.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftLeft.java index bb14a9cd1..5d84970ef 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftLeft.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftLeft.java @@ -2,8 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; -import dk.camelot64.kickc.model.values.ConstantBool; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -23,8 +21,8 @@ public class OperatorShiftLeft extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { - return left; + public SymbolType inferType(SymbolType left, SymbolType right) { + return left; } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftRight.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftRight.java index 6b3adb2b7..352dae6d5 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftRight.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorShiftRight.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -22,8 +21,8 @@ public class OperatorShiftRight extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { - return left; + public SymbolType inferType(SymbolType left, SymbolType right) { + return left; } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java index 02d3e51e8..422f6a4c2 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorSizeOf.java @@ -3,9 +3,7 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.symbols.ConstantVar; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeMulti; import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantRef; @@ -20,16 +18,17 @@ public class OperatorSizeOf extends OperatorUnary { @Override public ConstantLiteral calculateLiteral(ConstantLiteral operand, ProgramScope scope) { SymbolType type = operand.getType(scope); - return new ConstantInteger((long)type.getSizeBytes()); + return new ConstantInteger((long) type.getSizeBytes()); } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return SymbolType.BYTE; } /** * Get the constant variable containing the size of a specific type + * * @param programScope The program scope (used for finding/adding the constant). * @param type The type to get the variable for * @return The constant variable @@ -37,10 +36,10 @@ public class OperatorSizeOf extends OperatorUnary { public static ConstantRef getSizeOfConstantVar(ProgramScope programScope, SymbolType type) { String typeConstName = getSizeofConstantName(type); ConstantVar typeSizeConstant = programScope.getConstant(typeConstName); - if(typeSizeConstant ==null) { + if(typeSizeConstant == null) { // Constant not found - create it long typeSize = type.getSizeBytes(); - typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize)); + typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize&0xff, SymbolType.BYTE)); programScope.add(typeSizeConstant); } return typeSizeConstant.getRef(); @@ -48,18 +47,15 @@ public class OperatorSizeOf extends OperatorUnary { /** * Get the name of the constant variable containing the size of a specific type + * * @param type The type to get the variable for * @return The name of the constant */ public static String getSizeofConstantName(SymbolType type) { - if(type instanceof SymbolTypeMulti) { - // Grab the first sub-type. It will be the smallest - SymbolType subType = OperatorTypeId.getSubTypeToUse((SymbolTypeMulti) type); - return getSizeofConstantName(subType); - } else if(type instanceof SymbolTypePointer) { + if(type instanceof SymbolTypePointer) { return "SIZEOF_POINTER"; } else { - return "SIZEOF_"+type.getTypeName().toUpperCase().replace(" ", "_"); + return "SIZEOF_" + type.getTypeName().toUpperCase().replace(" ", "_"); } } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java index df22fc60d..0d09c75e9 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorTypeId.java @@ -24,7 +24,7 @@ public class OperatorTypeId extends OperatorUnary { } @Override - public SymbolType inferType(SymbolTypeSimple operandType) { + public SymbolType inferType(SymbolType operandType) { return SymbolType.BYTE; } @@ -36,7 +36,7 @@ public class OperatorTypeId extends OperatorUnary { * @return The constant variable */ public static ConstantRef getTypeIdConstantVar(ProgramScope programScope, SymbolType type) { - String typeConstName = "TYPEID_"+getTypeIdConstantName(type); + String typeConstName = "TYPEID_" + getTypeIdConstantName(type); ConstantVar typeIdConstant = programScope.getConstant(typeConstName); if(typeIdConstant == null) { // Constant not found - create it @@ -54,15 +54,7 @@ public class OperatorTypeId extends OperatorUnary { * @return The name of the constant */ private static String getTypeIdConstantName(SymbolType type) { - if(type instanceof SymbolTypeMulti) { - // Grab the first sub-type. It will be the smallest - SymbolType subType = getSubTypeToUse((SymbolTypeMulti) type); - if(subType==null) { - return "VOID"; - } else { - return getTypeIdConstantName(subType); - } - } else if(type instanceof SymbolTypeProcedure) { + if(type instanceof SymbolTypeProcedure) { return "PROCEDURE"; } else if(type instanceof SymbolTypePointer) { return "POINTER_" + getTypeIdConstantName(((SymbolTypePointer) type).getElementType()); @@ -113,33 +105,9 @@ public class OperatorTypeId extends OperatorUnary { return 0x0f; } else if(type instanceof SymbolTypePointer) { return 0x10 + getTypeId(((SymbolTypePointer) type).getElementType()); - } else if(type instanceof SymbolTypeMulti) { - // Return the smallest type ID - SymbolType useType = getSubTypeToUse((SymbolTypeMulti) type); - if(useType==null) return 0; - return getTypeId(useType); } else { return 0; } } - /** - * Find the sub-type to use for typeid() - * @param type The multi type - * @return The sub-type to use - */ - public static SymbolType getSubTypeToUse(SymbolTypeMulti type) { - SymbolType useType = null; - Integer useID = null; - for(SymbolType subType : type.getTypes()) { - int subId = getTypeId(subType); - if(useType==null || subId < useID) { - useType = subType; - useID = subId; - } - } - return useType; - } - - } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorUnary.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorUnary.java index d9efd026f..2c1775de7 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorUnary.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorUnary.java @@ -2,7 +2,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantLiteral; /** A unary expression operator */ @@ -25,6 +24,6 @@ public abstract class OperatorUnary extends Operator { * @param operandType The type of the operand * @return The type resulting from applying the operator to the operand */ - public abstract SymbolType inferType(SymbolTypeSimple operandType); + public abstract SymbolType inferType(SymbolType operandType); } diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java index 1ddc3a770..01f96476c 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorWord.java @@ -3,8 +3,6 @@ package dk.camelot64.kickc.model.operators; import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.types.NoMatchingType; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeSimple; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -24,8 +22,8 @@ public class OperatorWord extends OperatorBinary { } @Override - public SymbolType inferType(SymbolTypeSimple left, SymbolTypeSimple right) { - if(SymbolType.isByte(left) && SymbolType.isByte(right)) { + public SymbolType inferType(SymbolType left, SymbolType right) { + if(SymbolType.BYTE.equals(left) && SymbolType.BYTE.equals(right)) { return SymbolType.WORD; } throw new NoMatchingType("Word constructor cannot use " + left + " " + getOperator() + " " + right); diff --git a/src/main/java/dk/camelot64/kickc/model/operators/Operators.java b/src/main/java/dk/camelot64/kickc/model/operators/Operators.java index b9470a3c8..0afad2224 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/Operators.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/Operators.java @@ -26,6 +26,8 @@ public class Operators { public static final OperatorUnary CAST_DWORD = new OperatorCastDWord(2); public static final OperatorUnary CAST_SDWORD = new OperatorCastSDWord(2); public static final OperatorUnary CAST_BOOL= new OperatorCastBool(2); + public static final OperatorUnary CAST_UNUMBER = new OperatorCastUNumber(2); + public static final OperatorUnary CAST_SNUMBER = new OperatorCastSNumber(2); public static final OperatorUnary SIZEOF = new OperatorSizeOf(2); public static final OperatorUnary TYPEID = new OperatorTypeId(2); public static final OperatorBinary MULTIPLY = new OperatorMultiply(3); @@ -48,6 +50,7 @@ public class Operators { public static final OperatorBinary BOOL_OR = new OperatorBitwiseOr(11); public static final OperatorBinary LOGIC_AND = new OperatorLogicAnd(12); public static final OperatorBinary LOGIC_OR = new OperatorLogicOr(13); + public static final OperatorBinary ASSIGNMENT = new OperatorAssignment(14); public static Operator getBinary(String op) { switch(op) { @@ -148,6 +151,10 @@ public class Operators { return CAST_DWORD; } else if(SymbolType.SDWORD.equals(castType)) { return CAST_SDWORD; + } else if(SymbolType.UNUMBER.equals(castType)) { + return CAST_UNUMBER; + } else if(SymbolType.SNUMBER.equals(castType)) { + return CAST_SNUMBER; } else if(SymbolType.BOOLEAN.equals(castType)) { return CAST_BOOL; } else if(castType instanceof SymbolTypePointer) { @@ -158,4 +165,5 @@ public class Operators { } } + } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java b/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java index dc2c9554a..e78825414 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java @@ -4,7 +4,11 @@ import dk.camelot64.kickc.model.LiveRangeEquivalenceClass; import dk.camelot64.kickc.model.LiveRangeEquivalenceClassSet; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypeProgram; +import dk.camelot64.kickc.model.types.SymbolTypeStruct; +import dk.camelot64.kickc.model.values.RValue; +import dk.camelot64.kickc.model.values.StructMemberRef; /** The program scope containing the symbols of a program */ public class ProgramScope extends Scope { @@ -19,8 +23,18 @@ public class ProgramScope extends Scope { return new SymbolTypeProgram(); } - public String getSymbolTableContents(Program program) { - return toString(program, null); + + /** + * Get the struct definition for a struct + * @param structMemberRef + * @return + */ + public StructDefinition getStructDefinition(StructMemberRef structMemberRef) { + RValue struct = structMemberRef.getStruct(); + SymbolType structType = SymbolTypeInference.inferType(this, struct); + String structTypeName = ((SymbolTypeStruct) structType).getStructTypeName(); + StructDefinition structDefinition = getStructDefinition(structTypeName); + return structDefinition; } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java index 3070e188f..d7d55166b 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java @@ -82,7 +82,7 @@ public abstract class Scope implements Symbol { } } - public Symbol add(Symbol symbol) { + public T add(T symbol) { if(symbols.get(symbol.getLocalName()) != null) { throw new CompileError("Symbol already declared " + symbol.getLocalName()); } @@ -95,16 +95,12 @@ public abstract class Scope implements Symbol { } public VariableUnversioned addVariable(String name, SymbolType type) { - VariableUnversioned symbol = new VariableUnversioned(name, this, type); - add(symbol); - return symbol; + return add(new VariableUnversioned(name, this, type)); } public VariableIntermediate addVariableIntermediate() { String name = allocateIntermediateVariableName(); - VariableIntermediate symbol = new VariableIntermediate(name, this, SymbolType.VAR); - add(symbol); - return symbol; + return add(new VariableIntermediate(name, this, SymbolType.VAR)); } /** @@ -254,16 +250,12 @@ public abstract class Scope implements Symbol { public Label addLabel(String name) { - Label symbol = new Label(name, this, false); - add(symbol); - return symbol; + return add(new Label(name, this, false)); } public Label addLabelIntermediate() { String name = "@" + intermediateLabelCount++; - Label symbol = new Label(name, this, true); - add(symbol); - return symbol; + return add(new Label(name, this, true)); } public Label getLabel(String name) { @@ -276,9 +268,7 @@ public abstract class Scope implements Symbol { public BlockScope addBlockScope() { String name = ":" + blockCount++; - BlockScope blockScope = new BlockScope(name, this); - add(blockScope); - return blockScope; + return add(new BlockScope(name, this)); } public BlockScope getBlockScope(String name) { @@ -286,13 +276,7 @@ public abstract class Scope implements Symbol { } public Procedure addProcedure(String name, SymbolType type) { - Symbol symbol = symbols.get(name); - if(symbol != null) { - throw new RuntimeException("Error! Symbol already defined " + symbol); - } - Procedure procedure = new Procedure(name, type, this); - add(procedure); - return procedure; + return add(new Procedure(name, type, this)); } public Procedure getProcedure(String name) { @@ -304,6 +288,19 @@ public abstract class Scope implements Symbol { } } + /** + * Add a struct definition. + * The name can be either defined in the program or an intermediate name. + * @param name + */ + public StructDefinition addStructDefinition(String name) { + return add(new StructDefinition(name, this)); + } + + public StructDefinition getStructDefinition(String name) { + return (StructDefinition) getSymbol(name); + } + public Scope getScope(ScopeRef scopeRef) { if(scopeRef.getFullName().equals("") && this instanceof ProgramScope) { // Special case for the outer program scope diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java b/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java new file mode 100644 index 000000000..32d7d3adc --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/symbols/StructDefinition.java @@ -0,0 +1,56 @@ +package dk.camelot64.kickc.model.symbols; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeStruct; + +/** + * A struct definition containing a set of variables. + */ +public class StructDefinition extends Scope { + + public StructDefinition(String name, Scope parentScope) { + super(name, parentScope); + } + + @Override + public SymbolType getType() { + return new SymbolTypeStruct(this); + } + + /** + * Get a struct member variable + * @param name The name of the member + * @return The member variable + */ + public Variable getMember(String name) { + for(Variable member : getAllVariables(false)) { + if(member.getLocalName().equals(name)) { + return member; + } + } + return null; + } + + /** + * Get the number of bytes that the member data is offset from the start of the struct + * @param member The member to find offset for + * @return The byte offset of the start of the member data + */ + public int getMemberByteOffset(Variable member) { + int byteOffset=0; + for(Variable structMember : getAllVariables(false)) { + if(structMember.equals(member)) { + break; + } else { + byteOffset += structMember.getType().getSizeBytes(); + } + } + return byteOffset; + } + + @Override + public String toString(Program program) { + return "block-"+getFullName(); + } +} diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/VariableVersion.java b/src/main/java/dk/camelot64/kickc/model/symbols/VariableVersion.java index 7aca0fd3a..47c67dc0f 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/VariableVersion.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/VariableVersion.java @@ -12,6 +12,7 @@ public class VariableVersion extends Variable { this.setDeclaredAlignment(versionOf.getDeclaredAlignment()); this.setDeclaredRegister(versionOf.getDeclaredRegister()); this.setDeclaredVolatile(versionOf.isDeclaredVolatile()); + this.setInferredType(versionOf.isInferredType()); this.versionOfName = versionOf.getLocalName(); this.setComments(versionOf.getComments()); } diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java index 9bf23a2f8..c0abe5d1b 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolType.java @@ -1,25 +1,26 @@ package dk.camelot64.kickc.model.types; -import dk.camelot64.kickc.model.CompileError; - -import java.util.ArrayList; -import java.util.Collection; - /** Symbol Types */ public interface SymbolType { /** Unsigned byte (8 bits)). */ - SymbolTypeInteger BYTE = new SymbolTypeInteger("byte", 0, 255, false, 8); + SymbolTypeIntegerFixed BYTE = new SymbolTypeIntegerFixed("byte", 0, 255, false, 8); /** Signed byte (8 bits). */ - SymbolTypeInteger SBYTE = new SymbolTypeInteger("signed byte", -128, 127, true, 8); + SymbolTypeIntegerFixed SBYTE = new SymbolTypeIntegerFixed("signed byte", -128, 127, true, 8); /** Unsigned word (2 bytes, 16 bits). */ - SymbolTypeInteger WORD = new SymbolTypeInteger("word", 0, 65_535, false, 16); + SymbolTypeIntegerFixed WORD = new SymbolTypeIntegerFixed("word", 0, 65_535, false, 16); /** Signed word (2 bytes, 16 bits). */ - SymbolTypeInteger SWORD = new SymbolTypeInteger("signed word", -32_768, 32_767, true, 16); + SymbolTypeIntegerFixed SWORD = new SymbolTypeIntegerFixed("signed word", -32_768, 32_767, true, 16); /** Unsigned double word (4 bytes, 32 bits). */ - SymbolTypeInteger DWORD = new SymbolTypeInteger("dword", 0, 4_294_967_296L, false, 32); + SymbolTypeIntegerFixed DWORD = new SymbolTypeIntegerFixed("dword", 0, 4_294_967_296L, false, 32); /** Signed double word (4 bytes, 32 bits). */ - SymbolTypeInteger SDWORD = new SymbolTypeInteger("signed dword", -2_147_483_648, 2_147_483_647, true, 32); + SymbolTypeIntegerFixed SDWORD = new SymbolTypeIntegerFixed("signed dword", -2_147_483_648, 2_147_483_647, true, 32); + /** Integer with unknown size and unknown signedness (used for constant expressions). */ + SymbolTypeIntegerAuto NUMBER = new SymbolTypeIntegerAuto("number"); + /** Unsigned integer with unknown size (used for constant expressions). */ + SymbolTypeIntegerAuto UNUMBER = new SymbolTypeIntegerAuto("unumber"); + /** Signed integer with unknown size (used for constant expressions). */ + SymbolTypeIntegerAuto SNUMBER = new SymbolTypeIntegerAuto("snumber"); /** String value (treated like byte* ). */ SymbolTypeNamed STRING = new SymbolTypeNamed("string", 99); /** Boolean value. */ @@ -89,6 +90,8 @@ public interface SymbolType { return BOOLEAN; case "void": return VOID; + case "number": + return NUMBER; } return null; } @@ -103,164 +106,18 @@ public interface SymbolType { /** * Get the size of the type (in bytes). - * @return The size + * @return The size. -1 if the type is compile-time only. */ int getSizeBytes(); /** - * Is the type {@link #BYTE} or compatible {@link SymbolTypeMulti} - * - * @param type The type to examine - * @return true if the type is BYTE compatible - */ - static boolean isByte(SymbolType type) { - if(BYTE.equals(type)) { - return true; - } else if(type instanceof SymbolTypeMulti) { - return ((SymbolTypeMulti) type).isByte(); - } else { - return false; - } - } - - /** - * Is the type {@link #SBYTE} or compatible {@link SymbolTypeMulti} - * - * @param type The type to examine - * @return true if the type is SBYTE compatible - */ - static boolean isSByte(SymbolType type) { - if(SBYTE.equals(type)) { - return true; - } else if(type instanceof SymbolTypeMulti) { - return ((SymbolTypeMulti) type).isSByte(); - } else { - return false; - } - } - - /** - * Is the type {@link #WORD} or compatible {@link SymbolTypeMulti} - * - * @param type The type to examine - * @return true if the type is WORD compatible - */ - static boolean isWord(SymbolType type) { - if(WORD.equals(type)) { - return true; - } else if(type instanceof SymbolTypeMulti) { - return ((SymbolTypeMulti) type).isWord(); - } else { - return false; - } - } - - /** - * Is the type {@link #SWORD} or compatible {@link SymbolTypeMulti} - * - * @param type The type to examine - * @return true if the type is SWORD compatible - */ - static boolean isSWord(SymbolType type) { - if(SWORD.equals(type)) { - return true; - } else if(type instanceof SymbolTypeMulti) { - return ((SymbolTypeMulti) type).isSWord(); - } else { - return false; - } - } - - /** - * Is the type {@link #DWORD} or compatible {@link SymbolTypeMulti} - * - * @param type The type to examine - * @return true if the type is DWORD compatible - */ - static boolean isDWord(SymbolType type) { - if(DWORD.equals(type)) { - return true; - } else if(type instanceof SymbolTypeMulti) { - return ((SymbolTypeMulti) type).isDWord(); - } else { - return false; - } - } - - /** - * Is the type {@link #SDWORD} or compatible {@link SymbolTypeMulti} - * - * @param type The type to examine - * @return true if the type is SDWORD compatible - */ - static boolean isSDWord(SymbolType type) { - if(SDWORD.equals(type)) { - return true; - } else if(type instanceof SymbolTypeMulti) { - return ((SymbolTypeMulti) type).isSWord(); - } else { - return false; - } - } - - /** - * Is the type an integer type or compatible {@link SymbolTypeMulti} + * Is the type an integer type (including {@link #NUMBER}) * * @param type The type to examine * @return true if the type is integer */ static boolean isInteger(SymbolType type) { - return isSDWord(type) || isDWord(type) || isSWord(type) || isWord(type) || isSByte(type) || isByte(type); - } - - /** - * Get all integer types. - * - * @return All integeer types - */ - static Collection getIntegerTypes() { - ArrayList types = new ArrayList<>(); - types.add(BYTE); - types.add(SBYTE); - types.add(WORD); - types.add(SWORD); - types.add(DWORD); - types.add(SDWORD); - return types; - } - - /** - * Find the smallest integer type that contains both sub-types usable for math ( + - * / ). - * - * @param type1 Left type in a binary expression - * @param type2 Right type in a binary expression - * @return - */ - static SymbolType promotedMathType(SymbolTypeInteger type1, SymbolTypeInteger type2) { - for(SymbolTypeInteger candidate : getIntegerTypes()) { - boolean match1 = type1.getMinValue() >= candidate.getMinValue() && type1.getMaxValue() <= candidate.getMaxValue(); - boolean match2 = type2.getMinValue() >= candidate.getMinValue() && type2.getMaxValue() <= candidate.getMaxValue(); - if(match1 && match2) { - return candidate; - } - } - throw new NoMatchingType("Cannot promote to a common type for "+type1.toString()+" and "+type2.toString()); - } - - /** - * Find the unsigned integer type that contains both sub-types usable for binary operations ( & | ^ ). - * - * @param type1 Left type in a binary expression - * @param type2 Right type in a binary expression - * @return - */ - static SymbolType promotedBitwiseType(SymbolTypeInteger type1, SymbolTypeInteger type2) { - for(SymbolTypeInteger candidate : getIntegerTypes()) { - if(!candidate.isSigned() && type1.getBits()<=candidate.getBits() && type2.getBits()<=candidate.getBits()) { - return candidate; - } - } - throw new CompileError("Cannot promote to a common type for "+type1.toString()+" and "+type2.toString()); + return SDWORD.equals(type) || DWORD.equals(type) || SWORD.equals(type) || WORD.equals(type) || SBYTE.equals(type) || BYTE.equals(type) || NUMBER.equals(type)|| UNUMBER.equals(type)|| SNUMBER.equals(type); } } diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeArray.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeArray.java index 738b40754..7aaa8fce2 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeArray.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeArray.java @@ -31,11 +31,7 @@ public class SymbolTypeArray extends SymbolTypePointer { @Override public String getTypeName() { SymbolType elementType = getElementType(); - if(elementType instanceof SymbolTypeMulti) { - return "(" + elementType.getTypeName() + ")" + "[" + (size == null ? "" : size.toString()) + "]"; - } else { - return elementType.getTypeName() + "[" + (size == null ? "" : size.toString()) + "]"; - } + return elementType.getTypeName() + "[" + (size == null ? "" : size.toString()) + "]"; } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java index 8d5b113f4..4fc97f3cb 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeBlockScope.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.model.types; /** A block scope */ -public class SymbolTypeBlockScope implements SymbolTypeSimple { +public class SymbolTypeBlockScope implements SymbolType { public SymbolTypeBlockScope() { diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java new file mode 100644 index 000000000..9e07c94da --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeConversion.java @@ -0,0 +1,259 @@ +package dk.camelot64.kickc.model.types; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ConstantNotLiteral; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.symbols.ProgramScope; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.ConstantLiteral; +import dk.camelot64.kickc.model.values.ConstantValue; +import dk.camelot64.kickc.model.values.RValue; + +/** + * Rules for converting integer types. + *

+ * Integer conversion implements C99 6.3.1.8 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=70 + *

+ * The special number type is converted as described here https://gitlab.com/camelot/kickc/issues/181 + */ +public class SymbolTypeConversion { + + /** + * Find the integer type that results from a binary operator according to C99 6.3.1.8 + * http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=70 + * + * @param type1 Left type in a binary expression + * @param type2 Right type in a binary expression + * @return The type resulting from a binary operator performed on the two parameters + */ + public static SymbolType convertedMathType(SymbolTypeInteger type1, SymbolTypeInteger type2) { + // If any of the two types are unresolved - return an unresolved result + if(SymbolType.NUMBER.equals(type1) || SymbolType.NUMBER.equals(type2)) { + return SymbolType.NUMBER; + } + // If any of the two types are unresolved unsigned - return an unresolved unsigned result + if(SymbolType.UNUMBER.equals(type1) || SymbolType.UNUMBER.equals(type2)) { + return SymbolType.UNUMBER; + } + // If any of the two types are unresolved signed - return an unresolved signed result + if(SymbolType.SNUMBER.equals(type1) || SymbolType.SNUMBER.equals(type2)) { + return SymbolType.SNUMBER; + } + + // Both types are resolved (fixed) integer types + SymbolTypeIntegerFixed fixed1 = (SymbolTypeIntegerFixed) type1; + SymbolTypeIntegerFixed fixed2 = (SymbolTypeIntegerFixed) type2; + // C99 6.3.1.8 a. If two operands have the same type no conversion is performed + if(type1.equals(type2)) + return type1; + // C99 6.3.1.8 b. If both are signed or both are unsigned then the smallest type is converted to the size of the large type (byte->word->sword, sbyte->sword->sdword) + if(fixed1.isSigned() == fixed2.isSigned()) + return (fixed1.getBits() > fixed2.getBits()) ? fixed1 : fixed2; + // C99 6.3.1.8 c. One is signed and one unsigned. + // If the signed type can contain all values of the unsigned type then the unsigned value is converted to the signed type. (byte->sword, byte->sdword, word->sdword). + SymbolTypeIntegerFixed typeS, typeU; + if(fixed1.isSigned()) { + typeS = fixed1; + typeU = fixed2; + } else { + typeS = fixed2; + typeU = fixed1; + } + if(typeS.getBits() > typeU.getBits()) + return typeS; + // C99 6.3.1.8 d. The unsigned type is the same size as or larger than the signed type. + // The signed value is first converted to the size of the unsigned type and then converted to unsigned changing the sign and the value + // (sbyte->byte, sbyte->word, sbyte->dword, sword->word, sword->dword, sdword->dword). + return typeU; + } + + /** + * Find the integer type that a number operand in a binary operator should be converted/cast to according to number type conversion https://gitlab.com/camelot/kickc/issues/181 + * + * @param left The left value + * @param right The right value + * @param symbols The program scope symbols (used for looking up symbols and constants) + * @param currentStmt The current statement (used only for exception context) + * @return a non-null fixed integer type if a number type conversion is relevant. + */ + public static SymbolType getNumberCastType(RValue left, RValue right, ProgramScope symbols, Statement currentStmt) { + + SymbolType leftType = SymbolTypeInference.inferType(symbols, left); + SymbolType rightType = SymbolTypeInference.inferType(symbols, right); + + if(SymbolType.NUMBER.equals(leftType) || SymbolType.NUMBER.equals(rightType)) { + // A special type number is assigned to integer constants without a postfix literal. + // Numbers are flexible and will take a type based on their actual value when they meet a typed number in a calculation. + // Number types are only usable at compile time. + + if(leftType.equals(rightType)) { + // a) If the two operands are numbers the result is a number + return null; + } + + // a) If any the two operands are unsigned numbers the result is an unsigned number + if(SymbolType.UNUMBER.equals(leftType) || SymbolType.UNUMBER.equals(rightType)) + return SymbolType.UNUMBER; + // a) If any the two operands are signed numbers the result is an signed number + if(SymbolType.SNUMBER.equals(leftType) || SymbolType.SNUMBER.equals(rightType)) + return SymbolType.SNUMBER; + + // Treat pointers like WORD + if(leftType instanceof SymbolTypePointer) leftType = SymbolType.WORD; + if(rightType instanceof SymbolTypePointer) rightType = SymbolType.WORD; + + // Identify which of the two operands is a number and which is a fixed type + RValue numberVal; + SymbolTypeIntegerFixed fixedType; + if(SymbolType.NUMBER.equals(leftType) && SymbolType.isInteger(rightType)) { + // Left is the number type - right is the fixed type + numberVal = left; + fixedType = (SymbolTypeIntegerFixed) rightType; + } else if(SymbolType.NUMBER.equals(rightType) && SymbolType.isInteger(leftType)) { + // Right is the number type - left is the fixed type + numberVal = right; + fixedType = (SymbolTypeIntegerFixed) leftType; + } else { + // Binary operator combining number and non-integer + return null; + } + + if(fixedType.isSigned()) { + return SymbolType.SNUMBER; + } else { + return SymbolType.UNUMBER; + } + } + + // No number conversion + return null; + + } + + + public static SymbolType getSmallestSignedFixedIntegerType(ConstantValue constantValue, ProgramScope symbols) { + ConstantLiteral constantLiteral; + try { + constantLiteral = constantValue.calculateLiteral(symbols); + } catch(ConstantNotLiteral e) { + // Postpone til later! + return null; + } + if(constantLiteral instanceof ConstantInteger) { + Long value = ((ConstantInteger) constantLiteral).getValue(); + // b) If one operand is a signed type and the other a number the number is converted to the smallest signed type that can hold its values. + SymbolTypeIntegerFixed smallestSignedType = SymbolTypeIntegerFixed.getSmallestSigned(value); + if(smallestSignedType == null) { + throw new CompileError("Number constant has value that cannot be represented by a signed type " + constantValue.toString()); + } + return smallestSignedType; + } + // Postpone til later! + return null; + } + + public static SymbolType getSmallestUnsignedFixedIntegerType(ConstantValue constantValue, ProgramScope symbols) { + ConstantLiteral constantLiteral; + try { + constantLiteral = constantValue.calculateLiteral(symbols); + } catch(ConstantNotLiteral e) { + // Postpone til later! + return null; + } + if(constantLiteral instanceof ConstantInteger) { + Long value = ((ConstantInteger) constantLiteral).getValue(); + // b) If one operand is a signed type and the other a number the number is converted to the smallest signed type that can hold its values. + SymbolTypeIntegerFixed smallestUnsignedType; + if(value < 0) { + smallestUnsignedType = SymbolTypeIntegerFixed.getSmallestUnsigned(-value); + } else { + smallestUnsignedType = SymbolTypeIntegerFixed.getSmallestUnsigned(value); + } + if(smallestUnsignedType == null) { + throw new CompileError("Number constant has value that cannot be represented by a unsigned type " + constantValue.toString()); + } + return smallestUnsignedType; + } + // Postpone til later! + return null; + } + + + /** + * Determines if the types of an assignment match up properly + * + * @param lValueType The type of the LValue + * @param rValueType The type of the RValue + * @return true if the types match up + */ + public static boolean assignmentTypeMatch(SymbolType lValueType, SymbolType rValueType) { + if(lValueType.equals(rValueType)) + return true; + if(SymbolType.WORD.equals(lValueType) && SymbolType.BYTE.equals(rValueType)) + return true; + if(SymbolType.DWORD.equals(lValueType) && SymbolType.BYTE.equals(rValueType)) + return true; + if(SymbolType.DWORD.equals(lValueType) && SymbolType.WORD.equals(rValueType)) + return true; + if(SymbolType.SWORD.equals(lValueType) && SymbolType.SBYTE.equals(rValueType)) + return true; + if(SymbolType.SDWORD.equals(lValueType) && SymbolType.SBYTE.equals(rValueType)) + return true; + if(SymbolType.SDWORD.equals(lValueType) && SymbolType.SWORD.equals(rValueType)) + return true; + if(SymbolType.NUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) { + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.UNUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) { + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.SNUMBER.equals(rValueType) && SymbolType.isInteger(lValueType)) { + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.NUMBER.equals(lValueType) && SymbolType.isInteger(rValueType)) { + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.UNUMBER.equals(lValueType) && SymbolType.isInteger(rValueType)) { + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.SNUMBER.equals(lValueType) && SymbolType.isInteger(rValueType)) { + // R-value is still a number - constants are probably not done being identified & typed + return true; + } + if(SymbolType.STRING.equals(rValueType) && lValueType instanceof SymbolTypePointer && SymbolType.BYTE.equals(((SymbolTypePointer) lValueType).getElementType())) { + // String value can be assigned into a pointer + return true; + } + if(lValueType instanceof SymbolTypePointer && rValueType instanceof SymbolTypePointer && assignmentTypeMatch(((SymbolTypePointer) lValueType).getElementType(), ((SymbolTypePointer) rValueType).getElementType())) { + // Pointer types assigned from each other + // TODO: Maybe handle sizes + return true; + } + return false; + } + + /** + * Determines if the left side of an assignment needs a cast to be assigned to the right side + * + * @param lValueType The type of the LValue + * @param rValueType The type of the RValue + * @return true if the left side needs a cast + */ + public static boolean assignmentCastNeeded(SymbolType lValueType, SymbolType rValueType) { + if(lValueType.equals(rValueType)) + return false; + else if(lValueType instanceof SymbolTypePointer && rValueType instanceof SymbolTypePointer && ((SymbolTypePointer) lValueType).getElementType().equals(((SymbolTypePointer) rValueType).getElementType())) + return false; + else if(lValueType instanceof SymbolTypePointer && SymbolType.STRING.equals(rValueType) && SymbolType.BYTE.equals(((SymbolTypePointer) lValueType).getElementType())) + return false; + else + return true; + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java index d80e44138..3506dfadd 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInference.java @@ -1,143 +1,19 @@ package dk.camelot64.kickc.model.types; +import dk.camelot64.kickc.fragment.AsmFragmentInstanceSpec; import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.ConstantNotLiteral; import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.operators.Operator; import dk.camelot64.kickc.model.operators.OperatorBinary; import dk.camelot64.kickc.model.operators.OperatorUnary; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.statements.*; +import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.symbols.*; import dk.camelot64.kickc.model.values.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - /** - * Type inference of expressions (rValues & unary/binary operators) + * Type inference of an RValue */ public class SymbolTypeInference { - /** - * Infer the type of a unary operator on a value - * - * @param programScope The program scope usable for accessing the symbol table - * @param operator The unary operator - * @param rValue The value - * @return The type of the resulting value - */ - public static SymbolType inferType(ProgramScope programScope, OperatorUnary operator, RValue rValue) { - if(Operators.TYPEID.equals(operator)) { - return SymbolType.BYTE; - } else if(Operators.SIZEOF.equals(operator)) { - return SymbolType.BYTE; - } - if(rValue instanceof ConstantValue) { - // Calculate resulting constant literal - try { - ConstantValue constRValue = (ConstantValue) rValue; - ConstantLiteral literalRValue = constRValue.calculateLiteral(programScope); - ConstantValue value = operator.calculateLiteral(literalRValue, programScope); - return value.getType(programScope); - } catch(ConstantNotLiteral e) { - // Value literal cannot be calculated - } - } - // Infer value type - and then infer operator result type - SymbolType valueType = inferType(programScope, rValue); - return inferType(operator, valueType); - } - - /** - * Infer the type of a unary operator on an operand type - * - * @param operator The unary operator - * @param operandType The operand type - * @return The type of the result from applying the operator on the operand - */ - public static SymbolType inferType(OperatorUnary operator, SymbolType operandType) { - if(operandType instanceof SymbolTypeSimple) { - return operator.inferType((SymbolTypeSimple) operandType); - } else { - // Infer all resulting types for each sub-type of the multi-type - ArrayList resultTypes = new ArrayList<>(); - for(SymbolType opType : ((SymbolTypeMulti) operandType).getTypes()) { - SymbolType resType = inferType(operator, opType); - if(!resultTypes.contains(resType)) { - resultTypes.add(resType); - } - } - if(resultTypes.size() == 1) { - return resultTypes.get(0); - } else { - return new SymbolTypeMulti(resultTypes); - } - } - } - - /** - * Infer the type of a binary operator on a value - * - * @param programScope The program scope usable for accessing the symbol table - * @param left The left value - * @param operator The binary operator - * @param rValue The right value - * @return The type of the resulting value - */ - public static SymbolType inferType(ProgramScope programScope, RValue left, OperatorBinary operator, RValue right) { - if(left instanceof ConstantValue && right instanceof ConstantValue) { - // Calculate resulting constant literal - try { - ConstantValue value = operator.calculateLiteral( - ((ConstantValue) left).calculateLiteral(programScope), - ((ConstantValue) right).calculateLiteral(programScope) - ); - return value.getType(programScope); - } catch(ConstantNotLiteral e) { - // Value literal cannot be calculated - } - } - SymbolType leftType = inferType(programScope, left); - SymbolType rightType = inferType(programScope, right); - return inferType(leftType, operator, rightType); - } - - public static SymbolType inferType(SymbolType left, OperatorBinary operator, SymbolType right) { - if(left instanceof SymbolTypeSimple && right instanceof SymbolTypeSimple) { - return operator.inferType((SymbolTypeSimple) left, (SymbolTypeSimple) right); - } else { - // Infer all resulting types for each sub-type of the multi-type - if(left instanceof SymbolTypeSimple) { - left = new SymbolTypeMulti(Arrays.asList(left)); - } - if(right instanceof SymbolTypeSimple) { - right = new SymbolTypeMulti(Arrays.asList(right)); - } - ArrayList resultTypes = new ArrayList<>(); - for(SymbolType leftType : ((SymbolTypeMulti) left).getTypes()) { - for(SymbolType rightType : ((SymbolTypeMulti) right).getTypes()) { - SymbolType resType; - try { - resType = inferType(leftType, operator, rightType); - if(!resultTypes.contains(resType)) { - resultTypes.add(resType); - } - } catch(NoMatchingType e) { - // Cannot promote to common type - ignore! - } - } - } - if(resultTypes.size() == 1) { - return resultTypes.get(0); - } else { - return new SymbolTypeMulti(resultTypes); - } - } - } - public static SymbolType inferType(ProgramScope symbols, RValue rValue) { SymbolType type = null; if(rValue instanceof VariableRef) { @@ -159,10 +35,13 @@ public class SymbolTypeInference { type = SymbolType.BOOLEAN; } else if(rValue instanceof ConstantUnary) { ConstantUnary constUnary = (ConstantUnary) rValue; - return inferType(symbols, constUnary.getOperator(), constUnary.getOperand()); + SymbolType valueType = inferType(symbols, constUnary.getOperand()); + return constUnary.getOperator().inferType(valueType); } else if(rValue instanceof ConstantBinary) { ConstantBinary constBin = (ConstantBinary) rValue; - return inferType(symbols, constBin.getLeft(), constBin.getOperator(), constBin.getRight()); + SymbolType leftType = inferType(symbols, constBin.getLeft()); + SymbolType rightType = inferType(symbols, constBin.getRight()); + return constBin.getOperator().inferType(leftType, rightType); } else if(rValue instanceof ValueList) { type = inferTypeList(symbols, (ValueList) rValue); } else if(rValue instanceof PointerDereference) { @@ -191,10 +70,51 @@ public class SymbolTypeInference { } else if(rValue instanceof RangeComparison) { return ((RangeComparison) rValue).getType(); } else if(rValue instanceof RangeNext) { - return SymbolType.BYTE; + SymbolType rangedType = inferType(symbols, ((RangeNext) rValue).getRangeFirst()); + if(SymbolType.SBYTE.equals(rangedType) || SymbolType.SWORD.equals(rangedType) || SymbolType.SDWORD.equals(rangedType)) { + return SymbolType.SBYTE; + } else { + return SymbolType.BYTE; + } } else if(rValue instanceof ProcedureRef) { Procedure procedure = symbols.getProcedure((ProcedureRef) rValue); return procedure.getType(); + } else if(rValue instanceof AssignmentRValue) { + StatementAssignment assignment = ((AssignmentRValue) rValue).getAssignment(); + SymbolType rValueType; + RValue rValue1 = assignment.getrValue1(); + RValue rValue2 = assignment.getrValue2(); + if(assignment.getrValue1() == null && assignment.getOperator() == null) { + // Copy assignment + rValueType = inferType(symbols, rValue2); + } else if(assignment.getrValue1() == null && assignment.getOperator() instanceof OperatorUnary) { + // Unary operation assignment + SymbolType valueType = inferType(symbols, rValue2); + rValueType = ((OperatorUnary) assignment.getOperator()).inferType(valueType); + } else if(assignment.getOperator() instanceof OperatorBinary) { + // Binary operation assignment + SymbolType leftType = inferType(symbols, rValue1); + SymbolType rightType = inferType(symbols, rValue2); + rValueType = ((OperatorBinary) assignment.getOperator()).inferType(leftType, rightType); + } else { + throw new CompileError("Cannot infer type of " + assignment.toString()); + } + return rValueType; + } else if(rValue instanceof StructMemberRef) { + StructMemberRef structMemberRef = (StructMemberRef) rValue; + SymbolType structType = inferType(symbols, structMemberRef.getStruct()); + if(structType instanceof SymbolTypeStruct) { + String typeName = ((SymbolTypeStruct) structType).getStructTypeName(); + StructDefinition structDefinition = symbols.getStructDefinition(typeName); + Variable structMember = structDefinition.getVariable(structMemberRef.getMemberName()); + return structMember.getType(); + } else { + AsmFragmentInstanceSpec asmFragmentInstanceSpec = null; + Program program = asmFragmentInstanceSpec.getProgram(); + throw new CompileError("Dot applied to non-struct "+ structMemberRef.getStruct().toString(program)); + } + } else if(rValue instanceof StructZero) { + return ((StructZero)rValue).getTypeStruct(); } if(type == null) { throw new RuntimeException("Cannot infer type for " + rValue.toString()); @@ -209,273 +129,23 @@ public class SymbolTypeInference { if(elmType == null) { elmType = type; } else { - // element type already defined - check for a match - if(!typeMatch(elmType, type)) { - if(typeMatch(type, elmType)) { - elmType = type; + if(!elmType.equals(type)) { + if(SymbolType.NUMBER.equals(elmType) && SymbolType.isInteger(type)) { + elmType = SymbolType.NUMBER; + } else if(SymbolType.isInteger(elmType) && SymbolType.NUMBER.equals(type)) { + elmType = SymbolType.NUMBER; } else { - throw new RuntimeException("Array element has type mismatch " + elm.toString() + " not matching type " + elmType.getTypeName()); + throw new CompileError("Array element has type mismatch "+elm.toString() + " not matching type " + elmType.getTypeName()); } } } } if(elmType != null) { - if((list.getList().size() == 2 && SymbolType.isByte(elmType) || SymbolType.isSByte(elmType))) { - // Potentially a word constructor - return a composite type - ArrayList types = new ArrayList<>(); - types.add(new SymbolTypeArray(elmType)); - types.add(SymbolType.WORD); - return new SymbolTypeMulti(types); - } else if((list.getList().size() == 2 && SymbolType.isWord(elmType))) { - // Potentially a dword constructor - return a composite type - ArrayList types = new ArrayList<>(); - types.add(new SymbolTypeArray(elmType)); - types.add(SymbolType.DWORD); - return new SymbolTypeMulti(types); - } else { - return new SymbolTypeArray(elmType); - } + long size = list.getList().size(); + return new SymbolTypeArray(elmType, new ConstantInteger(size, size<256?SymbolType.BYTE:SymbolType.WORD)); } else { throw new RuntimeException("Cannot infer list element type " + list.toString()); } } - public static SymbolType inferTypeRValue(ProgramScope symbols, StatementAssignment assignment) { - SymbolType rValueType; - RValue rValue1 = assignment.getrValue1(); - RValue rValue2 = assignment.getrValue2(); - if(assignment.getrValue1() == null && assignment.getOperator() == null) { - rValueType = inferType(symbols, rValue2); - } else if(assignment.getrValue1() == null && assignment.getOperator() instanceof OperatorUnary) { - rValueType = inferType(symbols, (OperatorUnary) assignment.getOperator(), rValue2); - } else if(assignment.getOperator() instanceof OperatorBinary) { - rValueType = inferType(symbols, rValue1, (OperatorBinary) assignment.getOperator(), rValue2); - } else { - throw new CompileError("Cannot infer type of " + assignment.toString()); - } - return rValueType; - } - - /** - * Determine if lValue and rValue types match (the same types, not needing a cast). - * - * @param lValueType The lValue type - * @param rValueType The rvalue type - * @return true if the types match - */ - public static boolean typeMatch(SymbolType lValueType, SymbolType rValueType) { - if(lValueType.equals(rValueType)) { - // Types match directly - return true; - } else if(rValueType instanceof SymbolTypeMulti) { - Collection rTypes = ((SymbolTypeMulti) rValueType).getTypes(); - if(lValueType instanceof SymbolTypeMulti) { - // Both are inline types - RValue type must be superset of LValue - Collection lTypes = ((SymbolTypeMulti) lValueType).getTypes(); - return typeContainsMatchAll(lTypes, rTypes); - } else { - // Types match because the right side matches the left side - return typeContainsMatch(lValueType, rTypes); - } - } else if(lValueType instanceof SymbolTypePointer && rValueType instanceof SymbolTypePointer) { - return typeMatch( - ((SymbolTypePointer) lValueType).getElementType(), - ((SymbolTypePointer) rValueType).getElementType()); - } else if(lValueType instanceof SymbolTypePointer && SymbolType.STRING.equals(rValueType)) { - if(SymbolType.isByte(((SymbolTypePointer) lValueType).getElementType())) { - return true; - } - } else if(SymbolType.STRING.equals(lValueType) && rValueType instanceof SymbolTypePointer) { - if(SymbolType.isByte(((SymbolTypePointer) rValueType).getElementType())) { - return true; - } - } - return false; - } - - private static boolean typeContainsMatchAll(Collection lTypes, Collection rTypes) { - for(SymbolType lType : lTypes) { - if(!typeContainsMatch(lType, rTypes)) { - return false; - } - } - return true; - } - - /** - * Determine is a list of potential inferred types contains a match for another type - * - * @param lValueType The type (rValue) we want to find a match for in the list - * @param rTypes The list of inferred potential types - * @return true if the list has a match - */ - private static boolean typeContainsMatch(SymbolType lValueType, Collection rTypes) { - for(SymbolType rType : rTypes) { - if(typeMatch(lValueType, rType)) { - return true; - } - } - return false; - } - - public static void inferCallLValue(Program program, StatementCall call, boolean reinfer) { - ProgramScope programScope = program.getScope(); - LValue lValue = call.getlValue(); - if(lValue instanceof VariableRef) { - Variable symbol = programScope.getVariable((VariableRef) lValue); - if(SymbolType.VAR.equals(symbol.getType()) || (reinfer && symbol.isInferredType())) { - Procedure procedure = programScope.getProcedure(call.getProcedure()); - SymbolType type = procedure.getReturnType(); - setInferedType(program, call, symbol, type); - } - } - } - - public static void inferCallPointerLValue(Program program, StatementCallPointer call, boolean reinfer) { - ProgramScope programScope = program.getScope(); - LValue lValue = call.getlValue(); - if(lValue instanceof VariableRef) { - Variable symbol = programScope.getVariable((VariableRef) lValue); - if(SymbolType.VAR.equals(symbol.getType()) || (reinfer && symbol.isInferredType())) { - SymbolType procedureType = inferType(programScope, call.getProcedure()); - if(procedureType instanceof SymbolTypeProcedure) { - SymbolType returnType = ((SymbolTypeProcedure) procedureType).getReturnType(); - setInferedType(program, call, symbol, returnType); - } - } - } - } - - public static void inferPhiVariable(Program program, StatementPhiBlock.PhiVariable phiVariable, boolean reinfer) { - ProgramScope programScope = program.getScope(); - - Variable symbol = programScope.getVariable(phiVariable.getVariable()); - if(SymbolType.VAR.equals(symbol.getType()) || (reinfer && symbol.isInferredType())) { - SymbolType type = null; - for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { - RValue rValue = phiRValue.getrValue(); - SymbolType valueType = inferType(programScope, rValue); - if(type == null) { - type = valueType; - } else { - SymbolType newType = intersectTypes(type, valueType); - if(newType == null) { - throw new CompileError("Types not compatible " + type + " and " + valueType); - } - type = newType; - } - } - if(!SymbolType.VAR.equals(symbol.getType()) && !type.equals(symbol.getType())) { - program.getLog().append("Inferred type updated to " + type + " for " + symbol.toString(program)); - } - symbol.setTypeInferred(type); - } - } - - public static void inferAssignmentLValue(Program program, StatementAssignment assignment, boolean reinfer) { - ProgramScope programScope = program.getScope(); - LValue lValue = assignment.getlValue(); - if(lValue instanceof VariableRef) { - Variable symbol = programScope.getVariable((VariableRef) lValue); - if(SymbolType.VAR.equals(symbol.getType()) || (reinfer && symbol.isInferredType())) { - // Unresolved symbol - perform inference - Operator operator = assignment.getOperator(); - if(assignment.getrValue1() == null && operator == null) { - // Copy operation - RValue rValue = assignment.getrValue2(); - SymbolType type = inferType(programScope, rValue); - setInferedType(program, assignment, symbol, type); - } else if(assignment.getrValue1() == null && operator instanceof OperatorUnary) { - // Unary operation - RValue rValue = assignment.getrValue2(); - SymbolType type = inferType(programScope, (OperatorUnary) operator, rValue); - setInferedType(program, assignment, symbol, type); - } else if(operator instanceof OperatorBinary) { - // Binary operation - SymbolType type = inferType( - programScope, assignment.getrValue1(), - (OperatorBinary) assignment.getOperator(), - assignment.getrValue2()); - setInferedType(program, assignment, symbol, type); - } else { - throw new CompileError("Cannot infer type of " + assignment); - } - // If the type is an array or a string the symbol is constant - if(symbol.getType() instanceof SymbolTypeArray) { - symbol.setDeclaredConstant(true); - } else if(SymbolType.STRING.equals(symbol.getType())) { - symbol.setDeclaredConstant(true); - } - } - } - } - - private static void setInferedType(Program program, Statement statement, Variable symbol, SymbolType type) { - if(!SymbolType.VAR.equals(symbol.getType()) && !type.equals(symbol.getType())) { - program.getLog().append("Inferred type updated to " + type + " in " + statement.toString(program, false)); - } - symbol.setTypeInferred(type); - } - - public static void inferLValue(Program program, StatementLValue statementLValue, boolean reinfer) { - if(statementLValue instanceof StatementAssignment) { - inferAssignmentLValue(program, (StatementAssignment) statementLValue, reinfer); - } else if(statementLValue instanceof StatementCall) { - inferCallLValue(program, (StatementCall) statementLValue, reinfer); - } else if(statementLValue instanceof StatementCallPointer) { - inferCallPointerLValue(program, (StatementCallPointer) statementLValue, reinfer); - } else { - throw new RuntimeException("LValue statement not implemented " + statementLValue); - } - } - - /** - * Find the symbol type that is the intersection between the two passed types. - * Handles SymbolTypeMulti by intersecting the sub type lists. - * - * @param type1 The first type - * @param type2 The second type - * @return The intersection between the two types (handling multi-types) - */ - public static SymbolType intersectTypes(SymbolType type1, SymbolType type2) { - List newSubTypes = new ArrayList<>(); - if(type1 instanceof SymbolTypeMulti) { - Collection subTypes1 = ((SymbolTypeMulti) type1).getTypes(); - if(type2 instanceof SymbolTypeMulti) { - Collection subTypes2 = ((SymbolTypeMulti) type2).getTypes(); - for(SymbolType subType1 : subTypes1) { - if(subTypes2.contains(subType1)) { - newSubTypes.add(subType1); - } - } - } else { - // Element type is not multi - check if the list type contains it - if(subTypes1.contains(type2)) { - newSubTypes.add(type2); - } - } - } else { - // List-type not multi - check if the element type contains it - if(type2 instanceof SymbolTypeMulti) { - Collection subTypes2 = ((SymbolTypeMulti) type2).getTypes(); - if(subTypes2.contains(type1)) { - newSubTypes.add(type1); - } - } else { - // Element type is not multi - check if the list type is the same - if(type1.equals(type2)) { - newSubTypes.add(type1); - } - } - } - if(newSubTypes.size() == 0) { - return null; - } else if(newSubTypes.size() == 1) { - // A single type matching - use it - return newSubTypes.get(0); - } else { - // Multiple matches was found - use them - return new SymbolTypeMulti(newSubTypes); - } - } } diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInteger.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInteger.java index 1813650c8..9a64e214d 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInteger.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeInteger.java @@ -1,50 +1,6 @@ package dk.camelot64.kickc.model.types; -/** Integer symbol types (byte, signed byte, word, ...). */ -public class SymbolTypeInteger implements SymbolTypeSimple { +/** Integer type marker interface. */ +public interface SymbolTypeInteger extends SymbolType { - private final String typeName; - private final long minValue; - private final long maxValue; - private final boolean signed; - private final int bits; - - SymbolTypeInteger(String typeName, long minValue, long maxValue, boolean signed, int bits) { - this.typeName = typeName; - this.minValue = minValue; - this.maxValue = maxValue; - this.signed = signed; - this.bits = bits; - } - - @Override - public String getTypeName() { - return typeName; - } - - public long getMinValue() { - return minValue; - } - - public long getMaxValue() { - return maxValue; - } - - public boolean isSigned() { - return signed; - } - - public int getBits() { - return bits; - } - - @Override - public int getSizeBytes() { - return bits/8; - } - - @Override - public String toString() { - return getTypeName(); - } } diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java new file mode 100644 index 000000000..6e643aad8 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerAuto.java @@ -0,0 +1,42 @@ +package dk.camelot64.kickc.model.types; + +import java.util.Objects; + +/** Integer type that has not yet been fixed. This is used for constant expressions. The type is fixed when the constant meets a fixed type. */ +public class SymbolTypeIntegerAuto implements SymbolTypeInteger { + + private final String typeName; + + SymbolTypeIntegerAuto(String typeName) { + this.typeName = typeName; + } + + @Override + public String getTypeName() { + return typeName; + } + + @Override + public int getSizeBytes() { + return -1; + } + + @Override + public String toString() { + return getTypeName(); + } + + + @Override + public boolean equals(Object o) { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + SymbolTypeIntegerAuto that = (SymbolTypeIntegerAuto) o; + return Objects.equals(typeName, that.typeName); + } + + @Override + public int hashCode() { + return Objects.hash(typeName); + } +} diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java new file mode 100644 index 000000000..42f4a2659 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeIntegerFixed.java @@ -0,0 +1,105 @@ +package dk.camelot64.kickc.model.types; + +import java.util.ArrayList; +import java.util.Collection; + +/** Integer type with a fixed size (byte, signed byte, word, ...). */ +public class SymbolTypeIntegerFixed implements SymbolTypeInteger { + + private final String typeName; + private final long minValue; + private final long maxValue; + private final boolean signed; + private final int bits; + + SymbolTypeIntegerFixed(String typeName, long minValue, long maxValue, boolean signed, int bits) { + this.typeName = typeName; + this.minValue = minValue; + this.maxValue = maxValue; + this.signed = signed; + this.bits = bits; + } + + /** + * Get all fixed size integer types. + * + * @return All fixed size integer types + */ + public static Collection getIntegerFixedTypes() { + ArrayList types = new ArrayList<>(); + types.add(BYTE); + types.add(SBYTE); + types.add(WORD); + types.add(SWORD); + types.add(DWORD); + types.add(SDWORD); + return types; + } + /** + * Find the smallest signed type that can hold the passed value + * @param value The value + * @return The smallest signed type that can hold the value + */ + public static SymbolTypeIntegerFixed getSmallestSigned(Long value) { + for(SymbolTypeIntegerFixed fixedType : getIntegerFixedTypes()) { + if(fixedType.isSigned() && fixedType.contains(value)) + return fixedType; + } + return null; + } + + /** + * Find the smallest unsigned type that can hold the passed value + * @param value The value + * @return The smallest unsigned type that can hold the value + */ + public static SymbolTypeIntegerFixed getSmallestUnsigned(Long value) { + for(SymbolTypeIntegerFixed fixedType : getIntegerFixedTypes()) { + if(!fixedType.isSigned() && fixedType.contains(value)) + return fixedType; + } + return null; + } + + + /** + * Determines if a value can be represented by the type without loss of information + * + * @param value The value to examine + * @return true if the type contains the value + */ + public boolean contains(Long number) { + return number >= getMinValue() && number <= getMaxValue(); + } + + @Override + public String getTypeName() { + return typeName; + } + + public long getMinValue() { + return minValue; + } + + public long getMaxValue() { + return maxValue; + } + + public boolean isSigned() { + return signed; + } + + public int getBits() { + return bits; + } + + @Override + public int getSizeBytes() { + return bits/8; + } + + @Override + public String toString() { + return getTypeName(); + } +} diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeMulti.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeMulti.java deleted file mode 100644 index 802810c7f..000000000 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeMulti.java +++ /dev/null @@ -1,136 +0,0 @@ -package dk.camelot64.kickc.model.types; - -import java.util.Arrays; -import java.util.Collection; - -/** - * Symbol Type of an inline expression. Inline expressions can match multiple types depending on the actual value, - * eg. the value 27 matches both byte and signed byte (which can in turn be promoted to word/signed word, dword/signed dword), while the value -252 only matches signed word or signed dword. - */ -public class SymbolTypeMulti implements SymbolType { - - /** All numeric types. */ - public static final SymbolTypeMulti NUMERIC = new SymbolTypeMulti(Arrays.asList(BYTE, SBYTE, WORD, SWORD, DWORD, SDWORD)); - /** - * All potential types for the inline constant. - */ - private Collection types; - - public SymbolTypeMulti(Collection types) { - this.types = types; - } - - public Collection getTypes() { - return types; - } - - @Override - public int getSizeBytes() { - // Find the minimal sizeof - and return that - Integer size = null; - for(SymbolType type : types) { - if(size==null) { - size = type.getSizeBytes(); - } else if(size>type.getSizeBytes()) { - size = type.getSizeBytes(); - } - } - if(size==null) { - return -1; - } - return size; - } - - @Override - public String getTypeName() { - StringBuilder name = new StringBuilder(); - boolean first = true; - for(SymbolType type : types) { - if(first) { - first = false; - } else { - name.append("/"); - } - name.append(type); - } - return name.toString(); - } - - @Override - public boolean equals(Object o) { - if(this == o) { - return true; - } - if(o == null || getClass() != o.getClass()) { - return false; - } - SymbolTypeMulti that = (SymbolTypeMulti) o; - return types != null ? types.equals(that.types) : that.types == null; - } - - @Override - public int hashCode() { - return types != null ? types.hashCode() : 0; - } - - @Override - public String toString() { - return getTypeName(); - } - - /** - * Is unsigned byte one of the potential types - * - * @return true if unsigned byte is a potential type - */ - public boolean isByte() { - return types.contains(BYTE); - } - - /** - * Is signed byte one of the potential types - * - * @return true if signed byte is a potential type - */ - public boolean isSByte() { - return types.contains(SBYTE); - } - - /** - * Is unsigned word one of the potential types - * - * @return true if unsigned word is a potential type - */ - public boolean isWord() { - return types.contains(WORD); - } - - /** - * Is signed word one of the potential types - * - * @return true if signed word is a potential type - */ - public boolean isSWord() { - return types.contains(SWORD); - } - - /** - * Is unsigned dword one of the potential types - * - * @return true if unsigned dword is a potential type - */ - public boolean isDWord() { - return types.contains(DWORD); - } - - /** - * Is signed dword one of the potential types - * - * @return true if signed dword is a potential type - */ - public boolean isSDWord() { - return types.contains(SDWORD); - } - - -} diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java index fce17747e..5578a24bf 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeNamed.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.model.types; /** Basic named (string, char, ...) Symbol Types */ -public class SymbolTypeNamed implements SymbolTypeSimple { +public class SymbolTypeNamed implements SymbolType { private String typeName; diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java index 8be80416d..b9bedcb87 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypePointer.java @@ -1,10 +1,10 @@ package dk.camelot64.kickc.model.types; /** A pointer */ -public class SymbolTypePointer implements SymbolTypeSimple { +public class SymbolTypePointer implements SymbolType { /** The number of bytes needed to represent a pointer in memory. */ - public static final int SIZE_BYTES = 2; + public static final int SIZE_POINTER_BYTES = 2; private SymbolType elementType; @@ -28,7 +28,7 @@ public class SymbolTypePointer implements SymbolTypeSimple { @Override public int getSizeBytes() { - return SIZE_BYTES; + return SIZE_POINTER_BYTES; } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java index e97924672..f38c140db 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProcedure.java @@ -3,7 +3,7 @@ package dk.camelot64.kickc.model.types; import java.util.Objects; /** A function returning another type */ -public class SymbolTypeProcedure implements SymbolTypeSimple { +public class SymbolTypeProcedure implements SymbolType { private SymbolType returnType; @@ -40,7 +40,6 @@ public class SymbolTypeProcedure implements SymbolTypeSimple { @Override public int hashCode() { - return Objects.hash(returnType); } } diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java index 489f81cc8..186ba98b5 100644 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeProgram.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.model.types; /** A program */ -public class SymbolTypeProgram implements SymbolTypeSimple { +public class SymbolTypeProgram implements SymbolType { public SymbolTypeProgram() { diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeSimple.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeSimple.java deleted file mode 100644 index ea306056a..000000000 --- a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeSimple.java +++ /dev/null @@ -1,5 +0,0 @@ -package dk.camelot64.kickc.model.types; - -/** Marker interface for simple symbol types - ie. not a multi-type */ -public interface SymbolTypeSimple extends SymbolType { -} diff --git a/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java new file mode 100644 index 000000000..bc6cb3082 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/types/SymbolTypeStruct.java @@ -0,0 +1,59 @@ +package dk.camelot64.kickc.model.types; + +import dk.camelot64.kickc.model.symbols.StructDefinition; +import dk.camelot64.kickc.model.symbols.Variable; + +import java.util.Objects; + +/** A struct */ +public class SymbolTypeStruct implements SymbolType { + + /** Name of the struct type. */ + private String name; + + /** Size of the struct in bytes. */ + private int sizeBytes; + + public SymbolTypeStruct(StructDefinition structDefinition) { + this.name = structDefinition.getLocalName(); + int sizeBytes = 0; + for(Variable member : structDefinition.getAllVariables(false)) { + sizeBytes += member.getType().getSizeBytes(); + } + this.sizeBytes = sizeBytes; + } + + @Override + public String getTypeName() { + return "struct " + name; + } + + public String getStructTypeName() { + return name; + } + + @Override + public int getSizeBytes() { + return sizeBytes; + } + + @Override + public boolean equals(Object o) { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + SymbolTypeStruct that = (SymbolTypeStruct) o; + return sizeBytes == that.sizeBytes && + Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name, sizeBytes); + } + + @Override + public String toString() { + return getTypeName(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/values/AssignmentRValue.java b/src/main/java/dk/camelot64/kickc/model/values/AssignmentRValue.java new file mode 100644 index 000000000..36cb5d6ea --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/values/AssignmentRValue.java @@ -0,0 +1,28 @@ +package dk.camelot64.kickc.model.values; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.StatementAssignment; + +/** The "total" RValue of an assignment. */ +public class AssignmentRValue implements RValue { + + private StatementAssignment assignment; + + public AssignmentRValue(StatementAssignment assignment) { + this.assignment = assignment; + } + + public StatementAssignment getAssignment() { + return assignment; + } + + @Override + public String toString(Program program) { + return + (assignment.getrValue1() == null ? "" : assignment.getrValue1().toString(program) + " ") + + (assignment.getOperator() == null ? "" : assignment.getOperator() + " ") + + assignment.getrValue2().toString(program) + ; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantBinary.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantBinary.java index e15ed558a..90896ad5e 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantBinary.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantBinary.java @@ -50,12 +50,18 @@ public class ConstantBinary implements ConstantValue { @Override public ConstantLiteral calculateLiteral(ProgramScope scope) { - return operator.calculateLiteral(left.calculateLiteral(scope), right.calculateLiteral(scope)); + ConstantLiteral literal = operator.calculateLiteral(left.calculateLiteral(scope), right.calculateLiteral(scope)); + if(literal instanceof ConstantInteger && SymbolType.NUMBER.equals(literal.getType(scope))) { + ((ConstantInteger) literal).setType(getType(scope)); + } + return literal; } @Override public SymbolType getType(ProgramScope scope) { - return SymbolTypeInference.inferType(scope, left, operator, right); + SymbolType leftType = SymbolTypeInference.inferType(scope, left); + SymbolType rightType = SymbolTypeInference.inferType(scope, right); + return operator.inferType(leftType, rightType); } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java index c56e01657..7eccd45a4 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantInteger.java @@ -1,21 +1,30 @@ package dk.camelot64.kickc.model.values; import dk.camelot64.kickc.fragment.AsmFormat; -import dk.camelot64.kickc.model.*; +import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeMulti; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; -import java.util.ArrayList; - -/** SSA form constant integer value */ +/** Constant integer value */ public class ConstantInteger implements ConstantEnumerable { private Long number; - public ConstantInteger( Long number) { + /** The type of the number. (Either fixed size og the "number" type) */ + private SymbolType type; + + public ConstantInteger(Long number) { this.number = number; + this.type = SymbolType.NUMBER; + } + + public ConstantInteger(Long number, SymbolType type) { + this.number = number; + if(type != null) { + this.type = type; + } else { + this.type = SymbolType.NUMBER; + } } @Override @@ -32,14 +41,11 @@ public class ConstantInteger implements ConstantEnumerable { } public SymbolType getType() { - ArrayList potentialTypes = new ArrayList<>(); - Long number = getValue(); - for(SymbolTypeInteger typeInteger : SymbolType.getIntegerTypes()) { - if(number >= typeInteger.getMinValue() && number <= typeInteger.getMaxValue()) { - potentialTypes.add(typeInteger); - } - } - return new SymbolTypeMulti(potentialTypes); + return type; + } + + public void setType(SymbolType type) { + this.type = type; } @Override @@ -68,4 +74,5 @@ public class ConstantInteger implements ConstantEnumerable { public int hashCode() { return number != null ? number.hashCode() : 0; } + } diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantPointer.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantPointer.java index 452f3331c..dd8bf3940 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantPointer.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantPointer.java @@ -5,7 +5,7 @@ import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; -/** Constant pointer (meaning it points to a constant location)*/ +/** Constant pointer (meaning it points to a constant location) */ public class ConstantPointer implements ConstantEnumerable { /** The memory location pointed to. */ @@ -52,11 +52,7 @@ public class ConstantPointer implements ConstantEnumerable { @Override public String toString(Program program) { - if(program == null) { - return Long.toString(location); - } else { - return "(" + getType(program.getScope()).getTypeName() + ") " + Long.toString(location); - } + return "(" + getType().getTypeName() + ") " + Long.toString(location); } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java index 4474cb416..4f7c079a9 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantSymbolPointer.java @@ -6,6 +6,8 @@ import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypePointer; +import java.util.Objects; + /** A pointer to a symbol (variable or procedure) */ public class ConstantSymbolPointer implements ConstantValue { @@ -44,4 +46,18 @@ public class ConstantSymbolPointer implements ConstantValue { public String toString() { return toString(null); } + + @Override + public boolean equals(Object o) { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + ConstantSymbolPointer that = (ConstantSymbolPointer) o; + return Objects.equals(toSymbol, that.toSymbol); + } + + @Override + public int hashCode() { + + return Objects.hash(toSymbol); + } } diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantUnary.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantUnary.java index 80fc32871..d6ca0a7f9 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantUnary.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantUnary.java @@ -38,12 +38,17 @@ public class ConstantUnary implements ConstantValue { @Override public ConstantLiteral calculateLiteral(ProgramScope scope) { - return operator.calculateLiteral(operand.calculateLiteral(scope), scope); + ConstantLiteral literal = operator.calculateLiteral(operand.calculateLiteral(scope), scope); + if(literal instanceof ConstantInteger && SymbolType.NUMBER.equals(literal.getType(scope))) { + ((ConstantInteger) literal).setType(getType(scope)); + } + return literal; } @Override public SymbolType getType(ProgramScope scope) { - return SymbolTypeInference.inferType(scope, operator, operand); + SymbolType valueType = SymbolTypeInference.inferType(scope, operand); + return operator.inferType(valueType); } @Override diff --git a/src/main/java/dk/camelot64/kickc/model/values/StructMemberRef.java b/src/main/java/dk/camelot64/kickc/model/values/StructMemberRef.java new file mode 100644 index 000000000..a171bf582 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/values/StructMemberRef.java @@ -0,0 +1,45 @@ +package dk.camelot64.kickc.model.values; + +import dk.camelot64.kickc.model.Program; + +/** A reference to a struct member */ +public class StructMemberRef implements LValue { + + /** Expression evaluating to a struct. */ + private RValue struct; + + /** Name of the referenced member. */ + private String memberName; + + public StructMemberRef(RValue struct, String memberName) { + this.struct = struct; + this.memberName = memberName; + } + + public RValue getStruct() { + return struct; + } + + public void setStruct(RValue struct) { + this.struct = struct; + } + + public String getMemberName() { + return memberName; + } + + public void setMemberName(String memberName) { + this.memberName = memberName; + } + + @Override + public String toString() { + return toString(null); + } + + @Override + public String toString(Program program) { + return struct.toString(program) + "." + memberName ; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/values/StructZero.java b/src/main/java/dk/camelot64/kickc/model/values/StructZero.java new file mode 100644 index 000000000..9d6798d6e --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/values/StructZero.java @@ -0,0 +1,25 @@ +package dk.camelot64.kickc.model.values; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.types.SymbolTypeStruct; + +/** + * An zero-filled struct. + */ +public class StructZero implements RValue { + + private SymbolTypeStruct typeStruct; + + public StructZero(SymbolTypeStruct typeStruct) { + this.typeStruct = typeStruct; + } + + public SymbolTypeStruct getTypeStruct() { + return typeStruct; + } + + @Override + public String toString(Program program) { + return "{}"; + } +} diff --git a/src/main/java/dk/camelot64/kickc/model/values/ValueList.java b/src/main/java/dk/camelot64/kickc/model/values/ValueList.java index fd704486a..a81adb58a 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ValueList.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ValueList.java @@ -38,4 +38,8 @@ public class ValueList implements RValue { return out.toString(); } + @Override + public String toString() { + return toString(null); + } } diff --git a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 index dbc6688a9..a604ccb24 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickC.g4 +++ b/src/main/java/dk/camelot64/kickc/parser/KickC.g4 @@ -23,6 +23,7 @@ declSeq decl : declVariables ';' + | structDef ';' | declFunction | declKasm | globalDirective @@ -112,6 +113,20 @@ typeDecl | typeDecl '*' #typePtr | typeDecl '[' (expr)? ']' #typeArray | typeDecl '(' ')' #typeProcedure + | structDef #typeStructDef + | structRef #typeStructRef + ; + +structRef + : 'struct' NAME + ; + +structDef + : 'struct' NAME? '{' structMembers+ '}' + ; + +structMembers + : declVariables ';' ; commaExpr @@ -121,6 +136,8 @@ commaExpr expr : '(' commaExpr ')' #exprPar + | expr '.' NAME #exprDot + | expr '->' NAME #exprArrow | expr '(' parameterList? ')' #exprCall | 'sizeof' '(' ( typeDecl | expr ) ')' #exprSizeOf | 'typeid' '(' ( typeDecl | expr ) ')' #exprTypeId @@ -146,7 +163,7 @@ expr | '{' expr (',' expr )* '}' #initList | NAME #exprId | NUMBER #exprNumber - | STRING #exprString + | STRING+ #exprString | CHAR #exprChar | BOOLEAN #exprBool ; @@ -236,7 +253,7 @@ NUMFLOAT : BINFLOAT | DECFLOAT | HEXFLOAT; BINFLOAT : ('%' | '0b' | '0B' ) (BINDIGIT)* '.' BINDIGIT+; DECFLOAT : (DECDIGIT)* '.' DECDIGIT+; HEXFLOAT : ('$' | '0x' | '0X' ) (HEXDIGIT)* '.' HEXDIGIT+; -NUMINT : DECINTEGER | HEXINTEGER | BININTEGER ; +NUMINT : (DECINTEGER | HEXINTEGER | BININTEGER ) ([us][bcwisdl] | 'l')? ; BININTEGER : '0' [bB] BINDIGIT+ | '%' BINDIGIT+ ; DECINTEGER : DECDIGIT+ ; HEXINTEGER : ( '$' | '0x' | '0X' ) HEXDIGIT+ ; diff --git a/src/main/java/dk/camelot64/kickc/parser/KickC.tokens b/src/main/java/dk/camelot64/kickc/parser/KickC.tokens index c69744d23..42dfa728a 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickC.tokens +++ b/src/main/java/dk/camelot64/kickc/parser/KickC.tokens @@ -74,26 +74,28 @@ T__72=73 T__73=74 T__74=75 T__75=76 -MNEMONIC=77 -KICKASM=78 -SIMPLETYPE=79 -STRING=80 -CHAR=81 -BOOLEAN=82 -NUMBER=83 -NUMFLOAT=84 -BINFLOAT=85 -DECFLOAT=86 -HEXFLOAT=87 -NUMINT=88 -BININTEGER=89 -DECINTEGER=90 -HEXINTEGER=91 -NAME=92 -ASMREL=93 -WS=94 -COMMENT_LINE=95 -COMMENT_BLOCK=96 +T__76=77 +T__77=78 +MNEMONIC=79 +KICKASM=80 +SIMPLETYPE=81 +STRING=82 +CHAR=83 +BOOLEAN=84 +NUMBER=85 +NUMFLOAT=86 +BINFLOAT=87 +DECFLOAT=88 +HEXFLOAT=89 +NUMINT=90 +BININTEGER=91 +DECINTEGER=92 +HEXINTEGER=93 +NAME=94 +ASMREL=95 +WS=96 +COMMENT_LINE=97 +COMMENT_BLOCK=98 'import'=1 ';'=2 ','=3 @@ -126,47 +128,49 @@ COMMENT_BLOCK=96 '*'=30 '['=31 ']'=32 -'sizeof'=33 -'typeid'=34 -'--'=35 -'++'=36 -'+'=37 -'-'=38 -'!'=39 -'&'=40 -'~'=41 -'>>'=42 -'<<'=43 -'/'=44 -'%'=45 -'<'=46 -'>'=47 -'=='=48 -'!='=49 -'<='=50 -'>='=51 -'^'=52 -'|'=53 -'&&'=54 -'||'=55 -'?'=56 -'+='=57 -'-='=58 -'*='=59 -'/='=60 -'%='=61 -'<<='=62 -'>>='=63 -'&='=64 -'|='=65 -'^='=66 -'kickasm'=67 -'resource'=68 -'uses'=69 -'clobbers'=70 -'bytes'=71 -'cycles'=72 -'pc'=73 -'.byte'=74 -'#'=75 -'.'=76 +'struct'=33 +'.'=34 +'->'=35 +'sizeof'=36 +'typeid'=37 +'--'=38 +'++'=39 +'+'=40 +'-'=41 +'!'=42 +'&'=43 +'~'=44 +'>>'=45 +'<<'=46 +'/'=47 +'%'=48 +'<'=49 +'>'=50 +'=='=51 +'!='=52 +'<='=53 +'>='=54 +'^'=55 +'|'=56 +'&&'=57 +'||'=58 +'?'=59 +'+='=60 +'-='=61 +'*='=62 +'/='=63 +'%='=64 +'<<='=65 +'>>='=66 +'&='=67 +'|='=68 +'^='=69 +'kickasm'=70 +'resource'=71 +'uses'=72 +'clobbers'=73 +'bytes'=74 +'cycles'=75 +'pc'=76 +'.byte'=77 +'#'=78 diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCBaseListener.java b/src/main/java/dk/camelot64/kickc/parser/KickCBaseListener.java index 64996623d..ba4d3501e 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCBaseListener.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCBaseListener.java @@ -1,4 +1,4 @@ -// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7 +// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7 package dk.camelot64.kickc.parser; import org.antlr.v4.runtime.ParserRuleContext; @@ -551,6 +551,18 @@ public class KickCBaseListener implements KickCListener { *

The default implementation does nothing.

*/ @Override public void exitTypeArray(KickCParser.TypeArrayContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeStructRef(KickCParser.TypeStructRefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeStructRef(KickCParser.TypeStructRefContext ctx) { } /** * {@inheritDoc} * @@ -563,6 +575,18 @@ public class KickCBaseListener implements KickCListener { *

The default implementation does nothing.

*/ @Override public void exitTypeSimple(KickCParser.TypeSimpleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeStructDef(KickCParser.TypeStructDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeStructDef(KickCParser.TypeStructDefContext ctx) { } /** * {@inheritDoc} * @@ -575,6 +599,42 @@ public class KickCBaseListener implements KickCListener { *

The default implementation does nothing.

*/ @Override public void exitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStructRef(KickCParser.StructRefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStructRef(KickCParser.StructRefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStructDef(KickCParser.StructDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStructDef(KickCParser.StructDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStructMembers(KickCParser.StructMembersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStructMembers(KickCParser.StructMembersContext ctx) { } /** * {@inheritDoc} * @@ -695,6 +755,30 @@ public class KickCBaseListener implements KickCListener { *

The default implementation does nothing.

*/ @Override public void exitExprChar(KickCParser.ExprCharContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprArrow(KickCParser.ExprArrowContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprArrow(KickCParser.ExprArrowContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprDot(KickCParser.ExprDotContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprDot(KickCParser.ExprDotContext ctx) { } /** * {@inheritDoc} * diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCBaseVisitor.java b/src/main/java/dk/camelot64/kickc/parser/KickCBaseVisitor.java index 984232061..111fc9a36 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCBaseVisitor.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCBaseVisitor.java @@ -1,4 +1,4 @@ -// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7 +// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7 package dk.camelot64.kickc.parser; import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; @@ -326,6 +326,13 @@ public class KickCBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitTypeArray(KickCParser.TypeArrayContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTypeStructRef(KickCParser.TypeStructRefContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * @@ -333,6 +340,13 @@ public class KickCBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitTypeSimple(KickCParser.TypeSimpleContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitTypeStructDef(KickCParser.TypeStructDefContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * @@ -340,6 +354,27 @@ public class KickCBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStructRef(KickCParser.StructRefContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStructDef(KickCParser.StructDefContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitStructMembers(KickCParser.StructMembersContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * @@ -410,6 +445,20 @@ public class KickCBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitExprChar(KickCParser.ExprCharContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprArrow(KickCParser.ExprArrowContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitExprDot(KickCParser.ExprDotContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java index c628f18ce..c8c2c2b66 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.java @@ -1,4 +1,4 @@ -// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7 +// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7 package dk.camelot64.kickc.parser; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.CharStream; @@ -27,10 +27,10 @@ public class KickCLexer extends Lexer { T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59, T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66, T__66=67, T__67=68, T__68=69, T__69=70, T__70=71, T__71=72, T__72=73, - T__73=74, T__74=75, T__75=76, MNEMONIC=77, KICKASM=78, SIMPLETYPE=79, - STRING=80, CHAR=81, BOOLEAN=82, NUMBER=83, NUMFLOAT=84, BINFLOAT=85, DECFLOAT=86, - HEXFLOAT=87, NUMINT=88, BININTEGER=89, DECINTEGER=90, HEXINTEGER=91, NAME=92, - ASMREL=93, WS=94, COMMENT_LINE=95, COMMENT_BLOCK=96; + T__73=74, T__74=75, T__75=76, T__76=77, T__77=78, MNEMONIC=79, KICKASM=80, + SIMPLETYPE=81, STRING=82, CHAR=83, BOOLEAN=84, NUMBER=85, NUMFLOAT=86, + BINFLOAT=87, DECFLOAT=88, HEXFLOAT=89, NUMINT=90, BININTEGER=91, DECINTEGER=92, + HEXINTEGER=93, NAME=94, ASMREL=95, WS=96, COMMENT_LINE=97, COMMENT_BLOCK=98; public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -49,11 +49,11 @@ public class KickCLexer extends Lexer { "T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56", "T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64", "T__65", "T__66", "T__67", "T__68", "T__69", "T__70", "T__71", "T__72", - "T__73", "T__74", "T__75", "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", - "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", - "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "BINDIGIT", "DECDIGIT", - "HEXDIGIT", "NAME", "NAME_START", "NAME_CHAR", "ASMREL", "WS", "COMMENT_LINE", - "COMMENT_BLOCK" + "T__73", "T__74", "T__75", "T__76", "T__77", "MNEMONIC", "KICKASM", "SIMPLETYPE", + "STRING", "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", + "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "BINDIGIT", + "DECDIGIT", "HEXDIGIT", "NAME", "NAME_START", "NAME_CHAR", "ASMREL", "WS", + "COMMENT_LINE", "COMMENT_BLOCK" }; private static final String[] _LITERAL_NAMES = { @@ -61,12 +61,12 @@ public class KickCLexer extends Lexer { "'extern'", "'align'", "'register'", "'inline'", "'volatile'", "'interrupt'", "'reserve'", "'if'", "'else'", "'while'", "'do'", "'for'", "'return'", "'break'", "'continue'", "'asm'", "':'", "'..'", "'signed'", "'unsigned'", - "'*'", "'['", "']'", "'sizeof'", "'typeid'", "'--'", "'++'", "'+'", "'-'", - "'!'", "'&'", "'~'", "'>>'", "'<<'", "'/'", "'%'", "'<'", "'>'", "'=='", - "'!='", "'<='", "'>='", "'^'", "'|'", "'&&'", "'||'", "'?'", "'+='", "'-='", - "'*='", "'/='", "'%='", "'<<='", "'>>='", "'&='", "'|='", "'^='", "'kickasm'", - "'resource'", "'uses'", "'clobbers'", "'bytes'", "'cycles'", "'pc'", "'.byte'", - "'#'", "'.'" + "'*'", "'['", "']'", "'struct'", "'.'", "'->'", "'sizeof'", "'typeid'", + "'--'", "'++'", "'+'", "'-'", "'!'", "'&'", "'~'", "'>>'", "'<<'", "'/'", + "'%'", "'<'", "'>'", "'=='", "'!='", "'<='", "'>='", "'^'", "'|'", "'&&'", + "'||'", "'?'", "'+='", "'-='", "'*='", "'/='", "'%='", "'<<='", "'>>='", + "'&='", "'|='", "'^='", "'kickasm'", "'resource'", "'uses'", "'clobbers'", + "'bytes'", "'cycles'", "'pc'", "'.byte'", "'#'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -75,10 +75,10 @@ public class KickCLexer extends Lexer { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", - "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", - "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "ASMREL", - "WS", "COMMENT_LINE", "COMMENT_BLOCK" + null, null, null, null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE", + "STRING", "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", + "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", + "ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -138,7 +138,7 @@ public class KickCLexer extends Lexer { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2b\u03d7\b\1\4\2\t"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2d\u03ea\b\1\4\2\t"+ "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ @@ -149,348 +149,355 @@ public class KickCLexer extends Lexer { "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+ "\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+ "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+ - "`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+ - "\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n"+ - "\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3"+ - "\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16"+ - "\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20"+ - "\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22"+ - "\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25"+ - "\3\25\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30"+ - "\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+ - "\3\32\3\32\3\32\3\32\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\35"+ - "\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3 \3"+ - " \3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3%\3"+ - "%\3%\3&\3&\3\'\3\'\3(\3(\3)\3)\3*\3*\3+\3+\3+\3,\3,\3,\3-\3-\3.\3.\3/"+ - "\3/\3\60\3\60\3\61\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3"+ - "\64\3\65\3\65\3\66\3\66\3\67\3\67\3\67\38\38\38\39\39\3:\3:\3:\3;\3;\3"+ - ";\3<\3<\3<\3=\3=\3=\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3@\3A\3A\3A\3B\3B\3"+ - "B\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F\3"+ - "F\3F\3F\3G\3G\3G\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3"+ - "I\3I\3J\3J\3J\3K\3K\3K\3K\3K\3K\3L\3L\3M\3M\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3N\3N\3N\3N\3N\3N\5N\u02e6\nN\3O\3O\3O\3O\7O\u02ec\nO\fO\16O\u02ef\13"+ - "O\3O\3O\3O\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3"+ - "P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\5P\u0319\nP\3Q\3"+ - "Q\3Q\3Q\7Q\u031f\nQ\fQ\16Q\u0322\13Q\3Q\3Q\5Q\u0326\nQ\3R\3R\3R\3R\5R"+ - "\u032c\nR\3R\3R\3S\3S\3S\3S\3S\3S\3S\3S\3S\5S\u0339\nS\3T\3T\5T\u033d"+ - "\nT\3U\3U\3U\5U\u0342\nU\3V\3V\3V\3V\3V\5V\u0349\nV\3V\7V\u034c\nV\fV"+ - "\16V\u034f\13V\3V\3V\6V\u0353\nV\rV\16V\u0354\3W\7W\u0358\nW\fW\16W\u035b"+ - "\13W\3W\3W\6W\u035f\nW\rW\16W\u0360\3X\3X\3X\3X\3X\5X\u0368\nX\3X\7X\u036b"+ - "\nX\fX\16X\u036e\13X\3X\3X\6X\u0372\nX\rX\16X\u0373\3Y\3Y\3Y\5Y\u0379"+ - "\nY\3Z\3Z\3Z\6Z\u037e\nZ\rZ\16Z\u037f\3Z\3Z\6Z\u0384\nZ\rZ\16Z\u0385\5"+ - "Z\u0388\nZ\3[\6[\u038b\n[\r[\16[\u038c\3\\\3\\\3\\\3\\\3\\\5\\\u0394\n"+ - "\\\3\\\6\\\u0397\n\\\r\\\16\\\u0398\3]\3]\3^\3^\3_\3_\3`\3`\7`\u03a3\n"+ - "`\f`\16`\u03a6\13`\3a\3a\3b\3b\3c\3c\7c\u03ae\nc\fc\16c\u03b1\13c\3c\6"+ - "c\u03b4\nc\rc\16c\u03b5\3d\6d\u03b9\nd\rd\16d\u03ba\3d\3d\3e\3e\3e\3e"+ - "\7e\u03c3\ne\fe\16e\u03c6\13e\3e\3e\3f\3f\3f\3f\7f\u03ce\nf\ff\16f\u03d1"+ - "\13f\3f\3f\3f\3f\3f\4\u02ed\u03cf\2g\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21"+ - "\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30"+ - "/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.["+ - "/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u{?}@\177A\u0081B\u0083"+ - "C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097"+ - "M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00ab"+ - "W\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9\2\u00bb\2\u00bd\2\u00bf"+ - "^\u00c1\2\u00c3\2\u00c5_\u00c7`\u00c9a\u00cbb\3\2\r\3\2$$\3\2))\4\2DD"+ - "dd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\aac|\6\2\62;C\\aac|\4\2--//\6\2"+ - "\13\f\17\17\"\"\u00a2\u00a2\4\2\f\f\17\17\2\u0444\2\3\3\2\2\2\2\5\3\2"+ - "\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21"+ - "\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2"+ - "\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3"+ - "\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3"+ - "\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3"+ - "\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2"+ - "\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2"+ - "Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3"+ - "\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2"+ - "\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2"+ - "\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3"+ - "\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2"+ - "\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099"+ - "\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2"+ - "\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab"+ - "\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2"+ - "\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00bf\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7"+ - "\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\3\u00cd\3\2\2\2\5\u00d4\3\2\2"+ - "\2\7\u00d6\3\2\2\2\t\u00d8\3\2\2\2\13\u00da\3\2\2\2\r\u00dc\3\2\2\2\17"+ - "\u00de\3\2\2\2\21\u00e0\3\2\2\2\23\u00e2\3\2\2\2\25\u00e8\3\2\2\2\27\u00ef"+ - "\3\2\2\2\31\u00f5\3\2\2\2\33\u00fe\3\2\2\2\35\u0105\3\2\2\2\37\u010e\3"+ - "\2\2\2!\u0118\3\2\2\2#\u0120\3\2\2\2%\u0123\3\2\2\2\'\u0128\3\2\2\2)\u012e"+ - "\3\2\2\2+\u0131\3\2\2\2-\u0135\3\2\2\2/\u013c\3\2\2\2\61\u0142\3\2\2\2"+ - "\63\u014b\3\2\2\2\65\u014f\3\2\2\2\67\u0151\3\2\2\29\u0154\3\2\2\2;\u015b"+ - "\3\2\2\2=\u0164\3\2\2\2?\u0166\3\2\2\2A\u0168\3\2\2\2C\u016a\3\2\2\2E"+ - "\u0171\3\2\2\2G\u0178\3\2\2\2I\u017b\3\2\2\2K\u017e\3\2\2\2M\u0180\3\2"+ - "\2\2O\u0182\3\2\2\2Q\u0184\3\2\2\2S\u0186\3\2\2\2U\u0188\3\2\2\2W\u018b"+ - "\3\2\2\2Y\u018e\3\2\2\2[\u0190\3\2\2\2]\u0192\3\2\2\2_\u0194\3\2\2\2a"+ - "\u0196\3\2\2\2c\u0199\3\2\2\2e\u019c\3\2\2\2g\u019f\3\2\2\2i\u01a2\3\2"+ - "\2\2k\u01a4\3\2\2\2m\u01a6\3\2\2\2o\u01a9\3\2\2\2q\u01ac\3\2\2\2s\u01ae"+ - "\3\2\2\2u\u01b1\3\2\2\2w\u01b4\3\2\2\2y\u01b7\3\2\2\2{\u01ba\3\2\2\2}"+ - "\u01bd\3\2\2\2\177\u01c1\3\2\2\2\u0081\u01c5\3\2\2\2\u0083\u01c8\3\2\2"+ - "\2\u0085\u01cb\3\2\2\2\u0087\u01ce\3\2\2\2\u0089\u01d6\3\2\2\2\u008b\u01df"+ - "\3\2\2\2\u008d\u01e4\3\2\2\2\u008f\u01ed\3\2\2\2\u0091\u01f3\3\2\2\2\u0093"+ - "\u01fa\3\2\2\2\u0095\u01fd\3\2\2\2\u0097\u0203\3\2\2\2\u0099\u0205\3\2"+ - "\2\2\u009b\u02e5\3\2\2\2\u009d\u02e7\3\2\2\2\u009f\u0318\3\2\2\2\u00a1"+ - "\u031a\3\2\2\2\u00a3\u0327\3\2\2\2\u00a5\u0338\3\2\2\2\u00a7\u033c\3\2"+ - "\2\2\u00a9\u0341\3\2\2\2\u00ab\u0348\3\2\2\2\u00ad\u0359\3\2\2\2\u00af"+ - "\u0367\3\2\2\2\u00b1\u0378\3\2\2\2\u00b3\u0387\3\2\2\2\u00b5\u038a\3\2"+ - "\2\2\u00b7\u0393\3\2\2\2\u00b9\u039a\3\2\2\2\u00bb\u039c\3\2\2\2\u00bd"+ - "\u039e\3\2\2\2\u00bf\u03a0\3\2\2\2\u00c1\u03a7\3\2\2\2\u00c3\u03a9\3\2"+ - "\2\2\u00c5\u03ab\3\2\2\2\u00c7\u03b8\3\2\2\2\u00c9\u03be\3\2\2\2\u00cb"+ - "\u03c9\3\2\2\2\u00cd\u00ce\7k\2\2\u00ce\u00cf\7o\2\2\u00cf\u00d0\7r\2"+ - "\2\u00d0\u00d1\7q\2\2\u00d1\u00d2\7t\2\2\u00d2\u00d3\7v\2\2\u00d3\4\3"+ - "\2\2\2\u00d4\u00d5\7=\2\2\u00d5\6\3\2\2\2\u00d6\u00d7\7.\2\2\u00d7\b\3"+ - "\2\2\2\u00d8\u00d9\7?\2\2\u00d9\n\3\2\2\2\u00da\u00db\7*\2\2\u00db\f\3"+ - "\2\2\2\u00dc\u00dd\7+\2\2\u00dd\16\3\2\2\2\u00de\u00df\7}\2\2\u00df\20"+ - "\3\2\2\2\u00e0\u00e1\7\177\2\2\u00e1\22\3\2\2\2\u00e2\u00e3\7e\2\2\u00e3"+ - "\u00e4\7q\2\2\u00e4\u00e5\7p\2\2\u00e5\u00e6\7u\2\2\u00e6\u00e7\7v\2\2"+ - "\u00e7\24\3\2\2\2\u00e8\u00e9\7g\2\2\u00e9\u00ea\7z\2\2\u00ea\u00eb\7"+ - "v\2\2\u00eb\u00ec\7g\2\2\u00ec\u00ed\7t\2\2\u00ed\u00ee\7p\2\2\u00ee\26"+ - "\3\2\2\2\u00ef\u00f0\7c\2\2\u00f0\u00f1\7n\2\2\u00f1\u00f2\7k\2\2\u00f2"+ - "\u00f3\7i\2\2\u00f3\u00f4\7p\2\2\u00f4\30\3\2\2\2\u00f5\u00f6\7t\2\2\u00f6"+ - "\u00f7\7g\2\2\u00f7\u00f8\7i\2\2\u00f8\u00f9\7k\2\2\u00f9\u00fa\7u\2\2"+ - "\u00fa\u00fb\7v\2\2\u00fb\u00fc\7g\2\2\u00fc\u00fd\7t\2\2\u00fd\32\3\2"+ - "\2\2\u00fe\u00ff\7k\2\2\u00ff\u0100\7p\2\2\u0100\u0101\7n\2\2\u0101\u0102"+ - "\7k\2\2\u0102\u0103\7p\2\2\u0103\u0104\7g\2\2\u0104\34\3\2\2\2\u0105\u0106"+ - "\7x\2\2\u0106\u0107\7q\2\2\u0107\u0108\7n\2\2\u0108\u0109\7c\2\2\u0109"+ - "\u010a\7v\2\2\u010a\u010b\7k\2\2\u010b\u010c\7n\2\2\u010c\u010d\7g\2\2"+ - "\u010d\36\3\2\2\2\u010e\u010f\7k\2\2\u010f\u0110\7p\2\2\u0110\u0111\7"+ - "v\2\2\u0111\u0112\7g\2\2\u0112\u0113\7t\2\2\u0113\u0114\7t\2\2\u0114\u0115"+ - "\7w\2\2\u0115\u0116\7r\2\2\u0116\u0117\7v\2\2\u0117 \3\2\2\2\u0118\u0119"+ - "\7t\2\2\u0119\u011a\7g\2\2\u011a\u011b\7u\2\2\u011b\u011c\7g\2\2\u011c"+ - "\u011d\7t\2\2\u011d\u011e\7x\2\2\u011e\u011f\7g\2\2\u011f\"\3\2\2\2\u0120"+ - "\u0121\7k\2\2\u0121\u0122\7h\2\2\u0122$\3\2\2\2\u0123\u0124\7g\2\2\u0124"+ - "\u0125\7n\2\2\u0125\u0126\7u\2\2\u0126\u0127\7g\2\2\u0127&\3\2\2\2\u0128"+ - "\u0129\7y\2\2\u0129\u012a\7j\2\2\u012a\u012b\7k\2\2\u012b\u012c\7n\2\2"+ - "\u012c\u012d\7g\2\2\u012d(\3\2\2\2\u012e\u012f\7f\2\2\u012f\u0130\7q\2"+ - "\2\u0130*\3\2\2\2\u0131\u0132\7h\2\2\u0132\u0133\7q\2\2\u0133\u0134\7"+ - "t\2\2\u0134,\3\2\2\2\u0135\u0136\7t\2\2\u0136\u0137\7g\2\2\u0137\u0138"+ - "\7v\2\2\u0138\u0139\7w\2\2\u0139\u013a\7t\2\2\u013a\u013b\7p\2\2\u013b"+ - ".\3\2\2\2\u013c\u013d\7d\2\2\u013d\u013e\7t\2\2\u013e\u013f\7g\2\2\u013f"+ - "\u0140\7c\2\2\u0140\u0141\7m\2\2\u0141\60\3\2\2\2\u0142\u0143\7e\2\2\u0143"+ - "\u0144\7q\2\2\u0144\u0145\7p\2\2\u0145\u0146\7v\2\2\u0146\u0147\7k\2\2"+ - "\u0147\u0148\7p\2\2\u0148\u0149\7w\2\2\u0149\u014a\7g\2\2\u014a\62\3\2"+ - "\2\2\u014b\u014c\7c\2\2\u014c\u014d\7u\2\2\u014d\u014e\7o\2\2\u014e\64"+ - "\3\2\2\2\u014f\u0150\7<\2\2\u0150\66\3\2\2\2\u0151\u0152\7\60\2\2\u0152"+ - "\u0153\7\60\2\2\u01538\3\2\2\2\u0154\u0155\7u\2\2\u0155\u0156\7k\2\2\u0156"+ - "\u0157\7i\2\2\u0157\u0158\7p\2\2\u0158\u0159\7g\2\2\u0159\u015a\7f\2\2"+ - "\u015a:\3\2\2\2\u015b\u015c\7w\2\2\u015c\u015d\7p\2\2\u015d\u015e\7u\2"+ - "\2\u015e\u015f\7k\2\2\u015f\u0160\7i\2\2\u0160\u0161\7p\2\2\u0161\u0162"+ - "\7g\2\2\u0162\u0163\7f\2\2\u0163<\3\2\2\2\u0164\u0165\7,\2\2\u0165>\3"+ - "\2\2\2\u0166\u0167\7]\2\2\u0167@\3\2\2\2\u0168\u0169\7_\2\2\u0169B\3\2"+ - "\2\2\u016a\u016b\7u\2\2\u016b\u016c\7k\2\2\u016c\u016d\7|\2\2\u016d\u016e"+ - "\7g\2\2\u016e\u016f\7q\2\2\u016f\u0170\7h\2\2\u0170D\3\2\2\2\u0171\u0172"+ - "\7v\2\2\u0172\u0173\7{\2\2\u0173\u0174\7r\2\2\u0174\u0175\7g\2\2\u0175"+ - "\u0176\7k\2\2\u0176\u0177\7f\2\2\u0177F\3\2\2\2\u0178\u0179\7/\2\2\u0179"+ - "\u017a\7/\2\2\u017aH\3\2\2\2\u017b\u017c\7-\2\2\u017c\u017d\7-\2\2\u017d"+ - "J\3\2\2\2\u017e\u017f\7-\2\2\u017fL\3\2\2\2\u0180\u0181\7/\2\2\u0181N"+ - "\3\2\2\2\u0182\u0183\7#\2\2\u0183P\3\2\2\2\u0184\u0185\7(\2\2\u0185R\3"+ - "\2\2\2\u0186\u0187\7\u0080\2\2\u0187T\3\2\2\2\u0188\u0189\7@\2\2\u0189"+ - "\u018a\7@\2\2\u018aV\3\2\2\2\u018b\u018c\7>\2\2\u018c\u018d\7>\2\2\u018d"+ - "X\3\2\2\2\u018e\u018f\7\61\2\2\u018fZ\3\2\2\2\u0190\u0191\7\'\2\2\u0191"+ - "\\\3\2\2\2\u0192\u0193\7>\2\2\u0193^\3\2\2\2\u0194\u0195\7@\2\2\u0195"+ - "`\3\2\2\2\u0196\u0197\7?\2\2\u0197\u0198\7?\2\2\u0198b\3\2\2\2\u0199\u019a"+ - "\7#\2\2\u019a\u019b\7?\2\2\u019bd\3\2\2\2\u019c\u019d\7>\2\2\u019d\u019e"+ - "\7?\2\2\u019ef\3\2\2\2\u019f\u01a0\7@\2\2\u01a0\u01a1\7?\2\2\u01a1h\3"+ - "\2\2\2\u01a2\u01a3\7`\2\2\u01a3j\3\2\2\2\u01a4\u01a5\7~\2\2\u01a5l\3\2"+ - "\2\2\u01a6\u01a7\7(\2\2\u01a7\u01a8\7(\2\2\u01a8n\3\2\2\2\u01a9\u01aa"+ - "\7~\2\2\u01aa\u01ab\7~\2\2\u01abp\3\2\2\2\u01ac\u01ad\7A\2\2\u01adr\3"+ - "\2\2\2\u01ae\u01af\7-\2\2\u01af\u01b0\7?\2\2\u01b0t\3\2\2\2\u01b1\u01b2"+ - "\7/\2\2\u01b2\u01b3\7?\2\2\u01b3v\3\2\2\2\u01b4\u01b5\7,\2\2\u01b5\u01b6"+ - "\7?\2\2\u01b6x\3\2\2\2\u01b7\u01b8\7\61\2\2\u01b8\u01b9\7?\2\2\u01b9z"+ - "\3\2\2\2\u01ba\u01bb\7\'\2\2\u01bb\u01bc\7?\2\2\u01bc|\3\2\2\2\u01bd\u01be"+ - "\7>\2\2\u01be\u01bf\7>\2\2\u01bf\u01c0\7?\2\2\u01c0~\3\2\2\2\u01c1\u01c2"+ - "\7@\2\2\u01c2\u01c3\7@\2\2\u01c3\u01c4\7?\2\2\u01c4\u0080\3\2\2\2\u01c5"+ - "\u01c6\7(\2\2\u01c6\u01c7\7?\2\2\u01c7\u0082\3\2\2\2\u01c8\u01c9\7~\2"+ - "\2\u01c9\u01ca\7?\2\2\u01ca\u0084\3\2\2\2\u01cb\u01cc\7`\2\2\u01cc\u01cd"+ - "\7?\2\2\u01cd\u0086\3\2\2\2\u01ce\u01cf\7m\2\2\u01cf\u01d0\7k\2\2\u01d0"+ - "\u01d1\7e\2\2\u01d1\u01d2\7m\2\2\u01d2\u01d3\7c\2\2\u01d3\u01d4\7u\2\2"+ - "\u01d4\u01d5\7o\2\2\u01d5\u0088\3\2\2\2\u01d6\u01d7\7t\2\2\u01d7\u01d8"+ - "\7g\2\2\u01d8\u01d9\7u\2\2\u01d9\u01da\7q\2\2\u01da\u01db\7w\2\2\u01db"+ - "\u01dc\7t\2\2\u01dc\u01dd\7e\2\2\u01dd\u01de\7g\2\2\u01de\u008a\3\2\2"+ - "\2\u01df\u01e0\7w\2\2\u01e0\u01e1\7u\2\2\u01e1\u01e2\7g\2\2\u01e2\u01e3"+ - "\7u\2\2\u01e3\u008c\3\2\2\2\u01e4\u01e5\7e\2\2\u01e5\u01e6\7n\2\2\u01e6"+ - "\u01e7\7q\2\2\u01e7\u01e8\7d\2\2\u01e8\u01e9\7d\2\2\u01e9\u01ea\7g\2\2"+ - "\u01ea\u01eb\7t\2\2\u01eb\u01ec\7u\2\2\u01ec\u008e\3\2\2\2\u01ed\u01ee"+ - "\7d\2\2\u01ee\u01ef\7{\2\2\u01ef\u01f0\7v\2\2\u01f0\u01f1\7g\2\2\u01f1"+ - "\u01f2\7u\2\2\u01f2\u0090\3\2\2\2\u01f3\u01f4\7e\2\2\u01f4\u01f5\7{\2"+ - "\2\u01f5\u01f6\7e\2\2\u01f6\u01f7\7n\2\2\u01f7\u01f8\7g\2\2\u01f8\u01f9"+ - "\7u\2\2\u01f9\u0092\3\2\2\2\u01fa\u01fb\7r\2\2\u01fb\u01fc\7e\2\2\u01fc"+ - "\u0094\3\2\2\2\u01fd\u01fe\7\60\2\2\u01fe\u01ff\7d\2\2\u01ff\u0200\7{"+ - "\2\2\u0200\u0201\7v\2\2\u0201\u0202\7g\2\2\u0202\u0096\3\2\2\2\u0203\u0204"+ - "\7%\2\2\u0204\u0098\3\2\2\2\u0205\u0206\7\60\2\2\u0206\u009a\3\2\2\2\u0207"+ - "\u0208\7d\2\2\u0208\u0209\7t\2\2\u0209\u02e6\7m\2\2\u020a\u020b\7q\2\2"+ - "\u020b\u020c\7t\2\2\u020c\u02e6\7c\2\2\u020d\u020e\7m\2\2\u020e\u020f"+ - "\7k\2\2\u020f\u02e6\7n\2\2\u0210\u0211\7u\2\2\u0211\u0212\7n\2\2\u0212"+ - "\u02e6\7q\2\2\u0213\u0214\7p\2\2\u0214\u0215\7q\2\2\u0215\u02e6\7r\2\2"+ - "\u0216\u0217\7c\2\2\u0217\u0218\7u\2\2\u0218\u02e6\7n\2\2\u0219\u021a"+ - "\7r\2\2\u021a\u021b\7j\2\2\u021b\u02e6\7r\2\2\u021c\u021d\7c\2\2\u021d"+ - "\u021e\7p\2\2\u021e\u02e6\7e\2\2\u021f\u0220\7d\2\2\u0220\u0221\7r\2\2"+ - "\u0221\u02e6\7n\2\2\u0222\u0223\7e\2\2\u0223\u0224\7n\2\2\u0224\u02e6"+ - "\7e\2\2\u0225\u0226\7l\2\2\u0226\u0227\7u\2\2\u0227\u02e6\7t\2\2\u0228"+ - "\u0229\7c\2\2\u0229\u022a\7p\2\2\u022a\u02e6\7f\2\2\u022b\u022c\7t\2\2"+ - "\u022c\u022d\7n\2\2\u022d\u02e6\7c\2\2\u022e\u022f\7d\2\2\u022f\u0230"+ - "\7k\2\2\u0230\u02e6\7v\2\2\u0231\u0232\7t\2\2\u0232\u0233\7q\2\2\u0233"+ - "\u02e6\7n\2\2\u0234\u0235\7r\2\2\u0235\u0236\7n\2\2\u0236\u02e6\7c\2\2"+ - "\u0237\u0238\7r\2\2\u0238\u0239\7n\2\2\u0239\u02e6\7r\2\2\u023a\u023b"+ - "\7d\2\2\u023b\u023c\7o\2\2\u023c\u02e6\7k\2\2\u023d\u023e\7u\2\2\u023e"+ - "\u023f\7g\2\2\u023f\u02e6\7e\2\2\u0240\u0241\7t\2\2\u0241\u0242\7v\2\2"+ - "\u0242\u02e6\7k\2\2\u0243\u0244\7g\2\2\u0244\u0245\7q\2\2\u0245\u02e6"+ - "\7t\2\2\u0246\u0247\7u\2\2\u0247\u0248\7t\2\2\u0248\u02e6\7g\2\2\u0249"+ - "\u024a\7n\2\2\u024a\u024b\7u\2\2\u024b\u02e6\7t\2\2\u024c\u024d\7r\2\2"+ - "\u024d\u024e\7j\2\2\u024e\u02e6\7c\2\2\u024f\u0250\7c\2\2\u0250\u0251"+ - "\7n\2\2\u0251\u02e6\7t\2\2\u0252\u0253\7l\2\2\u0253\u0254\7o\2\2\u0254"+ - "\u02e6\7r\2\2\u0255\u0256\7d\2\2\u0256\u0257\7x\2\2\u0257\u02e6\7e\2\2"+ - "\u0258\u0259\7e\2\2\u0259\u025a\7n\2\2\u025a\u02e6\7k\2\2\u025b\u025c"+ - "\7t\2\2\u025c\u025d\7v\2\2\u025d\u02e6\7u\2\2\u025e\u025f\7c\2\2\u025f"+ - "\u0260\7f\2\2\u0260\u02e6\7e\2\2\u0261\u0262\7t\2\2\u0262\u0263\7t\2\2"+ - "\u0263\u02e6\7c\2\2\u0264\u0265\7d\2\2\u0265\u0266\7x\2\2\u0266\u02e6"+ - "\7u\2\2\u0267\u0268\7u\2\2\u0268\u0269\7g\2\2\u0269\u02e6\7k\2\2\u026a"+ - "\u026b\7u\2\2\u026b\u026c\7c\2\2\u026c\u02e6\7z\2\2\u026d\u026e\7u\2\2"+ - "\u026e\u026f\7v\2\2\u026f\u02e6\7{\2\2\u0270\u0271\7u\2\2\u0271\u0272"+ - "\7v\2\2\u0272\u02e6\7c\2\2\u0273\u0274\7u\2\2\u0274\u0275\7v\2\2\u0275"+ - "\u02e6\7z\2\2\u0276\u0277\7f\2\2\u0277\u0278\7g\2\2\u0278\u02e6\7{\2\2"+ - "\u0279\u027a\7v\2\2\u027a\u027b\7z\2\2\u027b\u02e6\7c\2\2\u027c\u027d"+ - "\7z\2\2\u027d\u027e\7c\2\2\u027e\u02e6\7c\2\2\u027f\u0280\7d\2\2\u0280"+ - "\u0281\7e\2\2\u0281\u02e6\7e\2\2\u0282\u0283\7c\2\2\u0283\u0284\7j\2\2"+ - "\u0284\u02e6\7z\2\2\u0285\u0286\7v\2\2\u0286\u0287\7{\2\2\u0287\u02e6"+ - "\7c\2\2\u0288\u0289\7v\2\2\u0289\u028a\7z\2\2\u028a\u02e6\7u\2\2\u028b"+ - "\u028c\7v\2\2\u028c\u028d\7c\2\2\u028d\u02e6\7u\2\2\u028e\u028f\7u\2\2"+ - "\u028f\u0290\7j\2\2\u0290\u02e6\7{\2\2\u0291\u0292\7u\2\2\u0292\u0293"+ - "\7j\2\2\u0293\u02e6\7z\2\2\u0294\u0295\7n\2\2\u0295\u0296\7f\2\2\u0296"+ - "\u02e6\7{\2\2\u0297\u0298\7n\2\2\u0298\u0299\7f\2\2\u0299\u02e6\7c\2\2"+ - "\u029a\u029b\7n\2\2\u029b\u029c\7f\2\2\u029c\u02e6\7z\2\2\u029d\u029e"+ - "\7n\2\2\u029e\u029f\7c\2\2\u029f\u02e6\7z\2\2\u02a0\u02a1\7v\2\2\u02a1"+ - "\u02a2\7c\2\2\u02a2\u02e6\7{\2\2\u02a3\u02a4\7v\2\2\u02a4\u02a5\7c\2\2"+ - "\u02a5\u02e6\7z\2\2\u02a6\u02a7\7d\2\2\u02a7\u02a8\7e\2\2\u02a8\u02e6"+ - "\7u\2\2\u02a9\u02aa\7e\2\2\u02aa\u02ab\7n\2\2\u02ab\u02e6\7x\2\2\u02ac"+ - "\u02ad\7v\2\2\u02ad\u02ae\7u\2\2\u02ae\u02e6\7z\2\2\u02af\u02b0\7n\2\2"+ - "\u02b0\u02b1\7c\2\2\u02b1\u02e6\7u\2\2\u02b2\u02b3\7e\2\2\u02b3\u02b4"+ - "\7r\2\2\u02b4\u02e6\7{\2\2\u02b5\u02b6\7e\2\2\u02b6\u02b7\7o\2\2\u02b7"+ - "\u02e6\7r\2\2\u02b8\u02b9\7e\2\2\u02b9\u02ba\7r\2\2\u02ba\u02e6\7z\2\2"+ - "\u02bb\u02bc\7f\2\2\u02bc\u02bd\7e\2\2\u02bd\u02e6\7r\2\2\u02be\u02bf"+ - "\7f\2\2\u02bf\u02c0\7g\2\2\u02c0\u02e6\7e\2\2\u02c1\u02c2\7k\2\2\u02c2"+ - "\u02c3\7p\2\2\u02c3\u02e6\7e\2\2\u02c4\u02c5\7c\2\2\u02c5\u02c6\7z\2\2"+ - "\u02c6\u02e6\7u\2\2\u02c7\u02c8\7d\2\2\u02c8\u02c9\7p\2\2\u02c9\u02e6"+ - "\7g\2\2\u02ca\u02cb\7e\2\2\u02cb\u02cc\7n\2\2\u02cc\u02e6\7f\2\2\u02cd"+ - "\u02ce\7u\2\2\u02ce\u02cf\7d\2\2\u02cf\u02e6\7e\2\2\u02d0\u02d1\7k\2\2"+ - "\u02d1\u02d2\7u\2\2\u02d2\u02e6\7e\2\2\u02d3\u02d4\7k\2\2\u02d4\u02d5"+ - "\7p\2\2\u02d5\u02e6\7z\2\2\u02d6\u02d7\7d\2\2\u02d7\u02d8\7g\2\2\u02d8"+ - "\u02e6\7s\2\2\u02d9\u02da\7u\2\2\u02da\u02db\7g\2\2\u02db\u02e6\7f\2\2"+ - "\u02dc\u02dd\7f\2\2\u02dd\u02de\7g\2\2\u02de\u02e6\7z\2\2\u02df\u02e0"+ - "\7k\2\2\u02e0\u02e1\7p\2\2\u02e1\u02e6\7{\2\2\u02e2\u02e3\7t\2\2\u02e3"+ - "\u02e4\7q\2\2\u02e4\u02e6\7t\2\2\u02e5\u0207\3\2\2\2\u02e5\u020a\3\2\2"+ - "\2\u02e5\u020d\3\2\2\2\u02e5\u0210\3\2\2\2\u02e5\u0213\3\2\2\2\u02e5\u0216"+ - "\3\2\2\2\u02e5\u0219\3\2\2\2\u02e5\u021c\3\2\2\2\u02e5\u021f\3\2\2\2\u02e5"+ - "\u0222\3\2\2\2\u02e5\u0225\3\2\2\2\u02e5\u0228\3\2\2\2\u02e5\u022b\3\2"+ - "\2\2\u02e5\u022e\3\2\2\2\u02e5\u0231\3\2\2\2\u02e5\u0234\3\2\2\2\u02e5"+ - "\u0237\3\2\2\2\u02e5\u023a\3\2\2\2\u02e5\u023d\3\2\2\2\u02e5\u0240\3\2"+ - "\2\2\u02e5\u0243\3\2\2\2\u02e5\u0246\3\2\2\2\u02e5\u0249\3\2\2\2\u02e5"+ - "\u024c\3\2\2\2\u02e5\u024f\3\2\2\2\u02e5\u0252\3\2\2\2\u02e5\u0255\3\2"+ - "\2\2\u02e5\u0258\3\2\2\2\u02e5\u025b\3\2\2\2\u02e5\u025e\3\2\2\2\u02e5"+ - "\u0261\3\2\2\2\u02e5\u0264\3\2\2\2\u02e5\u0267\3\2\2\2\u02e5\u026a\3\2"+ - "\2\2\u02e5\u026d\3\2\2\2\u02e5\u0270\3\2\2\2\u02e5\u0273\3\2\2\2\u02e5"+ - "\u0276\3\2\2\2\u02e5\u0279\3\2\2\2\u02e5\u027c\3\2\2\2\u02e5\u027f\3\2"+ - "\2\2\u02e5\u0282\3\2\2\2\u02e5\u0285\3\2\2\2\u02e5\u0288\3\2\2\2\u02e5"+ - "\u028b\3\2\2\2\u02e5\u028e\3\2\2\2\u02e5\u0291\3\2\2\2\u02e5\u0294\3\2"+ - "\2\2\u02e5\u0297\3\2\2\2\u02e5\u029a\3\2\2\2\u02e5\u029d\3\2\2\2\u02e5"+ - "\u02a0\3\2\2\2\u02e5\u02a3\3\2\2\2\u02e5\u02a6\3\2\2\2\u02e5\u02a9\3\2"+ - "\2\2\u02e5\u02ac\3\2\2\2\u02e5\u02af\3\2\2\2\u02e5\u02b2\3\2\2\2\u02e5"+ - "\u02b5\3\2\2\2\u02e5\u02b8\3\2\2\2\u02e5\u02bb\3\2\2\2\u02e5\u02be\3\2"+ - "\2\2\u02e5\u02c1\3\2\2\2\u02e5\u02c4\3\2\2\2\u02e5\u02c7\3\2\2\2\u02e5"+ - "\u02ca\3\2\2\2\u02e5\u02cd\3\2\2\2\u02e5\u02d0\3\2\2\2\u02e5\u02d3\3\2"+ - "\2\2\u02e5\u02d6\3\2\2\2\u02e5\u02d9\3\2\2\2\u02e5\u02dc\3\2\2\2\u02e5"+ - "\u02df\3\2\2\2\u02e5\u02e2\3\2\2\2\u02e6\u009c\3\2\2\2\u02e7\u02e8\7}"+ - "\2\2\u02e8\u02e9\7}\2\2\u02e9\u02ed\3\2\2\2\u02ea\u02ec\13\2\2\2\u02eb"+ - "\u02ea\3\2\2\2\u02ec\u02ef\3\2\2\2\u02ed\u02ee\3\2\2\2\u02ed\u02eb\3\2"+ - "\2\2\u02ee\u02f0\3\2\2\2\u02ef\u02ed\3\2\2\2\u02f0\u02f1\7\177\2\2\u02f1"+ - "\u02f2\7\177\2\2\u02f2\u009e\3\2\2\2\u02f3\u02f4\7d\2\2\u02f4\u02f5\7"+ - "{\2\2\u02f5\u02f6\7v\2\2\u02f6\u0319\7g\2\2\u02f7\u02f8\7y\2\2\u02f8\u02f9"+ - "\7q\2\2\u02f9\u02fa\7t\2\2\u02fa\u0319\7f\2\2\u02fb\u02fc\7f\2\2\u02fc"+ - "\u02fd\7y\2\2\u02fd\u02fe\7q\2\2\u02fe\u02ff\7t\2\2\u02ff\u0319\7f\2\2"+ - "\u0300\u0301\7d\2\2\u0301\u0302\7q\2\2\u0302\u0303\7q\2\2\u0303\u0319"+ - "\7n\2\2\u0304\u0305\7e\2\2\u0305\u0306\7j\2\2\u0306\u0307\7c\2\2\u0307"+ - "\u0319\7t\2\2\u0308\u0309\7u\2\2\u0309\u030a\7j\2\2\u030a\u030b\7q\2\2"+ - "\u030b\u030c\7t\2\2\u030c\u0319\7v\2\2\u030d\u030e\7k\2\2\u030e\u030f"+ - "\7p\2\2\u030f\u0319\7v\2\2\u0310\u0311\7n\2\2\u0311\u0312\7q\2\2\u0312"+ - "\u0313\7p\2\2\u0313\u0319\7i\2\2\u0314\u0315\7x\2\2\u0315\u0316\7q\2\2"+ - "\u0316\u0317\7k\2\2\u0317\u0319\7f\2\2\u0318\u02f3\3\2\2\2\u0318\u02f7"+ - "\3\2\2\2\u0318\u02fb\3\2\2\2\u0318\u0300\3\2\2\2\u0318\u0304\3\2\2\2\u0318"+ - "\u0308\3\2\2\2\u0318\u030d\3\2\2\2\u0318\u0310\3\2\2\2\u0318\u0314\3\2"+ - "\2\2\u0319\u00a0\3\2\2\2\u031a\u0320\7$\2\2\u031b\u031c\7^\2\2\u031c\u031f"+ - "\7$\2\2\u031d\u031f\n\2\2\2\u031e\u031b\3\2\2\2\u031e\u031d\3\2\2\2\u031f"+ - "\u0322\3\2\2\2\u0320\u031e\3\2\2\2\u0320\u0321\3\2\2\2\u0321\u0323\3\2"+ - "\2\2\u0322\u0320\3\2\2\2\u0323\u0325\7$\2\2\u0324\u0326\7|\2\2\u0325\u0324"+ - "\3\2\2\2\u0325\u0326\3\2\2\2\u0326\u00a2\3\2\2\2\u0327\u032b\7)\2\2\u0328"+ - "\u0329\7^\2\2\u0329\u032c\7)\2\2\u032a\u032c\n\3\2\2\u032b\u0328\3\2\2"+ - "\2\u032b\u032a\3\2\2\2\u032c\u032d\3\2\2\2\u032d\u032e\7)\2\2\u032e\u00a4"+ - "\3\2\2\2\u032f\u0330\7v\2\2\u0330\u0331\7t\2\2\u0331\u0332\7w\2\2\u0332"+ - "\u0339\7g\2\2\u0333\u0334\7h\2\2\u0334\u0335\7c\2\2\u0335\u0336\7n\2\2"+ - "\u0336\u0337\7u\2\2\u0337\u0339\7g\2\2\u0338\u032f\3\2\2\2\u0338\u0333"+ - "\3\2\2\2\u0339\u00a6\3\2\2\2\u033a\u033d\5\u00a9U\2\u033b\u033d\5\u00b1"+ - "Y\2\u033c\u033a\3\2\2\2\u033c\u033b\3\2\2\2\u033d\u00a8\3\2\2\2\u033e"+ - "\u0342\5\u00abV\2\u033f\u0342\5\u00adW\2\u0340\u0342\5\u00afX\2\u0341"+ - "\u033e\3\2\2\2\u0341\u033f\3\2\2\2\u0341\u0340\3\2\2\2\u0342\u00aa\3\2"+ - "\2\2\u0343\u0349\7\'\2\2\u0344\u0345\7\62\2\2\u0345\u0349\7d\2\2\u0346"+ - "\u0347\7\62\2\2\u0347\u0349\7D\2\2\u0348\u0343\3\2\2\2\u0348\u0344\3\2"+ - "\2\2\u0348\u0346\3\2\2\2\u0349\u034d\3\2\2\2\u034a\u034c\5\u00b9]\2\u034b"+ - "\u034a\3\2\2\2\u034c\u034f\3\2\2\2\u034d\u034b\3\2\2\2\u034d\u034e\3\2"+ - "\2\2\u034e\u0350\3\2\2\2\u034f\u034d\3\2\2\2\u0350\u0352\7\60\2\2\u0351"+ - "\u0353\5\u00b9]\2\u0352\u0351\3\2\2\2\u0353\u0354\3\2\2\2\u0354\u0352"+ - "\3\2\2\2\u0354\u0355\3\2\2\2\u0355\u00ac\3\2\2\2\u0356\u0358\5\u00bb^"+ - "\2\u0357\u0356\3\2\2\2\u0358\u035b\3\2\2\2\u0359\u0357\3\2\2\2\u0359\u035a"+ - "\3\2\2\2\u035a\u035c\3\2\2\2\u035b\u0359\3\2\2\2\u035c\u035e\7\60\2\2"+ - "\u035d\u035f\5\u00bb^\2\u035e\u035d\3\2\2\2\u035f\u0360\3\2\2\2\u0360"+ - "\u035e\3\2\2\2\u0360\u0361\3\2\2\2\u0361\u00ae\3\2\2\2\u0362\u0368\7&"+ - "\2\2\u0363\u0364\7\62\2\2\u0364\u0368\7z\2\2\u0365\u0366\7\62\2\2\u0366"+ - "\u0368\7Z\2\2\u0367\u0362\3\2\2\2\u0367\u0363\3\2\2\2\u0367\u0365\3\2"+ - "\2\2\u0368\u036c\3\2\2\2\u0369\u036b\5\u00bd_\2\u036a\u0369\3\2\2\2\u036b"+ - "\u036e\3\2\2\2\u036c\u036a\3\2\2\2\u036c\u036d\3\2\2\2\u036d\u036f\3\2"+ - "\2\2\u036e\u036c\3\2\2\2\u036f\u0371\7\60\2\2\u0370\u0372\5\u00bd_\2\u0371"+ - "\u0370\3\2\2\2\u0372\u0373\3\2\2\2\u0373\u0371\3\2\2\2\u0373\u0374\3\2"+ - "\2\2\u0374\u00b0\3\2\2\2\u0375\u0379\5\u00b5[\2\u0376\u0379\5\u00b7\\"+ - "\2\u0377\u0379\5\u00b3Z\2\u0378\u0375\3\2\2\2\u0378\u0376\3\2\2\2\u0378"+ - "\u0377\3\2\2\2\u0379\u00b2\3\2\2\2\u037a\u037b\7\62\2\2\u037b\u037d\t"+ - "\4\2\2\u037c\u037e\5\u00b9]\2\u037d\u037c\3\2\2\2\u037e\u037f\3\2\2\2"+ - "\u037f\u037d\3\2\2\2\u037f\u0380\3\2\2\2\u0380\u0388\3\2\2\2\u0381\u0383"+ - "\7\'\2\2\u0382\u0384\5\u00b9]\2\u0383\u0382\3\2\2\2\u0384\u0385\3\2\2"+ - "\2\u0385\u0383\3\2\2\2\u0385\u0386\3\2\2\2\u0386\u0388\3\2\2\2\u0387\u037a"+ - "\3\2\2\2\u0387\u0381\3\2\2\2\u0388\u00b4\3\2\2\2\u0389\u038b\5\u00bb^"+ - "\2\u038a\u0389\3\2\2\2\u038b\u038c\3\2\2\2\u038c\u038a\3\2\2\2\u038c\u038d"+ - "\3\2\2\2\u038d\u00b6\3\2\2\2\u038e\u0394\7&\2\2\u038f\u0390\7\62\2\2\u0390"+ - "\u0394\7z\2\2\u0391\u0392\7\62\2\2\u0392\u0394\7Z\2\2\u0393\u038e\3\2"+ - "\2\2\u0393\u038f\3\2\2\2\u0393\u0391\3\2\2\2\u0394\u0396\3\2\2\2\u0395"+ - "\u0397\5\u00bd_\2\u0396\u0395\3\2\2\2\u0397\u0398\3\2\2\2\u0398\u0396"+ - "\3\2\2\2\u0398\u0399\3\2\2\2\u0399\u00b8\3\2\2\2\u039a\u039b\t\5\2\2\u039b"+ - "\u00ba\3\2\2\2\u039c\u039d\t\6\2\2\u039d\u00bc\3\2\2\2\u039e\u039f\t\7"+ - "\2\2\u039f\u00be\3\2\2\2\u03a0\u03a4\5\u00c1a\2\u03a1\u03a3\5\u00c3b\2"+ - "\u03a2\u03a1\3\2\2\2\u03a3\u03a6\3\2\2\2\u03a4\u03a2\3\2\2\2\u03a4\u03a5"+ - "\3\2\2\2\u03a5\u00c0\3\2\2\2\u03a6\u03a4\3\2\2\2\u03a7\u03a8\t\b\2\2\u03a8"+ - "\u00c2\3\2\2\2\u03a9\u03aa\t\t\2\2\u03aa\u00c4\3\2\2\2\u03ab\u03af\7#"+ - "\2\2\u03ac\u03ae\5\u00c3b\2\u03ad\u03ac\3\2\2\2\u03ae\u03b1\3\2\2\2\u03af"+ - "\u03ad\3\2\2\2\u03af\u03b0\3\2\2\2\u03b0\u03b3\3\2\2\2\u03b1\u03af\3\2"+ - "\2\2\u03b2\u03b4\t\n\2\2\u03b3\u03b2\3\2\2\2\u03b4\u03b5\3\2\2\2\u03b5"+ - "\u03b3\3\2\2\2\u03b5\u03b6\3\2\2\2\u03b6\u00c6\3\2\2\2\u03b7\u03b9\t\13"+ - "\2\2\u03b8\u03b7\3\2\2\2\u03b9\u03ba\3\2\2\2\u03ba\u03b8\3\2\2\2\u03ba"+ - "\u03bb\3\2\2\2\u03bb\u03bc\3\2\2\2\u03bc\u03bd\bd\2\2\u03bd\u00c8\3\2"+ - "\2\2\u03be\u03bf\7\61\2\2\u03bf\u03c0\7\61\2\2\u03c0\u03c4\3\2\2\2\u03c1"+ - "\u03c3\n\f\2\2\u03c2\u03c1\3\2\2\2\u03c3\u03c6\3\2\2\2\u03c4\u03c2\3\2"+ - "\2\2\u03c4\u03c5\3\2\2\2\u03c5\u03c7\3\2\2\2\u03c6\u03c4\3\2\2\2\u03c7"+ - "\u03c8\be\3\2\u03c8\u00ca\3\2\2\2\u03c9\u03ca\7\61\2\2\u03ca\u03cb\7,"+ - "\2\2\u03cb\u03cf\3\2\2\2\u03cc\u03ce\13\2\2\2\u03cd\u03cc\3\2\2\2\u03ce"+ - "\u03d1\3\2\2\2\u03cf\u03d0\3\2\2\2\u03cf\u03cd\3\2\2\2\u03d0\u03d2\3\2"+ - "\2\2\u03d1\u03cf\3\2\2\2\u03d2\u03d3\7,\2\2\u03d3\u03d4\7\61\2\2\u03d4"+ - "\u03d5\3\2\2\2\u03d5\u03d6\bf\3\2\u03d6\u00cc\3\2\2\2\"\2\u02e5\u02ed"+ - "\u0318\u031e\u0320\u0325\u032b\u0338\u033c\u0341\u0348\u034d\u0354\u0359"+ - "\u0360\u0367\u036c\u0373\u0378\u037f\u0385\u0387\u038c\u0393\u0398\u03a4"+ - "\u03af\u03b5\u03ba\u03c4\u03cf\4\2\3\2\2\4\2"; + "`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\3\2\3\2\3\2\3\2\3"+ + "\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n"+ + "\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3"+ + "\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16"+ + "\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20"+ + "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21"+ + "\3\21\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24"+ + "\3\24\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+ + "\3\31\3\31\3\32\3\32\3\32\3\32\3\33\3\33\3\34\3\34\3\34\3\35\3\35\3\35"+ + "\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37"+ + "\3\37\3 \3 \3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3#\3#\3$\3$\3$\3%\3%\3%"+ + "\3%\3%\3%\3%\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3)\3*\3*\3+"+ + "\3+\3,\3,\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\61\3\61\3\62\3\62\3\63\3"+ + "\63\3\64\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67\3\67\3\67\38\38"+ + "\39\39\3:\3:\3:\3;\3;\3;\3<\3<\3=\3=\3=\3>\3>\3>\3?\3?\3?\3@\3@\3@\3A"+ + "\3A\3A\3B\3B\3B\3B\3C\3C\3C\3C\3D\3D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3G"+ + "\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3J\3J\3J\3J\3J"+ + "\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3N\3N\3N"+ + "\3N\3N\3N\3O\3O\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P"+ + "\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\3P\5P\u02f4"+ + "\nP\3Q\3Q\3Q\3Q\7Q\u02fa\nQ\fQ\16Q\u02fd\13Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3"+ + "R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3"+ + "R\3R\3R\3R\3R\3R\3R\3R\3R\5R\u0327\nR\3S\3S\3S\3S\7S\u032d\nS\fS\16S\u0330"+ + "\13S\3S\3S\5S\u0334\nS\3T\3T\3T\3T\5T\u033a\nT\3T\3T\3U\3U\3U\3U\3U\3"+ + "U\3U\3U\3U\5U\u0347\nU\3V\3V\5V\u034b\nV\3W\3W\3W\5W\u0350\nW\3X\3X\3"+ + "X\3X\3X\5X\u0357\nX\3X\7X\u035a\nX\fX\16X\u035d\13X\3X\3X\6X\u0361\nX"+ + "\rX\16X\u0362\3Y\7Y\u0366\nY\fY\16Y\u0369\13Y\3Y\3Y\6Y\u036d\nY\rY\16"+ + "Y\u036e\3Z\3Z\3Z\3Z\3Z\5Z\u0376\nZ\3Z\7Z\u0379\nZ\fZ\16Z\u037c\13Z\3Z"+ + "\3Z\6Z\u0380\nZ\rZ\16Z\u0381\3[\3[\3[\5[\u0387\n[\3[\3[\3[\5[\u038c\n"+ + "[\3\\\3\\\3\\\6\\\u0391\n\\\r\\\16\\\u0392\3\\\3\\\6\\\u0397\n\\\r\\\16"+ + "\\\u0398\5\\\u039b\n\\\3]\6]\u039e\n]\r]\16]\u039f\3^\3^\3^\3^\3^\5^\u03a7"+ + "\n^\3^\6^\u03aa\n^\r^\16^\u03ab\3_\3_\3`\3`\3a\3a\3b\3b\7b\u03b6\nb\f"+ + "b\16b\u03b9\13b\3c\3c\3d\3d\3e\3e\7e\u03c1\ne\fe\16e\u03c4\13e\3e\6e\u03c7"+ + "\ne\re\16e\u03c8\3f\6f\u03cc\nf\rf\16f\u03cd\3f\3f\3g\3g\3g\3g\7g\u03d6"+ + "\ng\fg\16g\u03d9\13g\3g\3g\3h\3h\3h\3h\7h\u03e1\nh\fh\16h\u03e4\13h\3"+ + "h\3h\3h\3h\3h\4\u02fb\u03e2\2i\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13"+ + "\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61"+ + "\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61"+ + "a\62c\63e\64g\65i\66k\67m8o9q:s;u{?}@\177A\u0081B\u0083C\u0085D\u0087"+ + "E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009b"+ + "O\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00af"+ + "Y\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd\2\u00bf\2\u00c1\2\u00c3"+ + "`\u00c5\2\u00c7\2\u00c9a\u00cbb\u00cdc\u00cfd\3\2\17\3\2$$\3\2))\4\2u"+ + "uww\7\2dfkknnuuyy\4\2DDdd\3\2\62\63\3\2\62;\5\2\62;CHch\5\2C\\aac|\6\2"+ + "\62;C\\aac|\4\2--//\6\2\13\f\17\17\"\"\u00a2\u00a2\4\2\f\f\17\17\2\u0459"+ + "\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2"+ + "\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2"+ + "\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2"+ + "\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2"+ + "\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3"+ + "\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2"+ + "\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2"+ + "U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3"+ + "\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2"+ + "\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2"+ + "{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085"+ + "\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2"+ + "\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097"+ + "\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2"+ + "\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9"+ + "\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2"+ + "\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb"+ + "\3\2\2\2\2\u00c3\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2"+ + "\2\2\u00cf\3\2\2\2\3\u00d1\3\2\2\2\5\u00d8\3\2\2\2\7\u00da\3\2\2\2\t\u00dc"+ + "\3\2\2\2\13\u00de\3\2\2\2\r\u00e0\3\2\2\2\17\u00e2\3\2\2\2\21\u00e4\3"+ + "\2\2\2\23\u00e6\3\2\2\2\25\u00ec\3\2\2\2\27\u00f3\3\2\2\2\31\u00f9\3\2"+ + "\2\2\33\u0102\3\2\2\2\35\u0109\3\2\2\2\37\u0112\3\2\2\2!\u011c\3\2\2\2"+ + "#\u0124\3\2\2\2%\u0127\3\2\2\2\'\u012c\3\2\2\2)\u0132\3\2\2\2+\u0135\3"+ + "\2\2\2-\u0139\3\2\2\2/\u0140\3\2\2\2\61\u0146\3\2\2\2\63\u014f\3\2\2\2"+ + "\65\u0153\3\2\2\2\67\u0155\3\2\2\29\u0158\3\2\2\2;\u015f\3\2\2\2=\u0168"+ + "\3\2\2\2?\u016a\3\2\2\2A\u016c\3\2\2\2C\u016e\3\2\2\2E\u0175\3\2\2\2G"+ + "\u0177\3\2\2\2I\u017a\3\2\2\2K\u0181\3\2\2\2M\u0188\3\2\2\2O\u018b\3\2"+ + "\2\2Q\u018e\3\2\2\2S\u0190\3\2\2\2U\u0192\3\2\2\2W\u0194\3\2\2\2Y\u0196"+ + "\3\2\2\2[\u0198\3\2\2\2]\u019b\3\2\2\2_\u019e\3\2\2\2a\u01a0\3\2\2\2c"+ + "\u01a2\3\2\2\2e\u01a4\3\2\2\2g\u01a6\3\2\2\2i\u01a9\3\2\2\2k\u01ac\3\2"+ + "\2\2m\u01af\3\2\2\2o\u01b2\3\2\2\2q\u01b4\3\2\2\2s\u01b6\3\2\2\2u\u01b9"+ + "\3\2\2\2w\u01bc\3\2\2\2y\u01be\3\2\2\2{\u01c1\3\2\2\2}\u01c4\3\2\2\2\177"+ + "\u01c7\3\2\2\2\u0081\u01ca\3\2\2\2\u0083\u01cd\3\2\2\2\u0085\u01d1\3\2"+ + "\2\2\u0087\u01d5\3\2\2\2\u0089\u01d8\3\2\2\2\u008b\u01db\3\2\2\2\u008d"+ + "\u01de\3\2\2\2\u008f\u01e6\3\2\2\2\u0091\u01ef\3\2\2\2\u0093\u01f4\3\2"+ + "\2\2\u0095\u01fd\3\2\2\2\u0097\u0203\3\2\2\2\u0099\u020a\3\2\2\2\u009b"+ + "\u020d\3\2\2\2\u009d\u0213\3\2\2\2\u009f\u02f3\3\2\2\2\u00a1\u02f5\3\2"+ + "\2\2\u00a3\u0326\3\2\2\2\u00a5\u0328\3\2\2\2\u00a7\u0335\3\2\2\2\u00a9"+ + "\u0346\3\2\2\2\u00ab\u034a\3\2\2\2\u00ad\u034f\3\2\2\2\u00af\u0356\3\2"+ + "\2\2\u00b1\u0367\3\2\2\2\u00b3\u0375\3\2\2\2\u00b5\u0386\3\2\2\2\u00b7"+ + "\u039a\3\2\2\2\u00b9\u039d\3\2\2\2\u00bb\u03a6\3\2\2\2\u00bd\u03ad\3\2"+ + "\2\2\u00bf\u03af\3\2\2\2\u00c1\u03b1\3\2\2\2\u00c3\u03b3\3\2\2\2\u00c5"+ + "\u03ba\3\2\2\2\u00c7\u03bc\3\2\2\2\u00c9\u03be\3\2\2\2\u00cb\u03cb\3\2"+ + "\2\2\u00cd\u03d1\3\2\2\2\u00cf\u03dc\3\2\2\2\u00d1\u00d2\7k\2\2\u00d2"+ + "\u00d3\7o\2\2\u00d3\u00d4\7r\2\2\u00d4\u00d5\7q\2\2\u00d5\u00d6\7t\2\2"+ + "\u00d6\u00d7\7v\2\2\u00d7\4\3\2\2\2\u00d8\u00d9\7=\2\2\u00d9\6\3\2\2\2"+ + "\u00da\u00db\7.\2\2\u00db\b\3\2\2\2\u00dc\u00dd\7?\2\2\u00dd\n\3\2\2\2"+ + "\u00de\u00df\7*\2\2\u00df\f\3\2\2\2\u00e0\u00e1\7+\2\2\u00e1\16\3\2\2"+ + "\2\u00e2\u00e3\7}\2\2\u00e3\20\3\2\2\2\u00e4\u00e5\7\177\2\2\u00e5\22"+ + "\3\2\2\2\u00e6\u00e7\7e\2\2\u00e7\u00e8\7q\2\2\u00e8\u00e9\7p\2\2\u00e9"+ + "\u00ea\7u\2\2\u00ea\u00eb\7v\2\2\u00eb\24\3\2\2\2\u00ec\u00ed\7g\2\2\u00ed"+ + "\u00ee\7z\2\2\u00ee\u00ef\7v\2\2\u00ef\u00f0\7g\2\2\u00f0\u00f1\7t\2\2"+ + "\u00f1\u00f2\7p\2\2\u00f2\26\3\2\2\2\u00f3\u00f4\7c\2\2\u00f4\u00f5\7"+ + "n\2\2\u00f5\u00f6\7k\2\2\u00f6\u00f7\7i\2\2\u00f7\u00f8\7p\2\2\u00f8\30"+ + "\3\2\2\2\u00f9\u00fa\7t\2\2\u00fa\u00fb\7g\2\2\u00fb\u00fc\7i\2\2\u00fc"+ + "\u00fd\7k\2\2\u00fd\u00fe\7u\2\2\u00fe\u00ff\7v\2\2\u00ff\u0100\7g\2\2"+ + "\u0100\u0101\7t\2\2\u0101\32\3\2\2\2\u0102\u0103\7k\2\2\u0103\u0104\7"+ + "p\2\2\u0104\u0105\7n\2\2\u0105\u0106\7k\2\2\u0106\u0107\7p\2\2\u0107\u0108"+ + "\7g\2\2\u0108\34\3\2\2\2\u0109\u010a\7x\2\2\u010a\u010b\7q\2\2\u010b\u010c"+ + "\7n\2\2\u010c\u010d\7c\2\2\u010d\u010e\7v\2\2\u010e\u010f\7k\2\2\u010f"+ + "\u0110\7n\2\2\u0110\u0111\7g\2\2\u0111\36\3\2\2\2\u0112\u0113\7k\2\2\u0113"+ + "\u0114\7p\2\2\u0114\u0115\7v\2\2\u0115\u0116\7g\2\2\u0116\u0117\7t\2\2"+ + "\u0117\u0118\7t\2\2\u0118\u0119\7w\2\2\u0119\u011a\7r\2\2\u011a\u011b"+ + "\7v\2\2\u011b \3\2\2\2\u011c\u011d\7t\2\2\u011d\u011e\7g\2\2\u011e\u011f"+ + "\7u\2\2\u011f\u0120\7g\2\2\u0120\u0121\7t\2\2\u0121\u0122\7x\2\2\u0122"+ + "\u0123\7g\2\2\u0123\"\3\2\2\2\u0124\u0125\7k\2\2\u0125\u0126\7h\2\2\u0126"+ + "$\3\2\2\2\u0127\u0128\7g\2\2\u0128\u0129\7n\2\2\u0129\u012a\7u\2\2\u012a"+ + "\u012b\7g\2\2\u012b&\3\2\2\2\u012c\u012d\7y\2\2\u012d\u012e\7j\2\2\u012e"+ + "\u012f\7k\2\2\u012f\u0130\7n\2\2\u0130\u0131\7g\2\2\u0131(\3\2\2\2\u0132"+ + "\u0133\7f\2\2\u0133\u0134\7q\2\2\u0134*\3\2\2\2\u0135\u0136\7h\2\2\u0136"+ + "\u0137\7q\2\2\u0137\u0138\7t\2\2\u0138,\3\2\2\2\u0139\u013a\7t\2\2\u013a"+ + "\u013b\7g\2\2\u013b\u013c\7v\2\2\u013c\u013d\7w\2\2\u013d\u013e\7t\2\2"+ + "\u013e\u013f\7p\2\2\u013f.\3\2\2\2\u0140\u0141\7d\2\2\u0141\u0142\7t\2"+ + "\2\u0142\u0143\7g\2\2\u0143\u0144\7c\2\2\u0144\u0145\7m\2\2\u0145\60\3"+ + "\2\2\2\u0146\u0147\7e\2\2\u0147\u0148\7q\2\2\u0148\u0149\7p\2\2\u0149"+ + "\u014a\7v\2\2\u014a\u014b\7k\2\2\u014b\u014c\7p\2\2\u014c\u014d\7w\2\2"+ + "\u014d\u014e\7g\2\2\u014e\62\3\2\2\2\u014f\u0150\7c\2\2\u0150\u0151\7"+ + "u\2\2\u0151\u0152\7o\2\2\u0152\64\3\2\2\2\u0153\u0154\7<\2\2\u0154\66"+ + "\3\2\2\2\u0155\u0156\7\60\2\2\u0156\u0157\7\60\2\2\u01578\3\2\2\2\u0158"+ + "\u0159\7u\2\2\u0159\u015a\7k\2\2\u015a\u015b\7i\2\2\u015b\u015c\7p\2\2"+ + "\u015c\u015d\7g\2\2\u015d\u015e\7f\2\2\u015e:\3\2\2\2\u015f\u0160\7w\2"+ + "\2\u0160\u0161\7p\2\2\u0161\u0162\7u\2\2\u0162\u0163\7k\2\2\u0163\u0164"+ + "\7i\2\2\u0164\u0165\7p\2\2\u0165\u0166\7g\2\2\u0166\u0167\7f\2\2\u0167"+ + "<\3\2\2\2\u0168\u0169\7,\2\2\u0169>\3\2\2\2\u016a\u016b\7]\2\2\u016b@"+ + "\3\2\2\2\u016c\u016d\7_\2\2\u016dB\3\2\2\2\u016e\u016f\7u\2\2\u016f\u0170"+ + "\7v\2\2\u0170\u0171\7t\2\2\u0171\u0172\7w\2\2\u0172\u0173\7e\2\2\u0173"+ + "\u0174\7v\2\2\u0174D\3\2\2\2\u0175\u0176\7\60\2\2\u0176F\3\2\2\2\u0177"+ + "\u0178\7/\2\2\u0178\u0179\7@\2\2\u0179H\3\2\2\2\u017a\u017b\7u\2\2\u017b"+ + "\u017c\7k\2\2\u017c\u017d\7|\2\2\u017d\u017e\7g\2\2\u017e\u017f\7q\2\2"+ + "\u017f\u0180\7h\2\2\u0180J\3\2\2\2\u0181\u0182\7v\2\2\u0182\u0183\7{\2"+ + "\2\u0183\u0184\7r\2\2\u0184\u0185\7g\2\2\u0185\u0186\7k\2\2\u0186\u0187"+ + "\7f\2\2\u0187L\3\2\2\2\u0188\u0189\7/\2\2\u0189\u018a\7/\2\2\u018aN\3"+ + "\2\2\2\u018b\u018c\7-\2\2\u018c\u018d\7-\2\2\u018dP\3\2\2\2\u018e\u018f"+ + "\7-\2\2\u018fR\3\2\2\2\u0190\u0191\7/\2\2\u0191T\3\2\2\2\u0192\u0193\7"+ + "#\2\2\u0193V\3\2\2\2\u0194\u0195\7(\2\2\u0195X\3\2\2\2\u0196\u0197\7\u0080"+ + "\2\2\u0197Z\3\2\2\2\u0198\u0199\7@\2\2\u0199\u019a\7@\2\2\u019a\\\3\2"+ + "\2\2\u019b\u019c\7>\2\2\u019c\u019d\7>\2\2\u019d^\3\2\2\2\u019e\u019f"+ + "\7\61\2\2\u019f`\3\2\2\2\u01a0\u01a1\7\'\2\2\u01a1b\3\2\2\2\u01a2\u01a3"+ + "\7>\2\2\u01a3d\3\2\2\2\u01a4\u01a5\7@\2\2\u01a5f\3\2\2\2\u01a6\u01a7\7"+ + "?\2\2\u01a7\u01a8\7?\2\2\u01a8h\3\2\2\2\u01a9\u01aa\7#\2\2\u01aa\u01ab"+ + "\7?\2\2\u01abj\3\2\2\2\u01ac\u01ad\7>\2\2\u01ad\u01ae\7?\2\2\u01ael\3"+ + "\2\2\2\u01af\u01b0\7@\2\2\u01b0\u01b1\7?\2\2\u01b1n\3\2\2\2\u01b2\u01b3"+ + "\7`\2\2\u01b3p\3\2\2\2\u01b4\u01b5\7~\2\2\u01b5r\3\2\2\2\u01b6\u01b7\7"+ + "(\2\2\u01b7\u01b8\7(\2\2\u01b8t\3\2\2\2\u01b9\u01ba\7~\2\2\u01ba\u01bb"+ + "\7~\2\2\u01bbv\3\2\2\2\u01bc\u01bd\7A\2\2\u01bdx\3\2\2\2\u01be\u01bf\7"+ + "-\2\2\u01bf\u01c0\7?\2\2\u01c0z\3\2\2\2\u01c1\u01c2\7/\2\2\u01c2\u01c3"+ + "\7?\2\2\u01c3|\3\2\2\2\u01c4\u01c5\7,\2\2\u01c5\u01c6\7?\2\2\u01c6~\3"+ + "\2\2\2\u01c7\u01c8\7\61\2\2\u01c8\u01c9\7?\2\2\u01c9\u0080\3\2\2\2\u01ca"+ + "\u01cb\7\'\2\2\u01cb\u01cc\7?\2\2\u01cc\u0082\3\2\2\2\u01cd\u01ce\7>\2"+ + "\2\u01ce\u01cf\7>\2\2\u01cf\u01d0\7?\2\2\u01d0\u0084\3\2\2\2\u01d1\u01d2"+ + "\7@\2\2\u01d2\u01d3\7@\2\2\u01d3\u01d4\7?\2\2\u01d4\u0086\3\2\2\2\u01d5"+ + "\u01d6\7(\2\2\u01d6\u01d7\7?\2\2\u01d7\u0088\3\2\2\2\u01d8\u01d9\7~\2"+ + "\2\u01d9\u01da\7?\2\2\u01da\u008a\3\2\2\2\u01db\u01dc\7`\2\2\u01dc\u01dd"+ + "\7?\2\2\u01dd\u008c\3\2\2\2\u01de\u01df\7m\2\2\u01df\u01e0\7k\2\2\u01e0"+ + "\u01e1\7e\2\2\u01e1\u01e2\7m\2\2\u01e2\u01e3\7c\2\2\u01e3\u01e4\7u\2\2"+ + "\u01e4\u01e5\7o\2\2\u01e5\u008e\3\2\2\2\u01e6\u01e7\7t\2\2\u01e7\u01e8"+ + "\7g\2\2\u01e8\u01e9\7u\2\2\u01e9\u01ea\7q\2\2\u01ea\u01eb\7w\2\2\u01eb"+ + "\u01ec\7t\2\2\u01ec\u01ed\7e\2\2\u01ed\u01ee\7g\2\2\u01ee\u0090\3\2\2"+ + "\2\u01ef\u01f0\7w\2\2\u01f0\u01f1\7u\2\2\u01f1\u01f2\7g\2\2\u01f2\u01f3"+ + "\7u\2\2\u01f3\u0092\3\2\2\2\u01f4\u01f5\7e\2\2\u01f5\u01f6\7n\2\2\u01f6"+ + "\u01f7\7q\2\2\u01f7\u01f8\7d\2\2\u01f8\u01f9\7d\2\2\u01f9\u01fa\7g\2\2"+ + "\u01fa\u01fb\7t\2\2\u01fb\u01fc\7u\2\2\u01fc\u0094\3\2\2\2\u01fd\u01fe"+ + "\7d\2\2\u01fe\u01ff\7{\2\2\u01ff\u0200\7v\2\2\u0200\u0201\7g\2\2\u0201"+ + "\u0202\7u\2\2\u0202\u0096\3\2\2\2\u0203\u0204\7e\2\2\u0204\u0205\7{\2"+ + "\2\u0205\u0206\7e\2\2\u0206\u0207\7n\2\2\u0207\u0208\7g\2\2\u0208\u0209"+ + "\7u\2\2\u0209\u0098\3\2\2\2\u020a\u020b\7r\2\2\u020b\u020c\7e\2\2\u020c"+ + "\u009a\3\2\2\2\u020d\u020e\7\60\2\2\u020e\u020f\7d\2\2\u020f\u0210\7{"+ + "\2\2\u0210\u0211\7v\2\2\u0211\u0212\7g\2\2\u0212\u009c\3\2\2\2\u0213\u0214"+ + "\7%\2\2\u0214\u009e\3\2\2\2\u0215\u0216\7d\2\2\u0216\u0217\7t\2\2\u0217"+ + "\u02f4\7m\2\2\u0218\u0219\7q\2\2\u0219\u021a\7t\2\2\u021a\u02f4\7c\2\2"+ + "\u021b\u021c\7m\2\2\u021c\u021d\7k\2\2\u021d\u02f4\7n\2\2\u021e\u021f"+ + "\7u\2\2\u021f\u0220\7n\2\2\u0220\u02f4\7q\2\2\u0221\u0222\7p\2\2\u0222"+ + "\u0223\7q\2\2\u0223\u02f4\7r\2\2\u0224\u0225\7c\2\2\u0225\u0226\7u\2\2"+ + "\u0226\u02f4\7n\2\2\u0227\u0228\7r\2\2\u0228\u0229\7j\2\2\u0229\u02f4"+ + "\7r\2\2\u022a\u022b\7c\2\2\u022b\u022c\7p\2\2\u022c\u02f4\7e\2\2\u022d"+ + "\u022e\7d\2\2\u022e\u022f\7r\2\2\u022f\u02f4\7n\2\2\u0230\u0231\7e\2\2"+ + "\u0231\u0232\7n\2\2\u0232\u02f4\7e\2\2\u0233\u0234\7l\2\2\u0234\u0235"+ + "\7u\2\2\u0235\u02f4\7t\2\2\u0236\u0237\7c\2\2\u0237\u0238\7p\2\2\u0238"+ + "\u02f4\7f\2\2\u0239\u023a\7t\2\2\u023a\u023b\7n\2\2\u023b\u02f4\7c\2\2"+ + "\u023c\u023d\7d\2\2\u023d\u023e\7k\2\2\u023e\u02f4\7v\2\2\u023f\u0240"+ + "\7t\2\2\u0240\u0241\7q\2\2\u0241\u02f4\7n\2\2\u0242\u0243\7r\2\2\u0243"+ + "\u0244\7n\2\2\u0244\u02f4\7c\2\2\u0245\u0246\7r\2\2\u0246\u0247\7n\2\2"+ + "\u0247\u02f4\7r\2\2\u0248\u0249\7d\2\2\u0249\u024a\7o\2\2\u024a\u02f4"+ + "\7k\2\2\u024b\u024c\7u\2\2\u024c\u024d\7g\2\2\u024d\u02f4\7e\2\2\u024e"+ + "\u024f\7t\2\2\u024f\u0250\7v\2\2\u0250\u02f4\7k\2\2\u0251\u0252\7g\2\2"+ + "\u0252\u0253\7q\2\2\u0253\u02f4\7t\2\2\u0254\u0255\7u\2\2\u0255\u0256"+ + "\7t\2\2\u0256\u02f4\7g\2\2\u0257\u0258\7n\2\2\u0258\u0259\7u\2\2\u0259"+ + "\u02f4\7t\2\2\u025a\u025b\7r\2\2\u025b\u025c\7j\2\2\u025c\u02f4\7c\2\2"+ + "\u025d\u025e\7c\2\2\u025e\u025f\7n\2\2\u025f\u02f4\7t\2\2\u0260\u0261"+ + "\7l\2\2\u0261\u0262\7o\2\2\u0262\u02f4\7r\2\2\u0263\u0264\7d\2\2\u0264"+ + "\u0265\7x\2\2\u0265\u02f4\7e\2\2\u0266\u0267\7e\2\2\u0267\u0268\7n\2\2"+ + "\u0268\u02f4\7k\2\2\u0269\u026a\7t\2\2\u026a\u026b\7v\2\2\u026b\u02f4"+ + "\7u\2\2\u026c\u026d\7c\2\2\u026d\u026e\7f\2\2\u026e\u02f4\7e\2\2\u026f"+ + "\u0270\7t\2\2\u0270\u0271\7t\2\2\u0271\u02f4\7c\2\2\u0272\u0273\7d\2\2"+ + "\u0273\u0274\7x\2\2\u0274\u02f4\7u\2\2\u0275\u0276\7u\2\2\u0276\u0277"+ + "\7g\2\2\u0277\u02f4\7k\2\2\u0278\u0279\7u\2\2\u0279\u027a\7c\2\2\u027a"+ + "\u02f4\7z\2\2\u027b\u027c\7u\2\2\u027c\u027d\7v\2\2\u027d\u02f4\7{\2\2"+ + "\u027e\u027f\7u\2\2\u027f\u0280\7v\2\2\u0280\u02f4\7c\2\2\u0281\u0282"+ + "\7u\2\2\u0282\u0283\7v\2\2\u0283\u02f4\7z\2\2\u0284\u0285\7f\2\2\u0285"+ + "\u0286\7g\2\2\u0286\u02f4\7{\2\2\u0287\u0288\7v\2\2\u0288\u0289\7z\2\2"+ + "\u0289\u02f4\7c\2\2\u028a\u028b\7z\2\2\u028b\u028c\7c\2\2\u028c\u02f4"+ + "\7c\2\2\u028d\u028e\7d\2\2\u028e\u028f\7e\2\2\u028f\u02f4\7e\2\2\u0290"+ + "\u0291\7c\2\2\u0291\u0292\7j\2\2\u0292\u02f4\7z\2\2\u0293\u0294\7v\2\2"+ + "\u0294\u0295\7{\2\2\u0295\u02f4\7c\2\2\u0296\u0297\7v\2\2\u0297\u0298"+ + "\7z\2\2\u0298\u02f4\7u\2\2\u0299\u029a\7v\2\2\u029a\u029b\7c\2\2\u029b"+ + "\u02f4\7u\2\2\u029c\u029d\7u\2\2\u029d\u029e\7j\2\2\u029e\u02f4\7{\2\2"+ + "\u029f\u02a0\7u\2\2\u02a0\u02a1\7j\2\2\u02a1\u02f4\7z\2\2\u02a2\u02a3"+ + "\7n\2\2\u02a3\u02a4\7f\2\2\u02a4\u02f4\7{\2\2\u02a5\u02a6\7n\2\2\u02a6"+ + "\u02a7\7f\2\2\u02a7\u02f4\7c\2\2\u02a8\u02a9\7n\2\2\u02a9\u02aa\7f\2\2"+ + "\u02aa\u02f4\7z\2\2\u02ab\u02ac\7n\2\2\u02ac\u02ad\7c\2\2\u02ad\u02f4"+ + "\7z\2\2\u02ae\u02af\7v\2\2\u02af\u02b0\7c\2\2\u02b0\u02f4\7{\2\2\u02b1"+ + "\u02b2\7v\2\2\u02b2\u02b3\7c\2\2\u02b3\u02f4\7z\2\2\u02b4\u02b5\7d\2\2"+ + "\u02b5\u02b6\7e\2\2\u02b6\u02f4\7u\2\2\u02b7\u02b8\7e\2\2\u02b8\u02b9"+ + "\7n\2\2\u02b9\u02f4\7x\2\2\u02ba\u02bb\7v\2\2\u02bb\u02bc\7u\2\2\u02bc"+ + "\u02f4\7z\2\2\u02bd\u02be\7n\2\2\u02be\u02bf\7c\2\2\u02bf\u02f4\7u\2\2"+ + "\u02c0\u02c1\7e\2\2\u02c1\u02c2\7r\2\2\u02c2\u02f4\7{\2\2\u02c3\u02c4"+ + "\7e\2\2\u02c4\u02c5\7o\2\2\u02c5\u02f4\7r\2\2\u02c6\u02c7\7e\2\2\u02c7"+ + "\u02c8\7r\2\2\u02c8\u02f4\7z\2\2\u02c9\u02ca\7f\2\2\u02ca\u02cb\7e\2\2"+ + "\u02cb\u02f4\7r\2\2\u02cc\u02cd\7f\2\2\u02cd\u02ce\7g\2\2\u02ce\u02f4"+ + "\7e\2\2\u02cf\u02d0\7k\2\2\u02d0\u02d1\7p\2\2\u02d1\u02f4\7e\2\2\u02d2"+ + "\u02d3\7c\2\2\u02d3\u02d4\7z\2\2\u02d4\u02f4\7u\2\2\u02d5\u02d6\7d\2\2"+ + "\u02d6\u02d7\7p\2\2\u02d7\u02f4\7g\2\2\u02d8\u02d9\7e\2\2\u02d9\u02da"+ + "\7n\2\2\u02da\u02f4\7f\2\2\u02db\u02dc\7u\2\2\u02dc\u02dd\7d\2\2\u02dd"+ + "\u02f4\7e\2\2\u02de\u02df\7k\2\2\u02df\u02e0\7u\2\2\u02e0\u02f4\7e\2\2"+ + "\u02e1\u02e2\7k\2\2\u02e2\u02e3\7p\2\2\u02e3\u02f4\7z\2\2\u02e4\u02e5"+ + "\7d\2\2\u02e5\u02e6\7g\2\2\u02e6\u02f4\7s\2\2\u02e7\u02e8\7u\2\2\u02e8"+ + "\u02e9\7g\2\2\u02e9\u02f4\7f\2\2\u02ea\u02eb\7f\2\2\u02eb\u02ec\7g\2\2"+ + "\u02ec\u02f4\7z\2\2\u02ed\u02ee\7k\2\2\u02ee\u02ef\7p\2\2\u02ef\u02f4"+ + "\7{\2\2\u02f0\u02f1\7t\2\2\u02f1\u02f2\7q\2\2\u02f2\u02f4\7t\2\2\u02f3"+ + "\u0215\3\2\2\2\u02f3\u0218\3\2\2\2\u02f3\u021b\3\2\2\2\u02f3\u021e\3\2"+ + "\2\2\u02f3\u0221\3\2\2\2\u02f3\u0224\3\2\2\2\u02f3\u0227\3\2\2\2\u02f3"+ + "\u022a\3\2\2\2\u02f3\u022d\3\2\2\2\u02f3\u0230\3\2\2\2\u02f3\u0233\3\2"+ + "\2\2\u02f3\u0236\3\2\2\2\u02f3\u0239\3\2\2\2\u02f3\u023c\3\2\2\2\u02f3"+ + "\u023f\3\2\2\2\u02f3\u0242\3\2\2\2\u02f3\u0245\3\2\2\2\u02f3\u0248\3\2"+ + "\2\2\u02f3\u024b\3\2\2\2\u02f3\u024e\3\2\2\2\u02f3\u0251\3\2\2\2\u02f3"+ + "\u0254\3\2\2\2\u02f3\u0257\3\2\2\2\u02f3\u025a\3\2\2\2\u02f3\u025d\3\2"+ + "\2\2\u02f3\u0260\3\2\2\2\u02f3\u0263\3\2\2\2\u02f3\u0266\3\2\2\2\u02f3"+ + "\u0269\3\2\2\2\u02f3\u026c\3\2\2\2\u02f3\u026f\3\2\2\2\u02f3\u0272\3\2"+ + "\2\2\u02f3\u0275\3\2\2\2\u02f3\u0278\3\2\2\2\u02f3\u027b\3\2\2\2\u02f3"+ + "\u027e\3\2\2\2\u02f3\u0281\3\2\2\2\u02f3\u0284\3\2\2\2\u02f3\u0287\3\2"+ + "\2\2\u02f3\u028a\3\2\2\2\u02f3\u028d\3\2\2\2\u02f3\u0290\3\2\2\2\u02f3"+ + "\u0293\3\2\2\2\u02f3\u0296\3\2\2\2\u02f3\u0299\3\2\2\2\u02f3\u029c\3\2"+ + "\2\2\u02f3\u029f\3\2\2\2\u02f3\u02a2\3\2\2\2\u02f3\u02a5\3\2\2\2\u02f3"+ + "\u02a8\3\2\2\2\u02f3\u02ab\3\2\2\2\u02f3\u02ae\3\2\2\2\u02f3\u02b1\3\2"+ + "\2\2\u02f3\u02b4\3\2\2\2\u02f3\u02b7\3\2\2\2\u02f3\u02ba\3\2\2\2\u02f3"+ + "\u02bd\3\2\2\2\u02f3\u02c0\3\2\2\2\u02f3\u02c3\3\2\2\2\u02f3\u02c6\3\2"+ + "\2\2\u02f3\u02c9\3\2\2\2\u02f3\u02cc\3\2\2\2\u02f3\u02cf\3\2\2\2\u02f3"+ + "\u02d2\3\2\2\2\u02f3\u02d5\3\2\2\2\u02f3\u02d8\3\2\2\2\u02f3\u02db\3\2"+ + "\2\2\u02f3\u02de\3\2\2\2\u02f3\u02e1\3\2\2\2\u02f3\u02e4\3\2\2\2\u02f3"+ + "\u02e7\3\2\2\2\u02f3\u02ea\3\2\2\2\u02f3\u02ed\3\2\2\2\u02f3\u02f0\3\2"+ + "\2\2\u02f4\u00a0\3\2\2\2\u02f5\u02f6\7}\2\2\u02f6\u02f7\7}\2\2\u02f7\u02fb"+ + "\3\2\2\2\u02f8\u02fa\13\2\2\2\u02f9\u02f8\3\2\2\2\u02fa\u02fd\3\2\2\2"+ + "\u02fb\u02fc\3\2\2\2\u02fb\u02f9\3\2\2\2\u02fc\u02fe\3\2\2\2\u02fd\u02fb"+ + "\3\2\2\2\u02fe\u02ff\7\177\2\2\u02ff\u0300\7\177\2\2\u0300\u00a2\3\2\2"+ + "\2\u0301\u0302\7d\2\2\u0302\u0303\7{\2\2\u0303\u0304\7v\2\2\u0304\u0327"+ + "\7g\2\2\u0305\u0306\7y\2\2\u0306\u0307\7q\2\2\u0307\u0308\7t\2\2\u0308"+ + "\u0327\7f\2\2\u0309\u030a\7f\2\2\u030a\u030b\7y\2\2\u030b\u030c\7q\2\2"+ + "\u030c\u030d\7t\2\2\u030d\u0327\7f\2\2\u030e\u030f\7d\2\2\u030f\u0310"+ + "\7q\2\2\u0310\u0311\7q\2\2\u0311\u0327\7n\2\2\u0312\u0313\7e\2\2\u0313"+ + "\u0314\7j\2\2\u0314\u0315\7c\2\2\u0315\u0327\7t\2\2\u0316\u0317\7u\2\2"+ + "\u0317\u0318\7j\2\2\u0318\u0319\7q\2\2\u0319\u031a\7t\2\2\u031a\u0327"+ + "\7v\2\2\u031b\u031c\7k\2\2\u031c\u031d\7p\2\2\u031d\u0327\7v\2\2\u031e"+ + "\u031f\7n\2\2\u031f\u0320\7q\2\2\u0320\u0321\7p\2\2\u0321\u0327\7i\2\2"+ + "\u0322\u0323\7x\2\2\u0323\u0324\7q\2\2\u0324\u0325\7k\2\2\u0325\u0327"+ + "\7f\2\2\u0326\u0301\3\2\2\2\u0326\u0305\3\2\2\2\u0326\u0309\3\2\2\2\u0326"+ + "\u030e\3\2\2\2\u0326\u0312\3\2\2\2\u0326\u0316\3\2\2\2\u0326\u031b\3\2"+ + "\2\2\u0326\u031e\3\2\2\2\u0326\u0322\3\2\2\2\u0327\u00a4\3\2\2\2\u0328"+ + "\u032e\7$\2\2\u0329\u032a\7^\2\2\u032a\u032d\7$\2\2\u032b\u032d\n\2\2"+ + "\2\u032c\u0329\3\2\2\2\u032c\u032b\3\2\2\2\u032d\u0330\3\2\2\2\u032e\u032c"+ + "\3\2\2\2\u032e\u032f\3\2\2\2\u032f\u0331\3\2\2\2\u0330\u032e\3\2\2\2\u0331"+ + "\u0333\7$\2\2\u0332\u0334\7|\2\2\u0333\u0332\3\2\2\2\u0333\u0334\3\2\2"+ + "\2\u0334\u00a6\3\2\2\2\u0335\u0339\7)\2\2\u0336\u0337\7^\2\2\u0337\u033a"+ + "\7)\2\2\u0338\u033a\n\3\2\2\u0339\u0336\3\2\2\2\u0339\u0338\3\2\2\2\u033a"+ + "\u033b\3\2\2\2\u033b\u033c\7)\2\2\u033c\u00a8\3\2\2\2\u033d\u033e\7v\2"+ + "\2\u033e\u033f\7t\2\2\u033f\u0340\7w\2\2\u0340\u0347\7g\2\2\u0341\u0342"+ + "\7h\2\2\u0342\u0343\7c\2\2\u0343\u0344\7n\2\2\u0344\u0345\7u\2\2\u0345"+ + "\u0347\7g\2\2\u0346\u033d\3\2\2\2\u0346\u0341\3\2\2\2\u0347\u00aa\3\2"+ + "\2\2\u0348\u034b\5\u00adW\2\u0349\u034b\5\u00b5[\2\u034a\u0348\3\2\2\2"+ + "\u034a\u0349\3\2\2\2\u034b\u00ac\3\2\2\2\u034c\u0350\5\u00afX\2\u034d"+ + "\u0350\5\u00b1Y\2\u034e\u0350\5\u00b3Z\2\u034f\u034c\3\2\2\2\u034f\u034d"+ + "\3\2\2\2\u034f\u034e\3\2\2\2\u0350\u00ae\3\2\2\2\u0351\u0357\7\'\2\2\u0352"+ + "\u0353\7\62\2\2\u0353\u0357\7d\2\2\u0354\u0355\7\62\2\2\u0355\u0357\7"+ + "D\2\2\u0356\u0351\3\2\2\2\u0356\u0352\3\2\2\2\u0356\u0354\3\2\2\2\u0357"+ + "\u035b\3\2\2\2\u0358\u035a\5\u00bd_\2\u0359\u0358\3\2\2\2\u035a\u035d"+ + "\3\2\2\2\u035b\u0359\3\2\2\2\u035b\u035c\3\2\2\2\u035c\u035e\3\2\2\2\u035d"+ + "\u035b\3\2\2\2\u035e\u0360\7\60\2\2\u035f\u0361\5\u00bd_\2\u0360\u035f"+ + "\3\2\2\2\u0361\u0362\3\2\2\2\u0362\u0360\3\2\2\2\u0362\u0363\3\2\2\2\u0363"+ + "\u00b0\3\2\2\2\u0364\u0366\5\u00bf`\2\u0365\u0364\3\2\2\2\u0366\u0369"+ + "\3\2\2\2\u0367\u0365\3\2\2\2\u0367\u0368\3\2\2\2\u0368\u036a\3\2\2\2\u0369"+ + "\u0367\3\2\2\2\u036a\u036c\7\60\2\2\u036b\u036d\5\u00bf`\2\u036c\u036b"+ + "\3\2\2\2\u036d\u036e\3\2\2\2\u036e\u036c\3\2\2\2\u036e\u036f\3\2\2\2\u036f"+ + "\u00b2\3\2\2\2\u0370\u0376\7&\2\2\u0371\u0372\7\62\2\2\u0372\u0376\7z"+ + "\2\2\u0373\u0374\7\62\2\2\u0374\u0376\7Z\2\2\u0375\u0370\3\2\2\2\u0375"+ + "\u0371\3\2\2\2\u0375\u0373\3\2\2\2\u0376\u037a\3\2\2\2\u0377\u0379\5\u00c1"+ + "a\2\u0378\u0377\3\2\2\2\u0379\u037c\3\2\2\2\u037a\u0378\3\2\2\2\u037a"+ + "\u037b\3\2\2\2\u037b\u037d\3\2\2\2\u037c\u037a\3\2\2\2\u037d\u037f\7\60"+ + "\2\2\u037e\u0380\5\u00c1a\2\u037f\u037e\3\2\2\2\u0380\u0381\3\2\2\2\u0381"+ + "\u037f\3\2\2\2\u0381\u0382\3\2\2\2\u0382\u00b4\3\2\2\2\u0383\u0387\5\u00b9"+ + "]\2\u0384\u0387\5\u00bb^\2\u0385\u0387\5\u00b7\\\2\u0386\u0383\3\2\2\2"+ + "\u0386\u0384\3\2\2\2\u0386\u0385\3\2\2\2\u0387\u038b\3\2\2\2\u0388\u0389"+ + "\t\4\2\2\u0389\u038c\t\5\2\2\u038a\u038c\7n\2\2\u038b\u0388\3\2\2\2\u038b"+ + "\u038a\3\2\2\2\u038b\u038c\3\2\2\2\u038c\u00b6\3\2\2\2\u038d\u038e\7\62"+ + "\2\2\u038e\u0390\t\6\2\2\u038f\u0391\5\u00bd_\2\u0390\u038f\3\2\2\2\u0391"+ + "\u0392\3\2\2\2\u0392\u0390\3\2\2\2\u0392\u0393\3\2\2\2\u0393\u039b\3\2"+ + "\2\2\u0394\u0396\7\'\2\2\u0395\u0397\5\u00bd_\2\u0396\u0395\3\2\2\2\u0397"+ + "\u0398\3\2\2\2\u0398\u0396\3\2\2\2\u0398\u0399\3\2\2\2\u0399\u039b\3\2"+ + "\2\2\u039a\u038d\3\2\2\2\u039a\u0394\3\2\2\2\u039b\u00b8\3\2\2\2\u039c"+ + "\u039e\5\u00bf`\2\u039d\u039c\3\2\2\2\u039e\u039f\3\2\2\2\u039f\u039d"+ + "\3\2\2\2\u039f\u03a0\3\2\2\2\u03a0\u00ba\3\2\2\2\u03a1\u03a7\7&\2\2\u03a2"+ + "\u03a3\7\62\2\2\u03a3\u03a7\7z\2\2\u03a4\u03a5\7\62\2\2\u03a5\u03a7\7"+ + "Z\2\2\u03a6\u03a1\3\2\2\2\u03a6\u03a2\3\2\2\2\u03a6\u03a4\3\2\2\2\u03a7"+ + "\u03a9\3\2\2\2\u03a8\u03aa\5\u00c1a\2\u03a9\u03a8\3\2\2\2\u03aa\u03ab"+ + "\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u00bc\3\2\2\2\u03ad"+ + "\u03ae\t\7\2\2\u03ae\u00be\3\2\2\2\u03af\u03b0\t\b\2\2\u03b0\u00c0\3\2"+ + "\2\2\u03b1\u03b2\t\t\2\2\u03b2\u00c2\3\2\2\2\u03b3\u03b7\5\u00c5c\2\u03b4"+ + "\u03b6\5\u00c7d\2\u03b5\u03b4\3\2\2\2\u03b6\u03b9\3\2\2\2\u03b7\u03b5"+ + "\3\2\2\2\u03b7\u03b8\3\2\2\2\u03b8\u00c4\3\2\2\2\u03b9\u03b7\3\2\2\2\u03ba"+ + "\u03bb\t\n\2\2\u03bb\u00c6\3\2\2\2\u03bc\u03bd\t\13\2\2\u03bd\u00c8\3"+ + "\2\2\2\u03be\u03c2\7#\2\2\u03bf\u03c1\5\u00c7d\2\u03c0\u03bf\3\2\2\2\u03c1"+ + "\u03c4\3\2\2\2\u03c2\u03c0\3\2\2\2\u03c2\u03c3\3\2\2\2\u03c3\u03c6\3\2"+ + "\2\2\u03c4\u03c2\3\2\2\2\u03c5\u03c7\t\f\2\2\u03c6\u03c5\3\2\2\2\u03c7"+ + "\u03c8\3\2\2\2\u03c8\u03c6\3\2\2\2\u03c8\u03c9\3\2\2\2\u03c9\u00ca\3\2"+ + "\2\2\u03ca\u03cc\t\r\2\2\u03cb\u03ca\3\2\2\2\u03cc\u03cd\3\2\2\2\u03cd"+ + "\u03cb\3\2\2\2\u03cd\u03ce\3\2\2\2\u03ce\u03cf\3\2\2\2\u03cf\u03d0\bf"+ + "\2\2\u03d0\u00cc\3\2\2\2\u03d1\u03d2\7\61\2\2\u03d2\u03d3\7\61\2\2\u03d3"+ + "\u03d7\3\2\2\2\u03d4\u03d6\n\16\2\2\u03d5\u03d4\3\2\2\2\u03d6\u03d9\3"+ + "\2\2\2\u03d7\u03d5\3\2\2\2\u03d7\u03d8\3\2\2\2\u03d8\u03da\3\2\2\2\u03d9"+ + "\u03d7\3\2\2\2\u03da\u03db\bg\3\2\u03db\u00ce\3\2\2\2\u03dc\u03dd\7\61"+ + "\2\2\u03dd\u03de\7,\2\2\u03de\u03e2\3\2\2\2\u03df\u03e1\13\2\2\2\u03e0"+ + "\u03df\3\2\2\2\u03e1\u03e4\3\2\2\2\u03e2\u03e3\3\2\2\2\u03e2\u03e0\3\2"+ + "\2\2\u03e3\u03e5\3\2\2\2\u03e4\u03e2\3\2\2\2\u03e5\u03e6\7,\2\2\u03e6"+ + "\u03e7\7\61\2\2\u03e7\u03e8\3\2\2\2\u03e8\u03e9\bh\3\2\u03e9\u00d0\3\2"+ + "\2\2#\2\u02f3\u02fb\u0326\u032c\u032e\u0333\u0339\u0346\u034a\u034f\u0356"+ + "\u035b\u0362\u0367\u036e\u0375\u037a\u0381\u0386\u038b\u0392\u0398\u039a"+ + "\u039f\u03a6\u03ab\u03b7\u03c2\u03c8\u03cd\u03d7\u03e2\4\2\3\2\2\4\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens index c69744d23..42dfa728a 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens +++ b/src/main/java/dk/camelot64/kickc/parser/KickCLexer.tokens @@ -74,26 +74,28 @@ T__72=73 T__73=74 T__74=75 T__75=76 -MNEMONIC=77 -KICKASM=78 -SIMPLETYPE=79 -STRING=80 -CHAR=81 -BOOLEAN=82 -NUMBER=83 -NUMFLOAT=84 -BINFLOAT=85 -DECFLOAT=86 -HEXFLOAT=87 -NUMINT=88 -BININTEGER=89 -DECINTEGER=90 -HEXINTEGER=91 -NAME=92 -ASMREL=93 -WS=94 -COMMENT_LINE=95 -COMMENT_BLOCK=96 +T__76=77 +T__77=78 +MNEMONIC=79 +KICKASM=80 +SIMPLETYPE=81 +STRING=82 +CHAR=83 +BOOLEAN=84 +NUMBER=85 +NUMFLOAT=86 +BINFLOAT=87 +DECFLOAT=88 +HEXFLOAT=89 +NUMINT=90 +BININTEGER=91 +DECINTEGER=92 +HEXINTEGER=93 +NAME=94 +ASMREL=95 +WS=96 +COMMENT_LINE=97 +COMMENT_BLOCK=98 'import'=1 ';'=2 ','=3 @@ -126,47 +128,49 @@ COMMENT_BLOCK=96 '*'=30 '['=31 ']'=32 -'sizeof'=33 -'typeid'=34 -'--'=35 -'++'=36 -'+'=37 -'-'=38 -'!'=39 -'&'=40 -'~'=41 -'>>'=42 -'<<'=43 -'/'=44 -'%'=45 -'<'=46 -'>'=47 -'=='=48 -'!='=49 -'<='=50 -'>='=51 -'^'=52 -'|'=53 -'&&'=54 -'||'=55 -'?'=56 -'+='=57 -'-='=58 -'*='=59 -'/='=60 -'%='=61 -'<<='=62 -'>>='=63 -'&='=64 -'|='=65 -'^='=66 -'kickasm'=67 -'resource'=68 -'uses'=69 -'clobbers'=70 -'bytes'=71 -'cycles'=72 -'pc'=73 -'.byte'=74 -'#'=75 -'.'=76 +'struct'=33 +'.'=34 +'->'=35 +'sizeof'=36 +'typeid'=37 +'--'=38 +'++'=39 +'+'=40 +'-'=41 +'!'=42 +'&'=43 +'~'=44 +'>>'=45 +'<<'=46 +'/'=47 +'%'=48 +'<'=49 +'>'=50 +'=='=51 +'!='=52 +'<='=53 +'>='=54 +'^'=55 +'|'=56 +'&&'=57 +'||'=58 +'?'=59 +'+='=60 +'-='=61 +'*='=62 +'/='=63 +'%='=64 +'<<='=65 +'>>='=66 +'&='=67 +'|='=68 +'^='=69 +'kickasm'=70 +'resource'=71 +'uses'=72 +'clobbers'=73 +'bytes'=74 +'cycles'=75 +'pc'=76 +'.byte'=77 +'#'=78 diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCListener.java b/src/main/java/dk/camelot64/kickc/parser/KickCListener.java index aef2c95a7..24069cabb 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCListener.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCListener.java @@ -1,4 +1,4 @@ -// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7 +// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7 package dk.camelot64.kickc.parser; import org.antlr.v4.runtime.tree.ParseTreeListener; @@ -517,6 +517,18 @@ public interface KickCListener extends ParseTreeListener { * @param ctx the parse tree */ void exitTypeArray(KickCParser.TypeArrayContext ctx); + /** + * Enter a parse tree produced by the {@code typeStructRef} + * labeled alternative in {@link KickCParser#typeDecl}. + * @param ctx the parse tree + */ + void enterTypeStructRef(KickCParser.TypeStructRefContext ctx); + /** + * Exit a parse tree produced by the {@code typeStructRef} + * labeled alternative in {@link KickCParser#typeDecl}. + * @param ctx the parse tree + */ + void exitTypeStructRef(KickCParser.TypeStructRefContext ctx); /** * Enter a parse tree produced by the {@code typeSimple} * labeled alternative in {@link KickCParser#typeDecl}. @@ -529,6 +541,18 @@ public interface KickCListener extends ParseTreeListener { * @param ctx the parse tree */ void exitTypeSimple(KickCParser.TypeSimpleContext ctx); + /** + * Enter a parse tree produced by the {@code typeStructDef} + * labeled alternative in {@link KickCParser#typeDecl}. + * @param ctx the parse tree + */ + void enterTypeStructDef(KickCParser.TypeStructDefContext ctx); + /** + * Exit a parse tree produced by the {@code typeStructDef} + * labeled alternative in {@link KickCParser#typeDecl}. + * @param ctx the parse tree + */ + void exitTypeStructDef(KickCParser.TypeStructDefContext ctx); /** * Enter a parse tree produced by the {@code typeSignedSimple} * labeled alternative in {@link KickCParser#typeDecl}. @@ -541,6 +565,36 @@ public interface KickCListener extends ParseTreeListener { * @param ctx the parse tree */ void exitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx); + /** + * Enter a parse tree produced by {@link KickCParser#structRef}. + * @param ctx the parse tree + */ + void enterStructRef(KickCParser.StructRefContext ctx); + /** + * Exit a parse tree produced by {@link KickCParser#structRef}. + * @param ctx the parse tree + */ + void exitStructRef(KickCParser.StructRefContext ctx); + /** + * Enter a parse tree produced by {@link KickCParser#structDef}. + * @param ctx the parse tree + */ + void enterStructDef(KickCParser.StructDefContext ctx); + /** + * Exit a parse tree produced by {@link KickCParser#structDef}. + * @param ctx the parse tree + */ + void exitStructDef(KickCParser.StructDefContext ctx); + /** + * Enter a parse tree produced by {@link KickCParser#structMembers}. + * @param ctx the parse tree + */ + void enterStructMembers(KickCParser.StructMembersContext ctx); + /** + * Exit a parse tree produced by {@link KickCParser#structMembers}. + * @param ctx the parse tree + */ + void exitStructMembers(KickCParser.StructMembersContext ctx); /** * Enter a parse tree produced by the {@code commaNone} * labeled alternative in {@link KickCParser#commaExpr}. @@ -661,6 +715,30 @@ public interface KickCListener extends ParseTreeListener { * @param ctx the parse tree */ void exitExprChar(KickCParser.ExprCharContext ctx); + /** + * Enter a parse tree produced by the {@code exprArrow} + * labeled alternative in {@link KickCParser#expr}. + * @param ctx the parse tree + */ + void enterExprArrow(KickCParser.ExprArrowContext ctx); + /** + * Exit a parse tree produced by the {@code exprArrow} + * labeled alternative in {@link KickCParser#expr}. + * @param ctx the parse tree + */ + void exitExprArrow(KickCParser.ExprArrowContext ctx); + /** + * Enter a parse tree produced by the {@code exprDot} + * labeled alternative in {@link KickCParser#expr}. + * @param ctx the parse tree + */ + void enterExprDot(KickCParser.ExprDotContext ctx); + /** + * Exit a parse tree produced by the {@code exprDot} + * labeled alternative in {@link KickCParser#expr}. + * @param ctx the parse tree + */ + void exitExprDot(KickCParser.ExprDotContext ctx); /** * Enter a parse tree produced by the {@code initList} * labeled alternative in {@link KickCParser#expr}. diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCParser.java b/src/main/java/dk/camelot64/kickc/parser/KickCParser.java index 383fd8a0a..57be1778b 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCParser.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCParser.java @@ -1,4 +1,4 @@ -// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7 +// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7 package dk.camelot64.kickc.parser; import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.dfa.DFA; @@ -27,29 +27,30 @@ public class KickCParser extends Parser { T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59, T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66, T__66=67, T__67=68, T__68=69, T__69=70, T__70=71, T__71=72, T__72=73, - T__73=74, T__74=75, T__75=76, MNEMONIC=77, KICKASM=78, SIMPLETYPE=79, - STRING=80, CHAR=81, BOOLEAN=82, NUMBER=83, NUMFLOAT=84, BINFLOAT=85, DECFLOAT=86, - HEXFLOAT=87, NUMINT=88, BININTEGER=89, DECINTEGER=90, HEXINTEGER=91, NAME=92, - ASMREL=93, WS=94, COMMENT_LINE=95, COMMENT_BLOCK=96; + T__73=74, T__74=75, T__75=76, T__76=77, T__77=78, MNEMONIC=79, KICKASM=80, + SIMPLETYPE=81, STRING=82, CHAR=83, BOOLEAN=84, NUMBER=85, NUMFLOAT=86, + BINFLOAT=87, DECFLOAT=88, HEXFLOAT=89, NUMINT=90, BININTEGER=91, DECINTEGER=92, + HEXINTEGER=93, NAME=94, ASMREL=95, WS=96, COMMENT_LINE=97, COMMENT_BLOCK=98; public static final int RULE_file = 0, RULE_asmFile = 1, RULE_importSeq = 2, RULE_importDecl = 3, RULE_declSeq = 4, RULE_decl = 5, RULE_declTypes = 6, RULE_declVariables = 7, RULE_declVariableList = 8, RULE_declVariableInit = 9, RULE_declFunction = 10, RULE_parameterListDecl = 11, RULE_parameterDecl = 12, RULE_globalDirective = 13, RULE_directive = 14, RULE_directiveReserve = 15, RULE_stmtSeq = 16, RULE_stmt = 17, - RULE_forLoop = 18, RULE_forClassicInit = 19, RULE_typeDecl = 20, RULE_commaExpr = 21, - RULE_expr = 22, RULE_parameterList = 23, RULE_declKasm = 24, RULE_asmDirectives = 25, - RULE_asmDirective = 26, RULE_asmLines = 27, RULE_asmLine = 28, RULE_asmLabel = 29, - RULE_asmInstruction = 30, RULE_asmBytes = 31, RULE_asmParamMode = 32, - RULE_asmExpr = 33; + RULE_forLoop = 18, RULE_forClassicInit = 19, RULE_typeDecl = 20, RULE_structRef = 21, + RULE_structDef = 22, RULE_structMembers = 23, RULE_commaExpr = 24, RULE_expr = 25, + RULE_parameterList = 26, RULE_declKasm = 27, RULE_asmDirectives = 28, + RULE_asmDirective = 29, RULE_asmLines = 30, RULE_asmLine = 31, RULE_asmLabel = 32, + RULE_asmInstruction = 33, RULE_asmBytes = 34, RULE_asmParamMode = 35, + RULE_asmExpr = 36; public static final String[] ruleNames = { "file", "asmFile", "importSeq", "importDecl", "declSeq", "decl", "declTypes", "declVariables", "declVariableList", "declVariableInit", "declFunction", "parameterListDecl", "parameterDecl", "globalDirective", "directive", "directiveReserve", "stmtSeq", "stmt", "forLoop", "forClassicInit", "typeDecl", - "commaExpr", "expr", "parameterList", "declKasm", "asmDirectives", "asmDirective", - "asmLines", "asmLine", "asmLabel", "asmInstruction", "asmBytes", "asmParamMode", - "asmExpr" + "structRef", "structDef", "structMembers", "commaExpr", "expr", "parameterList", + "declKasm", "asmDirectives", "asmDirective", "asmLines", "asmLine", "asmLabel", + "asmInstruction", "asmBytes", "asmParamMode", "asmExpr" }; private static final String[] _LITERAL_NAMES = { @@ -57,12 +58,12 @@ public class KickCParser extends Parser { "'extern'", "'align'", "'register'", "'inline'", "'volatile'", "'interrupt'", "'reserve'", "'if'", "'else'", "'while'", "'do'", "'for'", "'return'", "'break'", "'continue'", "'asm'", "':'", "'..'", "'signed'", "'unsigned'", - "'*'", "'['", "']'", "'sizeof'", "'typeid'", "'--'", "'++'", "'+'", "'-'", - "'!'", "'&'", "'~'", "'>>'", "'<<'", "'/'", "'%'", "'<'", "'>'", "'=='", - "'!='", "'<='", "'>='", "'^'", "'|'", "'&&'", "'||'", "'?'", "'+='", "'-='", - "'*='", "'/='", "'%='", "'<<='", "'>>='", "'&='", "'|='", "'^='", "'kickasm'", - "'resource'", "'uses'", "'clobbers'", "'bytes'", "'cycles'", "'pc'", "'.byte'", - "'#'", "'.'" + "'*'", "'['", "']'", "'struct'", "'.'", "'->'", "'sizeof'", "'typeid'", + "'--'", "'++'", "'+'", "'-'", "'!'", "'&'", "'~'", "'>>'", "'<<'", "'/'", + "'%'", "'<'", "'>'", "'=='", "'!='", "'<='", "'>='", "'^'", "'|'", "'&&'", + "'||'", "'?'", "'+='", "'-='", "'*='", "'/='", "'%='", "'<<='", "'>>='", + "'&='", "'|='", "'^='", "'kickasm'", "'resource'", "'uses'", "'clobbers'", + "'bytes'", "'cycles'", "'pc'", "'.byte'", "'#'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, null, null, null, null, null, null, null, @@ -71,10 +72,10 @@ public class KickCParser extends Parser { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE", "STRING", - "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", "HEXFLOAT", - "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", "ASMREL", - "WS", "COMMENT_LINE", "COMMENT_BLOCK" + null, null, null, null, null, null, null, "MNEMONIC", "KICKASM", "SIMPLETYPE", + "STRING", "CHAR", "BOOLEAN", "NUMBER", "NUMFLOAT", "BINFLOAT", "DECFLOAT", + "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER", "NAME", + "ASMREL", "WS", "COMMENT_LINE", "COMMENT_BLOCK" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -158,11 +159,11 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(68); + setState(74); importSeq(); - setState(69); + setState(75); declSeq(); - setState(70); + setState(76); match(EOF); } } @@ -207,9 +208,9 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(72); + setState(78); asmLines(); - setState(73); + setState(79); match(EOF); } } @@ -257,17 +258,17 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(78); + setState(84); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__0) { { { - setState(75); + setState(81); importDecl(); } } - setState(80); + setState(86); _errHandler.sync(this); _la = _input.LA(1); } @@ -311,9 +312,9 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(81); + setState(87); match(T__0); - setState(82); + setState(88); match(STRING); } } @@ -361,20 +362,20 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(85); + setState(91); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(84); + setState(90); decl(); } } - setState(87); + setState(93); _errHandler.sync(this); _la = _input.LA(1); - } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28))) != 0) || _la==T__66 || _la==SIMPLETYPE ); + } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28) | (1L << T__32))) != 0) || _la==T__69 || _la==SIMPLETYPE ); } } catch (RecognitionException re) { @@ -392,6 +393,9 @@ public class KickCParser extends Parser { public DeclVariablesContext declVariables() { return getRuleContext(DeclVariablesContext.class,0); } + public StructDefContext structDef() { + return getRuleContext(StructDefContext.class,0); + } public DeclFunctionContext declFunction() { return getRuleContext(DeclFunctionContext.class,0); } @@ -424,36 +428,45 @@ public class KickCParser extends Parser { DeclContext _localctx = new DeclContext(_ctx, getState()); enterRule(_localctx, 10, RULE_decl); try { - setState(95); + setState(104); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(89); + setState(95); declVariables(); - setState(90); + setState(96); match(T__1); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(92); - declFunction(); + setState(98); + structDef(); + setState(99); + match(T__1); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(93); - declKasm(); + setState(101); + declFunction(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(94); + setState(102); + declKasm(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(103); globalDirective(); } break; @@ -506,33 +519,33 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(100); + setState(109); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) { { { - setState(97); + setState(106); directive(); } } - setState(102); + setState(111); _errHandler.sync(this); _la = _input.LA(1); } - setState(103); + setState(112); typeDecl(0); - setState(107); + setState(116); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) { { { - setState(104); + setState(113); directive(); } } - setState(109); + setState(118); _errHandler.sync(this); _la = _input.LA(1); } @@ -581,9 +594,9 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(110); + setState(119); declTypes(); - setState(111); + setState(120); declVariableList(0); } } @@ -640,11 +653,11 @@ public class KickCParser extends Parser { enterOuterAlt(_localctx, 1); { { - setState(114); + setState(123); declVariableInit(); } _ctx.stop = _input.LT(-1); - setState(121); + setState(130); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,5,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -655,16 +668,16 @@ public class KickCParser extends Parser { { _localctx = new DeclVariableListContext(_parentctx, _parentState); pushNewRecursionContext(_localctx, _startState, RULE_declVariableList); - setState(116); + setState(125); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(117); + setState(126); match(T__2); - setState(118); + setState(127); declVariableInit(); } } } - setState(123); + setState(132); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,5,_ctx); } @@ -711,16 +724,16 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(124); + setState(133); match(NAME); - setState(127); + setState(136); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { case 1: { - setState(125); + setState(134); match(T__3); - setState(126); + setState(135); expr(0); } break; @@ -775,37 +788,37 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(129); + setState(138); declTypes(); - setState(130); + setState(139); match(NAME); - setState(131); + setState(140); match(T__4); - setState(133); + setState(142); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28))) != 0) || _la==SIMPLETYPE) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28) | (1L << T__32))) != 0) || _la==SIMPLETYPE) { { - setState(132); + setState(141); parameterListDecl(); } } - setState(135); + setState(144); match(T__5); - setState(136); + setState(145); match(T__6); - setState(138); + setState(147); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (T__66 - 67)) | (1L << (SIMPLETYPE - 67)) | (1L << (STRING - 67)) | (1L << (CHAR - 67)) | (1L << (BOOLEAN - 67)) | (1L << (NUMBER - 67)) | (1L << (NAME - 67)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__32) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 70)) & ~0x3f) == 0 && ((1L << (_la - 70)) & ((1L << (T__69 - 70)) | (1L << (SIMPLETYPE - 70)) | (1L << (STRING - 70)) | (1L << (CHAR - 70)) | (1L << (BOOLEAN - 70)) | (1L << (NUMBER - 70)) | (1L << (NAME - 70)))) != 0)) { { - setState(137); + setState(146); stmtSeq(); } } - setState(140); + setState(149); match(T__7); } } @@ -853,21 +866,21 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(142); + setState(151); parameterDecl(); - setState(147); + setState(156); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(143); + setState(152); match(T__2); - setState(144); + setState(153); parameterDecl(); } } - setState(149); + setState(158); _errHandler.sync(this); _la = _input.LA(1); } @@ -937,16 +950,16 @@ public class KickCParser extends Parser { ParameterDeclContext _localctx = new ParameterDeclContext(_ctx, getState()); enterRule(_localctx, 24, RULE_parameterDecl); try { - setState(154); + setState(163); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: _localctx = new ParameterDeclTypeContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(150); + setState(159); declTypes(); - setState(151); + setState(160); match(NAME); } break; @@ -954,7 +967,7 @@ public class KickCParser extends Parser { _localctx = new ParameterDeclVoidContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(153); + setState(162); match(SIMPLETYPE); } break; @@ -1000,9 +1013,9 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(156); + setState(165); directiveReserve(); - setState(157); + setState(166); match(T__1); } } @@ -1167,14 +1180,14 @@ public class KickCParser extends Parser { DirectiveContext _localctx = new DirectiveContext(_ctx, getState()); enterRule(_localctx, 28, RULE_directive); try { - setState(178); + setState(187); _errHandler.sync(this); switch (_input.LA(1)) { case T__8: _localctx = new DirectiveConstContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(159); + setState(168); match(T__8); } break; @@ -1182,7 +1195,7 @@ public class KickCParser extends Parser { _localctx = new DirectiveExternContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(160); + setState(169); match(T__9); } break; @@ -1190,13 +1203,13 @@ public class KickCParser extends Parser { _localctx = new DirectiveAlignContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(161); + setState(170); match(T__10); - setState(162); + setState(171); match(T__4); - setState(163); + setState(172); match(NUMBER); - setState(164); + setState(173); match(T__5); } break; @@ -1204,13 +1217,13 @@ public class KickCParser extends Parser { _localctx = new DirectiveRegisterContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(165); + setState(174); match(T__11); - setState(166); + setState(175); match(T__4); - setState(167); + setState(176); match(NAME); - setState(168); + setState(177); match(T__5); } break; @@ -1218,7 +1231,7 @@ public class KickCParser extends Parser { _localctx = new DirectiveInlineContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(169); + setState(178); match(T__12); } break; @@ -1226,7 +1239,7 @@ public class KickCParser extends Parser { _localctx = new DirectiveVolatileContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(170); + setState(179); match(T__13); } break; @@ -1234,18 +1247,18 @@ public class KickCParser extends Parser { _localctx = new DirectiveInterruptContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(171); + setState(180); match(T__14); - setState(175); + setState(184); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { case 1: { - setState(172); + setState(181); match(T__4); - setState(173); + setState(182); match(NAME); - setState(174); + setState(183); match(T__5); } break; @@ -1256,7 +1269,7 @@ public class KickCParser extends Parser { _localctx = new DirectiveReserveZpContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(177); + setState(186); directiveReserve(); } break; @@ -1306,29 +1319,29 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(180); + setState(189); match(T__15); - setState(181); + setState(190); match(T__4); - setState(182); + setState(191); match(NUMBER); - setState(187); + setState(196); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(183); + setState(192); match(T__2); - setState(184); + setState(193); match(NUMBER); } } - setState(189); + setState(198); _errHandler.sync(this); _la = _input.LA(1); } - setState(190); + setState(199); match(T__5); } } @@ -1376,20 +1389,20 @@ public class KickCParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(193); + setState(202); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(192); + setState(201); stmt(); } } - setState(195); + setState(204); _errHandler.sync(this); _la = _input.LA(1); - } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (T__66 - 67)) | (1L << (SIMPLETYPE - 67)) | (1L << (STRING - 67)) | (1L << (CHAR - 67)) | (1L << (BOOLEAN - 67)) | (1L << (NUMBER - 67)) | (1L << (NAME - 67)))) != 0) ); + } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__32) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 70)) & ~0x3f) == 0 && ((1L << (_la - 70)) & ((1L << (T__69 - 70)) | (1L << (SIMPLETYPE - 70)) | (1L << (STRING - 70)) | (1L << (CHAR - 70)) | (1L << (BOOLEAN - 70)) | (1L << (NUMBER - 70)) | (1L << (NAME - 70)))) != 0) ); } } catch (RecognitionException re) { @@ -1678,16 +1691,16 @@ public class KickCParser extends Parser { enterRule(_localctx, 34, RULE_stmt); int _la; try { - setState(273); + setState(282); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { case 1: _localctx = new StmtDeclVarContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(197); + setState(206); declVariables(); - setState(198); + setState(207); match(T__1); } break; @@ -1695,19 +1708,19 @@ public class KickCParser extends Parser { _localctx = new StmtBlockContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(200); + setState(209); match(T__6); - setState(202); + setState(211); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (T__66 - 67)) | (1L << (SIMPLETYPE - 67)) | (1L << (STRING - 67)) | (1L << (CHAR - 67)) | (1L << (BOOLEAN - 67)) | (1L << (NUMBER - 67)) | (1L << (NAME - 67)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__16) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22) | (1L << T__23) | (1L << T__24) | (1L << T__27) | (1L << T__28) | (1L << T__29) | (1L << T__32) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 70)) & ~0x3f) == 0 && ((1L << (_la - 70)) & ((1L << (T__69 - 70)) | (1L << (SIMPLETYPE - 70)) | (1L << (STRING - 70)) | (1L << (CHAR - 70)) | (1L << (BOOLEAN - 70)) | (1L << (NUMBER - 70)) | (1L << (NAME - 70)))) != 0)) { { - setState(201); + setState(210); stmtSeq(); } } - setState(204); + setState(213); match(T__7); } break; @@ -1715,9 +1728,9 @@ public class KickCParser extends Parser { _localctx = new StmtExprContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(205); + setState(214); commaExpr(0); - setState(206); + setState(215); match(T__1); } break; @@ -1725,24 +1738,24 @@ public class KickCParser extends Parser { _localctx = new StmtIfElseContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(208); + setState(217); match(T__16); - setState(209); + setState(218); match(T__4); - setState(210); + setState(219); commaExpr(0); - setState(211); + setState(220); match(T__5); - setState(212); + setState(221); stmt(); - setState(215); + setState(224); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { case 1: { - setState(213); + setState(222); match(T__17); - setState(214); + setState(223); stmt(); } break; @@ -1753,29 +1766,29 @@ public class KickCParser extends Parser { _localctx = new StmtWhileContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(220); + setState(229); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) { { { - setState(217); + setState(226); directive(); } } - setState(222); + setState(231); _errHandler.sync(this); _la = _input.LA(1); } - setState(223); + setState(232); match(T__18); - setState(224); + setState(233); match(T__4); - setState(225); + setState(234); commaExpr(0); - setState(226); + setState(235); match(T__5); - setState(227); + setState(236); stmt(); } break; @@ -1783,33 +1796,33 @@ public class KickCParser extends Parser { _localctx = new StmtDoWhileContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(232); + setState(241); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) { { { - setState(229); + setState(238); directive(); } } - setState(234); + setState(243); _errHandler.sync(this); _la = _input.LA(1); } - setState(235); + setState(244); match(T__19); - setState(236); + setState(245); stmt(); - setState(237); + setState(246); match(T__18); - setState(238); + setState(247); match(T__4); - setState(239); + setState(248); commaExpr(0); - setState(240); + setState(249); match(T__5); - setState(241); + setState(250); match(T__1); } break; @@ -1817,29 +1830,29 @@ public class KickCParser extends Parser { _localctx = new StmtForContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(246); + setState(255); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15))) != 0)) { { { - setState(243); + setState(252); directive(); } } - setState(248); + setState(257); _errHandler.sync(this); _la = _input.LA(1); } - setState(249); + setState(258); match(T__20); - setState(250); + setState(259); match(T__4); - setState(251); + setState(260); forLoop(); - setState(252); + setState(261); match(T__5); - setState(253); + setState(262); stmt(); } break; @@ -1847,19 +1860,19 @@ public class KickCParser extends Parser { _localctx = new StmtReturnContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(255); + setState(264); match(T__21); - setState(257); + setState(266); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 80)) & ~0x3f) == 0 && ((1L << (_la - 80)) & ((1L << (STRING - 80)) | (1L << (CHAR - 80)) | (1L << (BOOLEAN - 80)) | (1L << (NUMBER - 80)) | (1L << (NAME - 80)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 82)) & ~0x3f) == 0 && ((1L << (_la - 82)) & ((1L << (STRING - 82)) | (1L << (CHAR - 82)) | (1L << (BOOLEAN - 82)) | (1L << (NUMBER - 82)) | (1L << (NAME - 82)))) != 0)) { { - setState(256); + setState(265); commaExpr(0); } } - setState(259); + setState(268); match(T__1); } break; @@ -1867,9 +1880,9 @@ public class KickCParser extends Parser { _localctx = new StmtBreakContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(260); + setState(269); match(T__22); - setState(261); + setState(270); match(T__1); } break; @@ -1877,9 +1890,9 @@ public class KickCParser extends Parser { _localctx = new StmtContinueContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(262); + setState(271); match(T__23); - setState(263); + setState(272); match(T__1); } break; @@ -1887,23 +1900,23 @@ public class KickCParser extends Parser { _localctx = new StmtAsmContext(_localctx); enterOuterAlt(_localctx, 11); { - setState(264); + setState(273); match(T__24); - setState(266); + setState(275); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__4) { { - setState(265); + setState(274); asmDirectives(); } } - setState(268); + setState(277); match(T__6); - setState(269); + setState(278); asmLines(); - setState(270); + setState(279); match(T__7); } break; @@ -1911,7 +1924,7 @@ public class KickCParser extends Parser { _localctx = new StmtDeclKasmContext(_localctx); enterOuterAlt(_localctx, 12); { - setState(272); + setState(281); declKasm(); } break; @@ -1996,27 +2009,27 @@ public class KickCParser extends Parser { enterRule(_localctx, 36, RULE_forLoop); int _la; try { - setState(291); + setState(300); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { case 1: _localctx = new ForClassicContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(275); + setState(284); forClassicInit(); - setState(276); + setState(285); match(T__1); - setState(277); + setState(286); commaExpr(0); - setState(278); + setState(287); match(T__1); - setState(280); + setState(289); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 80)) & ~0x3f) == 0 && ((1L << (_la - 80)) & ((1L << (STRING - 80)) | (1L << (CHAR - 80)) | (1L << (BOOLEAN - 80)) | (1L << (NUMBER - 80)) | (1L << (NAME - 80)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 82)) & ~0x3f) == 0 && ((1L << (_la - 82)) & ((1L << (STRING - 82)) | (1L << (CHAR - 82)) | (1L << (BOOLEAN - 82)) | (1L << (NUMBER - 82)) | (1L << (NAME - 82)))) != 0)) { { - setState(279); + setState(288); commaExpr(0); } } @@ -2027,27 +2040,27 @@ public class KickCParser extends Parser { _localctx = new ForRangeContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(283); + setState(292); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28))) != 0) || _la==SIMPLETYPE) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28) | (1L << T__32))) != 0) || _la==SIMPLETYPE) { { - setState(282); + setState(291); declTypes(); } } - setState(285); + setState(294); match(NAME); - setState(286); + setState(295); match(T__25); - setState(287); + setState(296); expr(0); { - setState(288); + setState(297); match(T__26); } - setState(289); + setState(298); expr(0); } break; @@ -2119,19 +2132,19 @@ public class KickCParser extends Parser { enterRule(_localctx, 38, RULE_forClassicInit); int _la; try { - setState(297); + setState(306); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,27,_ctx) ) { case 1: _localctx = new ForClassicInitDeclContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(294); + setState(303); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28))) != 0) || _la==SIMPLETYPE) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28) | (1L << T__32))) != 0) || _la==SIMPLETYPE) { { - setState(293); + setState(302); declVariables(); } } @@ -2142,7 +2155,7 @@ public class KickCParser extends Parser { _localctx = new ForClassicInitExprContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(296); + setState(305); commaExpr(0); } break; @@ -2249,6 +2262,25 @@ public class KickCParser extends Parser { else return visitor.visitChildren(this); } } + public static class TypeStructRefContext extends TypeDeclContext { + public StructRefContext structRef() { + return getRuleContext(StructRefContext.class,0); + } + public TypeStructRefContext(TypeDeclContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterTypeStructRef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitTypeStructRef(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitTypeStructRef(this); + else return visitor.visitChildren(this); + } + } public static class TypeSimpleContext extends TypeDeclContext { public TerminalNode SIMPLETYPE() { return getToken(KickCParser.SIMPLETYPE, 0); } public TypeSimpleContext(TypeDeclContext ctx) { copyFrom(ctx); } @@ -2266,6 +2298,25 @@ public class KickCParser extends Parser { else return visitor.visitChildren(this); } } + public static class TypeStructDefContext extends TypeDeclContext { + public StructDefContext structDef() { + return getRuleContext(StructDefContext.class,0); + } + public TypeStructDefContext(TypeDeclContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterTypeStructDef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitTypeStructDef(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitTypeStructDef(this); + else return visitor.visitChildren(this); + } + } public static class TypeSignedSimpleContext extends TypeDeclContext { public TerminalNode SIMPLETYPE() { return getToken(KickCParser.SIMPLETYPE, 0); } public TypeSignedSimpleContext(TypeDeclContext ctx) { copyFrom(ctx); } @@ -2300,39 +2351,38 @@ public class KickCParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(309); + setState(320); _errHandler.sync(this); - switch (_input.LA(1)) { - case T__4: + switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) { + case 1: { _localctx = new TypeParContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(300); + setState(309); match(T__4); - setState(301); + setState(310); typeDecl(0); - setState(302); + setState(311); match(T__5); } break; - case SIMPLETYPE: + case 2: { _localctx = new TypeSimpleContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(304); + setState(313); match(SIMPLETYPE); } break; - case T__27: - case T__28: + case 3: { _localctx = new TypeSignedSimpleContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(305); + setState(314); _la = _input.LA(1); if ( !(_la==T__27 || _la==T__28) ) { _errHandler.recoverInline(this); @@ -2342,23 +2392,39 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(307); + setState(316); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) { case 1: { - setState(306); + setState(315); match(SIMPLETYPE); } break; } } break; - default: - throw new NoViableAltException(this); + case 4: + { + _localctx = new TypeStructDefContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(318); + structDef(); + } + break; + case 5: + { + _localctx = new TypeStructRefContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(319); + structRef(); + } + break; } _ctx.stop = _input.LT(-1); - setState(324); + setState(335); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,32,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -2366,16 +2432,16 @@ public class KickCParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(322); + setState(333); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { case 1: { _localctx = new TypePtrContext(new TypeDeclContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_typeDecl); - setState(311); - if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(312); + setState(322); + if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); + setState(323); match(T__29); } break; @@ -2383,21 +2449,21 @@ public class KickCParser extends Parser { { _localctx = new TypeArrayContext(new TypeDeclContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_typeDecl); - setState(313); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(314); + setState(324); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(325); match(T__30); - setState(316); + setState(327); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 80)) & ~0x3f) == 0 && ((1L << (_la - 80)) & ((1L << (STRING - 80)) | (1L << (CHAR - 80)) | (1L << (BOOLEAN - 80)) | (1L << (NUMBER - 80)) | (1L << (NAME - 80)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 82)) & ~0x3f) == 0 && ((1L << (_la - 82)) & ((1L << (STRING - 82)) | (1L << (CHAR - 82)) | (1L << (BOOLEAN - 82)) | (1L << (NUMBER - 82)) | (1L << (NAME - 82)))) != 0)) { { - setState(315); + setState(326); expr(0); } } - setState(318); + setState(329); match(T__31); } break; @@ -2405,18 +2471,18 @@ public class KickCParser extends Parser { { _localctx = new TypeProcedureContext(new TypeDeclContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_typeDecl); - setState(319); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(320); + setState(330); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(331); match(T__4); - setState(321); + setState(332); match(T__5); } break; } } } - setState(326); + setState(337); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,32,_ctx); } @@ -2433,6 +2499,173 @@ public class KickCParser extends Parser { return _localctx; } + public static class StructRefContext extends ParserRuleContext { + public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); } + public StructRefContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structRef; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStructRef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStructRef(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitStructRef(this); + else return visitor.visitChildren(this); + } + } + + public final StructRefContext structRef() throws RecognitionException { + StructRefContext _localctx = new StructRefContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_structRef); + try { + enterOuterAlt(_localctx, 1); + { + setState(338); + match(T__32); + setState(339); + match(NAME); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StructDefContext extends ParserRuleContext { + public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); } + public List structMembers() { + return getRuleContexts(StructMembersContext.class); + } + public StructMembersContext structMembers(int i) { + return getRuleContext(StructMembersContext.class,i); + } + public StructDefContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structDef; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStructDef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStructDef(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitStructDef(this); + else return visitor.visitChildren(this); + } + } + + public final StructDefContext structDef() throws RecognitionException { + StructDefContext _localctx = new StructDefContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_structDef); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(341); + match(T__32); + setState(343); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==NAME) { + { + setState(342); + match(NAME); + } + } + + setState(345); + match(T__6); + setState(347); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(346); + structMembers(); + } + } + setState(349); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__8) | (1L << T__9) | (1L << T__10) | (1L << T__11) | (1L << T__12) | (1L << T__13) | (1L << T__14) | (1L << T__15) | (1L << T__27) | (1L << T__28) | (1L << T__32))) != 0) || _la==SIMPLETYPE ); + setState(351); + match(T__7); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StructMembersContext extends ParserRuleContext { + public DeclVariablesContext declVariables() { + return getRuleContext(DeclVariablesContext.class,0); + } + public StructMembersContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structMembers; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterStructMembers(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitStructMembers(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitStructMembers(this); + else return visitor.visitChildren(this); + } + } + + public final StructMembersContext structMembers() throws RecognitionException { + StructMembersContext _localctx = new StructMembersContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_structMembers); + try { + enterOuterAlt(_localctx, 1); + { + setState(353); + declVariables(); + setState(354); + match(T__1); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + public static class CommaExprContext extends ParserRuleContext { public CommaExprContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); @@ -2495,8 +2728,8 @@ public class KickCParser extends Parser { int _parentState = getState(); CommaExprContext _localctx = new CommaExprContext(_ctx, _parentState); CommaExprContext _prevctx = _localctx; - int _startState = 42; - enterRecursionRule(_localctx, 42, RULE_commaExpr, _p); + int _startState = 48; + enterRecursionRule(_localctx, 48, RULE_commaExpr, _p); try { int _alt; enterOuterAlt(_localctx, 1); @@ -2506,13 +2739,13 @@ public class KickCParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(328); + setState(357); expr(0); } _ctx.stop = _input.LT(-1); - setState(335); + setState(364); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,33,_ctx); + _alt = getInterpreter().adaptivePredict(_input,35,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -2521,18 +2754,18 @@ public class KickCParser extends Parser { { _localctx = new CommaSimpleContext(new CommaExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_commaExpr); - setState(330); + setState(359); if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(331); + setState(360); match(T__2); - setState(332); + setState(361); expr(0); } } } - setState(337); + setState(366); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,33,_ctx); + _alt = getInterpreter().adaptivePredict(_input,35,_ctx); } } } @@ -2712,6 +2945,46 @@ public class KickCParser extends Parser { else return visitor.visitChildren(this); } } + public static class ExprArrowContext extends ExprContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); } + public ExprArrowContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterExprArrow(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitExprArrow(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitExprArrow(this); + else return visitor.visitChildren(this); + } + } + public static class ExprDotContext extends ExprContext { + public ExprContext expr() { + return getRuleContext(ExprContext.class,0); + } + public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); } + public ExprDotContext(ExprContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).enterExprDot(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof KickCListener ) ((KickCListener)listener).exitExprDot(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof KickCVisitor ) return ((KickCVisitor)visitor).visitExprDot(this); + else return visitor.visitChildren(this); + } + } public static class InitListContext extends ExprContext { public List expr() { return getRuleContexts(ExprContext.class); @@ -2820,7 +3093,10 @@ public class KickCParser extends Parser { } } public static class ExprStringContext extends ExprContext { - public TerminalNode STRING() { return getToken(KickCParser.STRING, 0); } + public List STRING() { return getTokens(KickCParser.STRING); } + public TerminalNode STRING(int i) { + return getToken(KickCParser.STRING, i); + } public ExprStringContext(ExprContext ctx) { copyFrom(ctx); } @Override public void enterRule(ParseTreeListener listener) { @@ -2968,27 +3244,27 @@ public class KickCParser extends Parser { int _parentState = getState(); ExprContext _localctx = new ExprContext(_ctx, _parentState); ExprContext _prevctx = _localctx; - int _startState = 44; - enterRecursionRule(_localctx, 44, RULE_expr, _p); + int _startState = 50; + enterRecursionRule(_localctx, 50, RULE_expr, _p); int _la; try { int _alt; enterOuterAlt(_localctx, 1); { - setState(388); + setState(421); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,37,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) { case 1: { _localctx = new ExprParContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(339); + setState(368); match(T__4); - setState(340); + setState(369); commaExpr(0); - setState(341); + setState(370); match(T__5); } break; @@ -2997,27 +3273,27 @@ public class KickCParser extends Parser { _localctx = new ExprSizeOfContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(343); - match(T__32); - setState(344); + setState(372); + match(T__35); + setState(373); match(T__4); - setState(347); + setState(376); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) { case 1: { - setState(345); + setState(374); typeDecl(0); } break; case 2: { - setState(346); + setState(375); expr(0); } break; } - setState(349); + setState(378); match(T__5); } break; @@ -3026,27 +3302,27 @@ public class KickCParser extends Parser { _localctx = new ExprTypeIdContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(351); - match(T__33); - setState(352); + setState(380); + match(T__36); + setState(381); match(T__4); - setState(355); + setState(384); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,35,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,37,_ctx) ) { case 1: { - setState(353); + setState(382); typeDecl(0); } break; case 2: { - setState(354); + setState(383); expr(0); } break; } - setState(357); + setState(386); match(T__5); } break; @@ -3055,13 +3331,13 @@ public class KickCParser extends Parser { _localctx = new ExprCastContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(359); + setState(388); match(T__4); - setState(360); + setState(389); typeDecl(0); - setState(361); + setState(390); match(T__5); - setState(362); + setState(391); expr(24); } break; @@ -3070,9 +3346,9 @@ public class KickCParser extends Parser { _localctx = new ExprPreModContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(364); + setState(393); _la = _input.LA(1); - if ( !(_la==T__34 || _la==T__35) ) { + if ( !(_la==T__37 || _la==T__38) ) { _errHandler.recoverInline(this); } else { @@ -3080,7 +3356,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(365); + setState(394); expr(23); } break; @@ -3089,9 +3365,9 @@ public class KickCParser extends Parser { _localctx = new ExprPtrContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(366); + setState(395); match(T__29); - setState(367); + setState(396); expr(21); } break; @@ -3100,9 +3376,9 @@ public class KickCParser extends Parser { _localctx = new ExprUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(368); + setState(397); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -3110,7 +3386,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(369); + setState(398); expr(20); } break; @@ -3119,9 +3395,9 @@ public class KickCParser extends Parser { _localctx = new ExprUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(370); + setState(399); _la = _input.LA(1); - if ( !(_la==T__45 || _la==T__46) ) { + if ( !(_la==T__48 || _la==T__49) ) { _errHandler.recoverInline(this); } else { @@ -3129,7 +3405,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(371); + setState(400); expr(16); } break; @@ -3138,27 +3414,27 @@ public class KickCParser extends Parser { _localctx = new InitListContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(372); + setState(401); match(T__6); - setState(373); + setState(402); expr(0); - setState(378); + setState(407); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(374); + setState(403); match(T__2); - setState(375); + setState(404); expr(0); } } - setState(380); + setState(409); _errHandler.sync(this); _la = _input.LA(1); } - setState(381); + setState(410); match(T__7); } break; @@ -3167,7 +3443,7 @@ public class KickCParser extends Parser { _localctx = new ExprIdContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(383); + setState(412); match(NAME); } break; @@ -3176,7 +3452,7 @@ public class KickCParser extends Parser { _localctx = new ExprNumberContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(384); + setState(413); match(NUMBER); } break; @@ -3185,8 +3461,26 @@ public class KickCParser extends Parser { _localctx = new ExprStringContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(385); - match(STRING); + setState(415); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(414); + match(STRING); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(417); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,39,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); } break; case 13: @@ -3194,7 +3488,7 @@ public class KickCParser extends Parser { _localctx = new ExprCharContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(386); + setState(419); match(CHAR); } break; @@ -3203,32 +3497,32 @@ public class KickCParser extends Parser { _localctx = new ExprBoolContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(387); + setState(420); match(BOOLEAN); } break; } _ctx.stop = _input.LT(-1); - setState(444); + setState(483); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,40,_ctx); + _alt = getInterpreter().adaptivePredict(_input,43,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(442); + setState(481); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,39,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) { case 1: { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(390); + setState(423); if (!(precpred(_ctx, 19))) throw new FailedPredicateException(this, "precpred(_ctx, 19)"); - setState(391); + setState(424); _la = _input.LA(1); - if ( !(_la==T__41 || _la==T__42) ) { + if ( !(_la==T__44 || _la==T__45) ) { _errHandler.recoverInline(this); } else { @@ -3236,7 +3530,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(392); + setState(425); expr(20); } break; @@ -3244,169 +3538,11 @@ public class KickCParser extends Parser { { _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(393); - if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); - setState(394); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__29) | (1L << T__43) | (1L << T__44))) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(395); - expr(19); - } - break; - case 3: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(396); - if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); - setState(397); - _la = _input.LA(1); - if ( !(_la==T__36 || _la==T__37) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(398); - expr(18); - } - break; - case 4: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(399); - if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)"); - setState(400); - _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__45) | (1L << T__46) | (1L << T__47) | (1L << T__48) | (1L << T__49) | (1L << T__50))) != 0)) ) { - _errHandler.recoverInline(this); - } - else { - if ( _input.LA(1)==Token.EOF ) matchedEOF = true; - _errHandler.reportMatch(this); - consume(); - } - setState(401); - expr(16); - } - break; - case 5: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(402); - if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); - { - setState(403); - match(T__39); - } - setState(404); - expr(15); - } - break; - case 6: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(405); - if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); - { - setState(406); - match(T__51); - } - setState(407); - expr(14); - } - break; - case 7: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(408); - if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); - { - setState(409); - match(T__52); - } - setState(410); - expr(13); - } - break; - case 8: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(411); - if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); - { - setState(412); - match(T__53); - } - setState(413); - expr(12); - } - break; - case 9: - { - _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(414); - if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); - { - setState(415); - match(T__54); - } - setState(416); - expr(11); - } - break; - case 10: - { - _localctx = new ExprTernaryContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(417); - if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(418); - match(T__55); - setState(419); - expr(0); - setState(420); - match(T__25); - setState(421); - expr(10); - } - break; - case 11: - { - _localctx = new ExprAssignmentContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(423); - if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); - setState(424); - match(T__3); - setState(425); - expr(8); - } - break; - case 12: - { - _localctx = new ExprAssignmentCompoundContext(new ExprContext(_parentctx, _parentState)); - pushNewRecursionContext(_localctx, _startState, RULE_expr); setState(426); - if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); + if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)"); setState(427); _la = _input.LA(1); - if ( !(((((_la - 57)) & ~0x3f) == 0 && ((1L << (_la - 57)) & ((1L << (T__56 - 57)) | (1L << (T__57 - 57)) | (1L << (T__58 - 57)) | (1L << (T__59 - 57)) | (1L << (T__60 - 57)) | (1L << (T__61 - 57)) | (1L << (T__62 - 57)) | (1L << (T__63 - 57)) | (1L << (T__64 - 57)) | (1L << (T__65 - 57)))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__29) | (1L << T__46) | (1L << T__47))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -3415,54 +3551,236 @@ public class KickCParser extends Parser { consume(); } setState(428); + expr(19); + } + break; + case 3: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(429); + if (!(precpred(_ctx, 17))) throw new FailedPredicateException(this, "precpred(_ctx, 17)"); + setState(430); + _la = _input.LA(1); + if ( !(_la==T__39 || _la==T__40) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(431); + expr(18); + } + break; + case 4: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(432); + if (!(precpred(_ctx, 15))) throw new FailedPredicateException(this, "precpred(_ctx, 15)"); + setState(433); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__48) | (1L << T__49) | (1L << T__50) | (1L << T__51) | (1L << T__52) | (1L << T__53))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(434); + expr(16); + } + break; + case 5: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(435); + if (!(precpred(_ctx, 14))) throw new FailedPredicateException(this, "precpred(_ctx, 14)"); + { + setState(436); + match(T__42); + } + setState(437); + expr(15); + } + break; + case 6: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(438); + if (!(precpred(_ctx, 13))) throw new FailedPredicateException(this, "precpred(_ctx, 13)"); + { + setState(439); + match(T__54); + } + setState(440); + expr(14); + } + break; + case 7: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(441); + if (!(precpred(_ctx, 12))) throw new FailedPredicateException(this, "precpred(_ctx, 12)"); + { + setState(442); + match(T__55); + } + setState(443); + expr(13); + } + break; + case 8: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(444); + if (!(precpred(_ctx, 11))) throw new FailedPredicateException(this, "precpred(_ctx, 11)"); + { + setState(445); + match(T__56); + } + setState(446); + expr(12); + } + break; + case 9: + { + _localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(447); + if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); + { + setState(448); + match(T__57); + } + setState(449); + expr(11); + } + break; + case 10: + { + _localctx = new ExprTernaryContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(450); + if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); + setState(451); + match(T__58); + setState(452); + expr(0); + setState(453); + match(T__25); + setState(454); + expr(10); + } + break; + case 11: + { + _localctx = new ExprAssignmentContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(456); + if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); + setState(457); + match(T__3); + setState(458); + expr(8); + } + break; + case 12: + { + _localctx = new ExprAssignmentCompoundContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(459); + if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); + setState(460); + _la = _input.LA(1); + if ( !(((((_la - 60)) & ~0x3f) == 0 && ((1L << (_la - 60)) & ((1L << (T__59 - 60)) | (1L << (T__60 - 60)) | (1L << (T__61 - 60)) | (1L << (T__62 - 60)) | (1L << (T__63 - 60)) | (1L << (T__64 - 60)) | (1L << (T__65 - 60)) | (1L << (T__66 - 60)) | (1L << (T__67 - 60)) | (1L << (T__68 - 60)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(461); expr(7); } break; case 13: { - _localctx = new ExprCallContext(new ExprContext(_parentctx, _parentState)); + _localctx = new ExprDotContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(429); - if (!(precpred(_ctx, 28))) throw new FailedPredicateException(this, "precpred(_ctx, 28)"); - setState(430); - match(T__4); - setState(432); - _errHandler.sync(this); - _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__32) | (1L << T__33) | (1L << T__34) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__45) | (1L << T__46))) != 0) || ((((_la - 80)) & ~0x3f) == 0 && ((1L << (_la - 80)) & ((1L << (STRING - 80)) | (1L << (CHAR - 80)) | (1L << (BOOLEAN - 80)) | (1L << (NUMBER - 80)) | (1L << (NAME - 80)))) != 0)) { - { - setState(431); - parameterList(); - } - } - - setState(434); - match(T__5); + setState(462); + if (!(precpred(_ctx, 30))) throw new FailedPredicateException(this, "precpred(_ctx, 30)"); + setState(463); + match(T__33); + setState(464); + match(NAME); } break; case 14: { - _localctx = new ExprArrayContext(new ExprContext(_parentctx, _parentState)); + _localctx = new ExprArrowContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(435); - if (!(precpred(_ctx, 25))) throw new FailedPredicateException(this, "precpred(_ctx, 25)"); - setState(436); - match(T__30); - setState(437); - commaExpr(0); - setState(438); - match(T__31); + setState(465); + if (!(precpred(_ctx, 29))) throw new FailedPredicateException(this, "precpred(_ctx, 29)"); + setState(466); + match(T__34); + setState(467); + match(NAME); } break; case 15: + { + _localctx = new ExprCallContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(468); + if (!(precpred(_ctx, 28))) throw new FailedPredicateException(this, "precpred(_ctx, 28)"); + setState(469); + match(T__4); + setState(471); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__4) | (1L << T__6) | (1L << T__29) | (1L << T__35) | (1L << T__36) | (1L << T__37) | (1L << T__38) | (1L << T__39) | (1L << T__40) | (1L << T__41) | (1L << T__42) | (1L << T__43) | (1L << T__48) | (1L << T__49))) != 0) || ((((_la - 82)) & ~0x3f) == 0 && ((1L << (_la - 82)) & ((1L << (STRING - 82)) | (1L << (CHAR - 82)) | (1L << (BOOLEAN - 82)) | (1L << (NUMBER - 82)) | (1L << (NAME - 82)))) != 0)) { + { + setState(470); + parameterList(); + } + } + + setState(473); + match(T__5); + } + break; + case 16: + { + _localctx = new ExprArrayContext(new ExprContext(_parentctx, _parentState)); + pushNewRecursionContext(_localctx, _startState, RULE_expr); + setState(474); + if (!(precpred(_ctx, 25))) throw new FailedPredicateException(this, "precpred(_ctx, 25)"); + setState(475); + match(T__30); + setState(476); + commaExpr(0); + setState(477); + match(T__31); + } + break; + case 17: { _localctx = new ExprPostModContext(new ExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_expr); - setState(440); + setState(479); if (!(precpred(_ctx, 22))) throw new FailedPredicateException(this, "precpred(_ctx, 22)"); - setState(441); + setState(480); _la = _input.LA(1); - if ( !(_la==T__34 || _la==T__35) ) { + if ( !(_la==T__37 || _la==T__38) ) { _errHandler.recoverInline(this); } else { @@ -3475,9 +3793,9 @@ public class KickCParser extends Parser { } } } - setState(446); + setState(485); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,40,_ctx); + _alt = getInterpreter().adaptivePredict(_input,43,_ctx); } } } @@ -3520,26 +3838,26 @@ public class KickCParser extends Parser { public final ParameterListContext parameterList() throws RecognitionException { ParameterListContext _localctx = new ParameterListContext(_ctx, getState()); - enterRule(_localctx, 46, RULE_parameterList); + enterRule(_localctx, 52, RULE_parameterList); int _la; try { enterOuterAlt(_localctx, 1); { - setState(447); + setState(486); expr(0); - setState(452); + setState(491); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(448); + setState(487); match(T__2); - setState(449); + setState(488); expr(0); } } - setState(454); + setState(493); _errHandler.sync(this); _la = _input.LA(1); } @@ -3582,24 +3900,24 @@ public class KickCParser extends Parser { public final DeclKasmContext declKasm() throws RecognitionException { DeclKasmContext _localctx = new DeclKasmContext(_ctx, getState()); - enterRule(_localctx, 48, RULE_declKasm); + enterRule(_localctx, 54, RULE_declKasm); int _la; try { enterOuterAlt(_localctx, 1); { - setState(455); - match(T__66); - setState(457); + setState(494); + match(T__69); + setState(496); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__4) { { - setState(456); + setState(495); asmDirectives(); } } - setState(459); + setState(498); match(KICKASM); } } @@ -3642,32 +3960,32 @@ public class KickCParser extends Parser { public final AsmDirectivesContext asmDirectives() throws RecognitionException { AsmDirectivesContext _localctx = new AsmDirectivesContext(_ctx, getState()); - enterRule(_localctx, 50, RULE_asmDirectives); + enterRule(_localctx, 56, RULE_asmDirectives); int _la; try { enterOuterAlt(_localctx, 1); { - setState(461); + setState(500); match(T__4); - setState(462); + setState(501); asmDirective(); - setState(467); + setState(506); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(463); + setState(502); match(T__2); - setState(464); + setState(503); asmDirective(); } } - setState(469); + setState(508); _errHandler.sync(this); _la = _input.LA(1); } - setState(470); + setState(509); match(T__5); } } @@ -3804,97 +4122,97 @@ public class KickCParser extends Parser { public final AsmDirectiveContext asmDirective() throws RecognitionException { AsmDirectiveContext _localctx = new AsmDirectiveContext(_ctx, getState()); - enterRule(_localctx, 52, RULE_asmDirective); + enterRule(_localctx, 58, RULE_asmDirective); try { - setState(487); + setState(526); _errHandler.sync(this); switch (_input.LA(1)) { - case T__67: + case T__70: _localctx = new AsmDirectiveResourceContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(472); - match(T__67); - setState(473); - match(STRING); - } - break; - case T__68: - _localctx = new AsmDirectiveUsesContext(_localctx); - enterOuterAlt(_localctx, 2); - { - setState(474); - match(T__68); - setState(475); - match(NAME); - } - break; - case T__69: - _localctx = new AsmDirectiveClobberContext(_localctx); - enterOuterAlt(_localctx, 3); - { - setState(476); - match(T__69); - setState(477); - match(STRING); - } - break; - case T__70: - _localctx = new AsmDirectiveBytesContext(_localctx); - enterOuterAlt(_localctx, 4); - { - setState(478); + setState(511); match(T__70); - setState(479); - expr(0); + setState(512); + match(STRING); } break; case T__71: - _localctx = new AsmDirectiveCyclesContext(_localctx); - enterOuterAlt(_localctx, 5); + _localctx = new AsmDirectiveUsesContext(_localctx); + enterOuterAlt(_localctx, 2); { - setState(480); + setState(513); match(T__71); - setState(481); - expr(0); + setState(514); + match(NAME); } break; case T__72: + _localctx = new AsmDirectiveClobberContext(_localctx); + enterOuterAlt(_localctx, 3); + { + setState(515); + match(T__72); + setState(516); + match(STRING); + } + break; + case T__73: + _localctx = new AsmDirectiveBytesContext(_localctx); + enterOuterAlt(_localctx, 4); + { + setState(517); + match(T__73); + setState(518); + expr(0); + } + break; + case T__74: + _localctx = new AsmDirectiveCyclesContext(_localctx); + enterOuterAlt(_localctx, 5); + { + setState(519); + match(T__74); + setState(520); + expr(0); + } + break; + case T__75: _localctx = new AsmDirectiveAddressContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(482); - match(T__72); - setState(485); + setState(521); + match(T__75); + setState(524); _errHandler.sync(this); switch (_input.LA(1)) { case T__12: { - setState(483); + setState(522); match(T__12); } break; case T__4: case T__6: case T__29: - case T__32: - case T__33: - case T__34: case T__35: case T__36: case T__37: case T__38: case T__39: case T__40: - case T__45: - case T__46: + case T__41: + case T__42: + case T__43: + case T__48: + case T__49: case STRING: case CHAR: case BOOLEAN: case NUMBER: case NAME: { - setState(484); + setState(523); expr(0); } break; @@ -3946,22 +4264,22 @@ public class KickCParser extends Parser { public final AsmLinesContext asmLines() throws RecognitionException { AsmLinesContext _localctx = new AsmLinesContext(_ctx, getState()); - enterRule(_localctx, 54, RULE_asmLines); + enterRule(_localctx, 60, RULE_asmLines); int _la; try { enterOuterAlt(_localctx, 1); { - setState(492); + setState(531); _errHandler.sync(this); _la = _input.LA(1); - while (((((_la - 39)) & ~0x3f) == 0 && ((1L << (_la - 39)) & ((1L << (T__38 - 39)) | (1L << (T__73 - 39)) | (1L << (MNEMONIC - 39)) | (1L << (NAME - 39)))) != 0)) { + while (((((_la - 42)) & ~0x3f) == 0 && ((1L << (_la - 42)) & ((1L << (T__41 - 42)) | (1L << (T__76 - 42)) | (1L << (MNEMONIC - 42)) | (1L << (NAME - 42)))) != 0)) { { { - setState(489); + setState(528); asmLine(); } } - setState(494); + setState(533); _errHandler.sync(this); _la = _input.LA(1); } @@ -4009,30 +4327,30 @@ public class KickCParser extends Parser { public final AsmLineContext asmLine() throws RecognitionException { AsmLineContext _localctx = new AsmLineContext(_ctx, getState()); - enterRule(_localctx, 56, RULE_asmLine); + enterRule(_localctx, 62, RULE_asmLine); try { - setState(498); + setState(537); _errHandler.sync(this); switch (_input.LA(1)) { - case T__38: + case T__41: case NAME: enterOuterAlt(_localctx, 1); { - setState(495); + setState(534); asmLabel(); } break; case MNEMONIC: enterOuterAlt(_localctx, 2); { - setState(496); + setState(535); asmInstruction(); } break; - case T__73: + case T__76: enterOuterAlt(_localctx, 3); { - setState(497); + setState(536); asmBytes(); } break; @@ -4099,39 +4417,39 @@ public class KickCParser extends Parser { public final AsmLabelContext asmLabel() throws RecognitionException { AsmLabelContext _localctx = new AsmLabelContext(_ctx, getState()); - enterRule(_localctx, 58, RULE_asmLabel); + enterRule(_localctx, 64, RULE_asmLabel); int _la; try { - setState(507); + setState(546); _errHandler.sync(this); switch (_input.LA(1)) { case NAME: _localctx = new AsmLabelNameContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(500); + setState(539); match(NAME); - setState(501); + setState(540); match(T__25); } break; - case T__38: + case T__41: _localctx = new AsmLabelMultiContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(502); - match(T__38); - setState(504); + setState(541); + match(T__41); + setState(543); _errHandler.sync(this); _la = _input.LA(1); if (_la==NAME) { { - setState(503); + setState(542); match(NAME); } } - setState(506); + setState(545); match(T__25); } break; @@ -4176,18 +4494,18 @@ public class KickCParser extends Parser { public final AsmInstructionContext asmInstruction() throws RecognitionException { AsmInstructionContext _localctx = new AsmInstructionContext(_ctx, getState()); - enterRule(_localctx, 60, RULE_asmInstruction); + enterRule(_localctx, 66, RULE_asmInstruction); try { enterOuterAlt(_localctx, 1); { - setState(509); + setState(548); match(MNEMONIC); - setState(511); + setState(550); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,50,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,53,_ctx) ) { case 1: { - setState(510); + setState(549); asmParamMode(); } break; @@ -4233,28 +4551,28 @@ public class KickCParser extends Parser { public final AsmBytesContext asmBytes() throws RecognitionException { AsmBytesContext _localctx = new AsmBytesContext(_ctx, getState()); - enterRule(_localctx, 62, RULE_asmBytes); + enterRule(_localctx, 68, RULE_asmBytes); int _la; try { enterOuterAlt(_localctx, 1); { - setState(513); - match(T__73); - setState(514); + setState(552); + match(T__76); + setState(553); asmExpr(0); - setState(519); + setState(558); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(515); + setState(554); match(T__2); - setState(516); + setState(555); asmExpr(0); } } - setState(521); + setState(560); _errHandler.sync(this); _la = _input.LA(1); } @@ -4402,16 +4720,16 @@ public class KickCParser extends Parser { public final AsmParamModeContext asmParamMode() throws RecognitionException { AsmParamModeContext _localctx = new AsmParamModeContext(_ctx, getState()); - enterRule(_localctx, 64, RULE_asmParamMode); + enterRule(_localctx, 70, RULE_asmParamMode); try { - setState(545); + setState(584); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,52,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,55,_ctx) ) { case 1: _localctx = new AsmModeAbsContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(522); + setState(561); asmExpr(0); } break; @@ -4419,9 +4737,9 @@ public class KickCParser extends Parser { _localctx = new AsmModeImmContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(523); - match(T__74); - setState(524); + setState(562); + match(T__77); + setState(563); asmExpr(0); } break; @@ -4429,11 +4747,11 @@ public class KickCParser extends Parser { _localctx = new AsmModeAbsXYContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(525); + setState(564); asmExpr(0); - setState(526); + setState(565); match(T__2); - setState(527); + setState(566); match(NAME); } break; @@ -4441,15 +4759,15 @@ public class KickCParser extends Parser { _localctx = new AsmModeIndIdxXYContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(529); + setState(568); match(T__4); - setState(530); + setState(569); asmExpr(0); - setState(531); + setState(570); match(T__5); - setState(532); + setState(571); match(T__2); - setState(533); + setState(572); match(NAME); } break; @@ -4457,15 +4775,15 @@ public class KickCParser extends Parser { _localctx = new AsmModeIdxIndXYContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(535); + setState(574); match(T__4); - setState(536); + setState(575); asmExpr(0); - setState(537); + setState(576); match(T__2); - setState(538); + setState(577); match(NAME); - setState(539); + setState(578); match(T__5); } break; @@ -4473,11 +4791,11 @@ public class KickCParser extends Parser { _localctx = new AsmModeIndContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(541); + setState(580); match(T__4); - setState(542); + setState(581); asmExpr(0); - setState(543); + setState(582); match(T__5); } break; @@ -4660,14 +4978,14 @@ public class KickCParser extends Parser { int _parentState = getState(); AsmExprContext _localctx = new AsmExprContext(_ctx, _parentState); AsmExprContext _prevctx = _localctx; - int _startState = 66; - enterRecursionRule(_localctx, 66, RULE_asmExpr, _p); + int _startState = 72; + enterRecursionRule(_localctx, 72, RULE_asmExpr, _p); int _la; try { int _alt; enterOuterAlt(_localctx, 1); { - setState(561); + setState(600); _errHandler.sync(this); switch (_input.LA(1)) { case T__30: @@ -4676,25 +4994,25 @@ public class KickCParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(548); + setState(587); match(T__30); - setState(549); + setState(588); asmExpr(0); - setState(550); + setState(589); match(T__31); } break; - case T__36: - case T__37: - case T__45: - case T__46: + case T__39: + case T__40: + case T__48: + case T__49: { _localctx = new AsmExprUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(552); + setState(591); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__36) | (1L << T__37) | (1L << T__45) | (1L << T__46))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__39) | (1L << T__40) | (1L << T__48) | (1L << T__49))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -4702,7 +5020,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(553); + setState(592); asmExpr(8); } break; @@ -4711,7 +5029,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprLabelContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(554); + setState(593); match(NAME); } break; @@ -4720,7 +5038,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprLabelRelContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(555); + setState(594); match(ASMREL); } break; @@ -4729,11 +5047,11 @@ public class KickCParser extends Parser { _localctx = new AsmExprReplaceContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(556); + setState(595); match(T__6); - setState(557); + setState(596); match(NAME); - setState(558); + setState(597); match(T__7); } break; @@ -4742,7 +5060,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprIntContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(559); + setState(598); match(NUMBER); } break; @@ -4751,7 +5069,7 @@ public class KickCParser extends Parser { _localctx = new AsmExprCharContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(560); + setState(599); match(CHAR); } break; @@ -4759,28 +5077,28 @@ public class KickCParser extends Parser { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(577); + setState(616); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,55,_ctx); + _alt = getInterpreter().adaptivePredict(_input,58,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(575); + setState(614); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,54,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,57,_ctx) ) { case 1: { _localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_asmExpr); - setState(563); + setState(602); if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); { - setState(564); - match(T__75); + setState(603); + match(T__33); } - setState(565); + setState(604); asmExpr(11); } break; @@ -4788,11 +5106,11 @@ public class KickCParser extends Parser { { _localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_asmExpr); - setState(566); + setState(605); if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(567); + setState(606); _la = _input.LA(1); - if ( !(_la==T__41 || _la==T__42) ) { + if ( !(_la==T__44 || _la==T__45) ) { _errHandler.recoverInline(this); } else { @@ -4800,7 +5118,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(568); + setState(607); asmExpr(10); } break; @@ -4808,11 +5126,11 @@ public class KickCParser extends Parser { { _localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_asmExpr); - setState(569); + setState(608); if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); - setState(570); + setState(609); _la = _input.LA(1); - if ( !(_la==T__29 || _la==T__43) ) { + if ( !(_la==T__29 || _la==T__46) ) { _errHandler.recoverInline(this); } else { @@ -4820,7 +5138,7 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(571); + setState(610); asmExpr(8); } break; @@ -4828,11 +5146,11 @@ public class KickCParser extends Parser { { _localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_asmExpr); - setState(572); + setState(611); if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); - setState(573); + setState(612); _la = _input.LA(1); - if ( !(_la==T__36 || _la==T__37) ) { + if ( !(_la==T__39 || _la==T__40) ) { _errHandler.recoverInline(this); } else { @@ -4840,16 +5158,16 @@ public class KickCParser extends Parser { _errHandler.reportMatch(this); consume(); } - setState(574); + setState(613); asmExpr(7); } break; } } } - setState(579); + setState(618); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,55,_ctx); + _alt = getInterpreter().adaptivePredict(_input,58,_ctx); } } } @@ -4870,11 +5188,11 @@ public class KickCParser extends Parser { return declVariableList_sempred((DeclVariableListContext)_localctx, predIndex); case 20: return typeDecl_sempred((TypeDeclContext)_localctx, predIndex); - case 21: + case 24: return commaExpr_sempred((CommaExprContext)_localctx, predIndex); - case 22: + case 25: return expr_sempred((ExprContext)_localctx, predIndex); - case 33: + case 36: return asmExpr_sempred((AsmExprContext)_localctx, predIndex); } return true; @@ -4889,11 +5207,11 @@ public class KickCParser extends Parser { private boolean typeDecl_sempred(TypeDeclContext _localctx, int predIndex) { switch (predIndex) { case 1: - return precpred(_ctx, 3); + return precpred(_ctx, 5); case 2: - return precpred(_ctx, 2); + return precpred(_ctx, 4); case 3: - return precpred(_ctx, 1); + return precpred(_ctx, 3); } return true; } @@ -4931,256 +5249,276 @@ public class KickCParser extends Parser { case 16: return precpred(_ctx, 7); case 17: - return precpred(_ctx, 28); + return precpred(_ctx, 30); case 18: - return precpred(_ctx, 25); + return precpred(_ctx, 29); case 19: + return precpred(_ctx, 28); + case 20: + return precpred(_ctx, 25); + case 21: return precpred(_ctx, 22); } return true; } private boolean asmExpr_sempred(AsmExprContext _localctx, int predIndex) { switch (predIndex) { - case 20: - return precpred(_ctx, 10); - case 21: - return precpred(_ctx, 9); case 22: - return precpred(_ctx, 7); + return precpred(_ctx, 10); case 23: + return precpred(_ctx, 9); + case 24: + return precpred(_ctx, 7); + case 25: return precpred(_ctx, 6); } return true; } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3b\u0247\4\2\t\2\4"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3d\u026e\4\2\t\2\4"+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ - "\t!\4\"\t\"\4#\t#\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\4\7\4O\n\4\f\4\16\4R\13"+ - "\4\3\5\3\5\3\5\3\6\6\6X\n\6\r\6\16\6Y\3\7\3\7\3\7\3\7\3\7\3\7\5\7b\n\7"+ - "\3\b\7\be\n\b\f\b\16\bh\13\b\3\b\3\b\7\bl\n\b\f\b\16\bo\13\b\3\t\3\t\3"+ - "\t\3\n\3\n\3\n\3\n\3\n\3\n\7\nz\n\n\f\n\16\n}\13\n\3\13\3\13\3\13\5\13"+ - "\u0082\n\13\3\f\3\f\3\f\3\f\5\f\u0088\n\f\3\f\3\f\3\f\5\f\u008d\n\f\3"+ - "\f\3\f\3\r\3\r\3\r\7\r\u0094\n\r\f\r\16\r\u0097\13\r\3\16\3\16\3\16\3"+ - "\16\5\16\u009d\n\16\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+ - "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\5\20\u00b2\n\20\3\20\5\20"+ - "\u00b5\n\20\3\21\3\21\3\21\3\21\3\21\7\21\u00bc\n\21\f\21\16\21\u00bf"+ - "\13\21\3\21\3\21\3\22\6\22\u00c4\n\22\r\22\16\22\u00c5\3\23\3\23\3\23"+ - "\3\23\3\23\5\23\u00cd\n\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+ - "\3\23\3\23\5\23\u00da\n\23\3\23\7\23\u00dd\n\23\f\23\16\23\u00e0\13\23"+ - "\3\23\3\23\3\23\3\23\3\23\3\23\3\23\7\23\u00e9\n\23\f\23\16\23\u00ec\13"+ - "\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\7\23\u00f7\n\23\f\23"+ - "\16\23\u00fa\13\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u0104"+ - "\n\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u010d\n\23\3\23\3\23\3\23"+ - "\3\23\3\23\5\23\u0114\n\23\3\24\3\24\3\24\3\24\3\24\5\24\u011b\n\24\3"+ - "\24\5\24\u011e\n\24\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u0126\n\24\3\25"+ - "\5\25\u0129\n\25\3\25\5\25\u012c\n\25\3\26\3\26\3\26\3\26\3\26\3\26\3"+ - "\26\3\26\5\26\u0136\n\26\5\26\u0138\n\26\3\26\3\26\3\26\3\26\3\26\5\26"+ - "\u013f\n\26\3\26\3\26\3\26\3\26\7\26\u0145\n\26\f\26\16\26\u0148\13\26"+ - "\3\27\3\27\3\27\3\27\3\27\3\27\7\27\u0150\n\27\f\27\16\27\u0153\13\27"+ - "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u015e\n\30\3\30\3\30"+ - "\3\30\3\30\3\30\3\30\5\30\u0166\n\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ - "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\7\30\u017b"+ - "\n\30\f\30\16\30\u017e\13\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u0187"+ - "\n\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ - "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ - "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ - "\3\30\5\30\u01b3\n\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\7\30\u01bd"+ - "\n\30\f\30\16\30\u01c0\13\30\3\31\3\31\3\31\7\31\u01c5\n\31\f\31\16\31"+ - "\u01c8\13\31\3\32\3\32\5\32\u01cc\n\32\3\32\3\32\3\33\3\33\3\33\3\33\7"+ - "\33\u01d4\n\33\f\33\16\33\u01d7\13\33\3\33\3\33\3\34\3\34\3\34\3\34\3"+ - "\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\5\34\u01e8\n\34\5\34\u01ea"+ - "\n\34\3\35\7\35\u01ed\n\35\f\35\16\35\u01f0\13\35\3\36\3\36\3\36\5\36"+ - "\u01f5\n\36\3\37\3\37\3\37\3\37\5\37\u01fb\n\37\3\37\5\37\u01fe\n\37\3"+ - " \3 \5 \u0202\n \3!\3!\3!\3!\7!\u0208\n!\f!\16!\u020b\13!\3\"\3\"\3\""+ - "\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3"+ - "\"\3\"\3\"\5\"\u0224\n\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\5#"+ - "\u0234\n#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\7#\u0242\n#\f#\16#\u0245"+ - "\13#\3#\2\7\22*,.D$\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60"+ - "\62\64\668:<>@BD\2\r\3\2\36\37\3\2%&\3\2\'+\3\2\60\61\3\2,-\4\2 ./\3"+ - "\2\'(\3\2\60\65\3\2;D\4\2\'(\60\61\4\2 ..\2\u0299\2F\3\2\2\2\4J\3\2\2"+ - "\2\6P\3\2\2\2\bS\3\2\2\2\nW\3\2\2\2\fa\3\2\2\2\16f\3\2\2\2\20p\3\2\2\2"+ - "\22s\3\2\2\2\24~\3\2\2\2\26\u0083\3\2\2\2\30\u0090\3\2\2\2\32\u009c\3"+ - "\2\2\2\34\u009e\3\2\2\2\36\u00b4\3\2\2\2 \u00b6\3\2\2\2\"\u00c3\3\2\2"+ - "\2$\u0113\3\2\2\2&\u0125\3\2\2\2(\u012b\3\2\2\2*\u0137\3\2\2\2,\u0149"+ - "\3\2\2\2.\u0186\3\2\2\2\60\u01c1\3\2\2\2\62\u01c9\3\2\2\2\64\u01cf\3\2"+ - "\2\2\66\u01e9\3\2\2\28\u01ee\3\2\2\2:\u01f4\3\2\2\2<\u01fd\3\2\2\2>\u01ff"+ - "\3\2\2\2@\u0203\3\2\2\2B\u0223\3\2\2\2D\u0233\3\2\2\2FG\5\6\4\2GH\5\n"+ - "\6\2HI\7\2\2\3I\3\3\2\2\2JK\58\35\2KL\7\2\2\3L\5\3\2\2\2MO\5\b\5\2NM\3"+ - "\2\2\2OR\3\2\2\2PN\3\2\2\2PQ\3\2\2\2Q\7\3\2\2\2RP\3\2\2\2ST\7\3\2\2TU"+ - "\7R\2\2U\t\3\2\2\2VX\5\f\7\2WV\3\2\2\2XY\3\2\2\2YW\3\2\2\2YZ\3\2\2\2Z"+ - "\13\3\2\2\2[\\\5\20\t\2\\]\7\4\2\2]b\3\2\2\2^b\5\26\f\2_b\5\62\32\2`b"+ - "\5\34\17\2a[\3\2\2\2a^\3\2\2\2a_\3\2\2\2a`\3\2\2\2b\r\3\2\2\2ce\5\36\20"+ - "\2dc\3\2\2\2eh\3\2\2\2fd\3\2\2\2fg\3\2\2\2gi\3\2\2\2hf\3\2\2\2im\5*\26"+ - "\2jl\5\36\20\2kj\3\2\2\2lo\3\2\2\2mk\3\2\2\2mn\3\2\2\2n\17\3\2\2\2om\3"+ - "\2\2\2pq\5\16\b\2qr\5\22\n\2r\21\3\2\2\2st\b\n\1\2tu\5\24\13\2u{\3\2\2"+ - "\2vw\f\3\2\2wx\7\5\2\2xz\5\24\13\2yv\3\2\2\2z}\3\2\2\2{y\3\2\2\2{|\3\2"+ - "\2\2|\23\3\2\2\2}{\3\2\2\2~\u0081\7^\2\2\177\u0080\7\6\2\2\u0080\u0082"+ - "\5.\30\2\u0081\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\25\3\2\2\2\u0083"+ - "\u0084\5\16\b\2\u0084\u0085\7^\2\2\u0085\u0087\7\7\2\2\u0086\u0088\5\30"+ - "\r\2\u0087\u0086\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u0089\3\2\2\2\u0089"+ - "\u008a\7\b\2\2\u008a\u008c\7\t\2\2\u008b\u008d\5\"\22\2\u008c\u008b\3"+ - "\2\2\2\u008c\u008d\3\2\2\2\u008d\u008e\3\2\2\2\u008e\u008f\7\n\2\2\u008f"+ - "\27\3\2\2\2\u0090\u0095\5\32\16\2\u0091\u0092\7\5\2\2\u0092\u0094\5\32"+ - "\16\2\u0093\u0091\3\2\2\2\u0094\u0097\3\2\2\2\u0095\u0093\3\2\2\2\u0095"+ - "\u0096\3\2\2\2\u0096\31\3\2\2\2\u0097\u0095\3\2\2\2\u0098\u0099\5\16\b"+ - "\2\u0099\u009a\7^\2\2\u009a\u009d\3\2\2\2\u009b\u009d\7Q\2\2\u009c\u0098"+ - "\3\2\2\2\u009c\u009b\3\2\2\2\u009d\33\3\2\2\2\u009e\u009f\5 \21\2\u009f"+ - "\u00a0\7\4\2\2\u00a0\35\3\2\2\2\u00a1\u00b5\7\13\2\2\u00a2\u00b5\7\f\2"+ - "\2\u00a3\u00a4\7\r\2\2\u00a4\u00a5\7\7\2\2\u00a5\u00a6\7U\2\2\u00a6\u00b5"+ - "\7\b\2\2\u00a7\u00a8\7\16\2\2\u00a8\u00a9\7\7\2\2\u00a9\u00aa\7^\2\2\u00aa"+ - "\u00b5\7\b\2\2\u00ab\u00b5\7\17\2\2\u00ac\u00b5\7\20\2\2\u00ad\u00b1\7"+ - "\21\2\2\u00ae\u00af\7\7\2\2\u00af\u00b0\7^\2\2\u00b0\u00b2\7\b\2\2\u00b1"+ - "\u00ae\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\u00b5\3\2\2\2\u00b3\u00b5\5 "+ - "\21\2\u00b4\u00a1\3\2\2\2\u00b4\u00a2\3\2\2\2\u00b4\u00a3\3\2\2\2\u00b4"+ - "\u00a7\3\2\2\2\u00b4\u00ab\3\2\2\2\u00b4\u00ac\3\2\2\2\u00b4\u00ad\3\2"+ - "\2\2\u00b4\u00b3\3\2\2\2\u00b5\37\3\2\2\2\u00b6\u00b7\7\22\2\2\u00b7\u00b8"+ - "\7\7\2\2\u00b8\u00bd\7U\2\2\u00b9\u00ba\7\5\2\2\u00ba\u00bc\7U\2\2\u00bb"+ - "\u00b9\3\2\2\2\u00bc\u00bf\3\2\2\2\u00bd\u00bb\3\2\2\2\u00bd\u00be\3\2"+ - "\2\2\u00be\u00c0\3\2\2\2\u00bf\u00bd\3\2\2\2\u00c0\u00c1\7\b\2\2\u00c1"+ - "!\3\2\2\2\u00c2\u00c4\5$\23\2\u00c3\u00c2\3\2\2\2\u00c4\u00c5\3\2\2\2"+ - "\u00c5\u00c3\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6#\3\2\2\2\u00c7\u00c8\5"+ - "\20\t\2\u00c8\u00c9\7\4\2\2\u00c9\u0114\3\2\2\2\u00ca\u00cc\7\t\2\2\u00cb"+ - "\u00cd\5\"\22\2\u00cc\u00cb\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd\u00ce\3"+ - "\2\2\2\u00ce\u0114\7\n\2\2\u00cf\u00d0\5,\27\2\u00d0\u00d1\7\4\2\2\u00d1"+ - "\u0114\3\2\2\2\u00d2\u00d3\7\23\2\2\u00d3\u00d4\7\7\2\2\u00d4\u00d5\5"+ - ",\27\2\u00d5\u00d6\7\b\2\2\u00d6\u00d9\5$\23\2\u00d7\u00d8\7\24\2\2\u00d8"+ - "\u00da\5$\23\2\u00d9\u00d7\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u0114\3\2"+ - "\2\2\u00db\u00dd\5\36\20\2\u00dc\u00db\3\2\2\2\u00dd\u00e0\3\2\2\2\u00de"+ - "\u00dc\3\2\2\2\u00de\u00df\3\2\2\2\u00df\u00e1\3\2\2\2\u00e0\u00de\3\2"+ - "\2\2\u00e1\u00e2\7\25\2\2\u00e2\u00e3\7\7\2\2\u00e3\u00e4\5,\27\2\u00e4"+ - "\u00e5\7\b\2\2\u00e5\u00e6\5$\23\2\u00e6\u0114\3\2\2\2\u00e7\u00e9\5\36"+ - "\20\2\u00e8\u00e7\3\2\2\2\u00e9\u00ec\3\2\2\2\u00ea\u00e8\3\2\2\2\u00ea"+ - "\u00eb\3\2\2\2\u00eb\u00ed\3\2\2\2\u00ec\u00ea\3\2\2\2\u00ed\u00ee\7\26"+ - "\2\2\u00ee\u00ef\5$\23\2\u00ef\u00f0\7\25\2\2\u00f0\u00f1\7\7\2\2\u00f1"+ - "\u00f2\5,\27\2\u00f2\u00f3\7\b\2\2\u00f3\u00f4\7\4\2\2\u00f4\u0114\3\2"+ - "\2\2\u00f5\u00f7\5\36\20\2\u00f6\u00f5\3\2\2\2\u00f7\u00fa\3\2\2\2\u00f8"+ - "\u00f6\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9\u00fb\3\2\2\2\u00fa\u00f8\3\2"+ - "\2\2\u00fb\u00fc\7\27\2\2\u00fc\u00fd\7\7\2\2\u00fd\u00fe\5&\24\2\u00fe"+ - "\u00ff\7\b\2\2\u00ff\u0100\5$\23\2\u0100\u0114\3\2\2\2\u0101\u0103\7\30"+ - "\2\2\u0102\u0104\5,\27\2\u0103\u0102\3\2\2\2\u0103\u0104\3\2\2\2\u0104"+ - "\u0105\3\2\2\2\u0105\u0114\7\4\2\2\u0106\u0107\7\31\2\2\u0107\u0114\7"+ - "\4\2\2\u0108\u0109\7\32\2\2\u0109\u0114\7\4\2\2\u010a\u010c\7\33\2\2\u010b"+ - "\u010d\5\64\33\2\u010c\u010b\3\2\2\2\u010c\u010d\3\2\2\2\u010d\u010e\3"+ - "\2\2\2\u010e\u010f\7\t\2\2\u010f\u0110\58\35\2\u0110\u0111\7\n\2\2\u0111"+ - "\u0114\3\2\2\2\u0112\u0114\5\62\32\2\u0113\u00c7\3\2\2\2\u0113\u00ca\3"+ - "\2\2\2\u0113\u00cf\3\2\2\2\u0113\u00d2\3\2\2\2\u0113\u00de\3\2\2\2\u0113"+ - "\u00ea\3\2\2\2\u0113\u00f8\3\2\2\2\u0113\u0101\3\2\2\2\u0113\u0106\3\2"+ - "\2\2\u0113\u0108\3\2\2\2\u0113\u010a\3\2\2\2\u0113\u0112\3\2\2\2\u0114"+ - "%\3\2\2\2\u0115\u0116\5(\25\2\u0116\u0117\7\4\2\2\u0117\u0118\5,\27\2"+ - "\u0118\u011a\7\4\2\2\u0119\u011b\5,\27\2\u011a\u0119\3\2\2\2\u011a\u011b"+ - "\3\2\2\2\u011b\u0126\3\2\2\2\u011c\u011e\5\16\b\2\u011d\u011c\3\2\2\2"+ - "\u011d\u011e\3\2\2\2\u011e\u011f\3\2\2\2\u011f\u0120\7^\2\2\u0120\u0121"+ - "\7\34\2\2\u0121\u0122\5.\30\2\u0122\u0123\7\35\2\2\u0123\u0124\5.\30\2"+ - "\u0124\u0126\3\2\2\2\u0125\u0115\3\2\2\2\u0125\u011d\3\2\2\2\u0126\'\3"+ - "\2\2\2\u0127\u0129\5\20\t\2\u0128\u0127\3\2\2\2\u0128\u0129\3\2\2\2\u0129"+ - "\u012c\3\2\2\2\u012a\u012c\5,\27\2\u012b\u0128\3\2\2\2\u012b\u012a\3\2"+ - "\2\2\u012c)\3\2\2\2\u012d\u012e\b\26\1\2\u012e\u012f\7\7\2\2\u012f\u0130"+ - "\5*\26\2\u0130\u0131\7\b\2\2\u0131\u0138\3\2\2\2\u0132\u0138\7Q\2\2\u0133"+ - "\u0135\t\2\2\2\u0134\u0136\7Q\2\2\u0135\u0134\3\2\2\2\u0135\u0136\3\2"+ - "\2\2\u0136\u0138\3\2\2\2\u0137\u012d\3\2\2\2\u0137\u0132\3\2\2\2\u0137"+ - "\u0133\3\2\2\2\u0138\u0146\3\2\2\2\u0139\u013a\f\5\2\2\u013a\u0145\7 "+ - "\2\2\u013b\u013c\f\4\2\2\u013c\u013e\7!\2\2\u013d\u013f\5.\30\2\u013e"+ - "\u013d\3\2\2\2\u013e\u013f\3\2\2\2\u013f\u0140\3\2\2\2\u0140\u0145\7\""+ - "\2\2\u0141\u0142\f\3\2\2\u0142\u0143\7\7\2\2\u0143\u0145\7\b\2\2\u0144"+ - "\u0139\3\2\2\2\u0144\u013b\3\2\2\2\u0144\u0141\3\2\2\2\u0145\u0148\3\2"+ - "\2\2\u0146\u0144\3\2\2\2\u0146\u0147\3\2\2\2\u0147+\3\2\2\2\u0148\u0146"+ - "\3\2\2\2\u0149\u014a\b\27\1\2\u014a\u014b\5.\30\2\u014b\u0151\3\2\2\2"+ - "\u014c\u014d\f\3\2\2\u014d\u014e\7\5\2\2\u014e\u0150\5.\30\2\u014f\u014c"+ - "\3\2\2\2\u0150\u0153\3\2\2\2\u0151\u014f\3\2\2\2\u0151\u0152\3\2\2\2\u0152"+ - "-\3\2\2\2\u0153\u0151\3\2\2\2\u0154\u0155\b\30\1\2\u0155\u0156\7\7\2\2"+ - "\u0156\u0157\5,\27\2\u0157\u0158\7\b\2\2\u0158\u0187\3\2\2\2\u0159\u015a"+ - "\7#\2\2\u015a\u015d\7\7\2\2\u015b\u015e\5*\26\2\u015c\u015e\5.\30\2\u015d"+ - "\u015b\3\2\2\2\u015d\u015c\3\2\2\2\u015e\u015f\3\2\2\2\u015f\u0160\7\b"+ - "\2\2\u0160\u0187\3\2\2\2\u0161\u0162\7$\2\2\u0162\u0165\7\7\2\2\u0163"+ - "\u0166\5*\26\2\u0164\u0166\5.\30\2\u0165\u0163\3\2\2\2\u0165\u0164\3\2"+ - "\2\2\u0166\u0167\3\2\2\2\u0167\u0168\7\b\2\2\u0168\u0187\3\2\2\2\u0169"+ - "\u016a\7\7\2\2\u016a\u016b\5*\26\2\u016b\u016c\7\b\2\2\u016c\u016d\5."+ - "\30\32\u016d\u0187\3\2\2\2\u016e\u016f\t\3\2\2\u016f\u0187\5.\30\31\u0170"+ - "\u0171\7 \2\2\u0171\u0187\5.\30\27\u0172\u0173\t\4\2\2\u0173\u0187\5."+ - "\30\26\u0174\u0175\t\5\2\2\u0175\u0187\5.\30\22\u0176\u0177\7\t\2\2\u0177"+ - "\u017c\5.\30\2\u0178\u0179\7\5\2\2\u0179\u017b\5.\30\2\u017a\u0178\3\2"+ - "\2\2\u017b\u017e\3\2\2\2\u017c\u017a\3\2\2\2\u017c\u017d\3\2\2\2\u017d"+ - "\u017f\3\2\2\2\u017e\u017c\3\2\2\2\u017f\u0180\7\n\2\2\u0180\u0187\3\2"+ - "\2\2\u0181\u0187\7^\2\2\u0182\u0187\7U\2\2\u0183\u0187\7R\2\2\u0184\u0187"+ - "\7S\2\2\u0185\u0187\7T\2\2\u0186\u0154\3\2\2\2\u0186\u0159\3\2\2\2\u0186"+ - "\u0161\3\2\2\2\u0186\u0169\3\2\2\2\u0186\u016e\3\2\2\2\u0186\u0170\3\2"+ - "\2\2\u0186\u0172\3\2\2\2\u0186\u0174\3\2\2\2\u0186\u0176\3\2\2\2\u0186"+ - "\u0181\3\2\2\2\u0186\u0182\3\2\2\2\u0186\u0183\3\2\2\2\u0186\u0184\3\2"+ - "\2\2\u0186\u0185\3\2\2\2\u0187\u01be\3\2\2\2\u0188\u0189\f\25\2\2\u0189"+ - "\u018a\t\6\2\2\u018a\u01bd\5.\30\26\u018b\u018c\f\24\2\2\u018c\u018d\t"+ - "\7\2\2\u018d\u01bd\5.\30\25\u018e\u018f\f\23\2\2\u018f\u0190\t\b\2\2\u0190"+ - "\u01bd\5.\30\24\u0191\u0192\f\21\2\2\u0192\u0193\t\t\2\2\u0193\u01bd\5"+ - ".\30\22\u0194\u0195\f\20\2\2\u0195\u0196\7*\2\2\u0196\u01bd\5.\30\21\u0197"+ - "\u0198\f\17\2\2\u0198\u0199\7\66\2\2\u0199\u01bd\5.\30\20\u019a\u019b"+ - "\f\16\2\2\u019b\u019c\7\67\2\2\u019c\u01bd\5.\30\17\u019d\u019e\f\r\2"+ - "\2\u019e\u019f\78\2\2\u019f\u01bd\5.\30\16\u01a0\u01a1\f\f\2\2\u01a1\u01a2"+ - "\79\2\2\u01a2\u01bd\5.\30\r\u01a3\u01a4\f\13\2\2\u01a4\u01a5\7:\2\2\u01a5"+ - "\u01a6\5.\30\2\u01a6\u01a7\7\34\2\2\u01a7\u01a8\5.\30\f\u01a8\u01bd\3"+ - "\2\2\2\u01a9\u01aa\f\n\2\2\u01aa\u01ab\7\6\2\2\u01ab\u01bd\5.\30\n\u01ac"+ - "\u01ad\f\t\2\2\u01ad\u01ae\t\n\2\2\u01ae\u01bd\5.\30\t\u01af\u01b0\f\36"+ - "\2\2\u01b0\u01b2\7\7\2\2\u01b1\u01b3\5\60\31\2\u01b2\u01b1\3\2\2\2\u01b2"+ - "\u01b3\3\2\2\2\u01b3\u01b4\3\2\2\2\u01b4\u01bd\7\b\2\2\u01b5\u01b6\f\33"+ - "\2\2\u01b6\u01b7\7!\2\2\u01b7\u01b8\5,\27\2\u01b8\u01b9\7\"\2\2\u01b9"+ - "\u01bd\3\2\2\2\u01ba\u01bb\f\30\2\2\u01bb\u01bd\t\3\2\2\u01bc\u0188\3"+ - "\2\2\2\u01bc\u018b\3\2\2\2\u01bc\u018e\3\2\2\2\u01bc\u0191\3\2\2\2\u01bc"+ - "\u0194\3\2\2\2\u01bc\u0197\3\2\2\2\u01bc\u019a\3\2\2\2\u01bc\u019d\3\2"+ - "\2\2\u01bc\u01a0\3\2\2\2\u01bc\u01a3\3\2\2\2\u01bc\u01a9\3\2\2\2\u01bc"+ - "\u01ac\3\2\2\2\u01bc\u01af\3\2\2\2\u01bc\u01b5\3\2\2\2\u01bc\u01ba\3\2"+ - "\2\2\u01bd\u01c0\3\2\2\2\u01be\u01bc\3\2\2\2\u01be\u01bf\3\2\2\2\u01bf"+ - "/\3\2\2\2\u01c0\u01be\3\2\2\2\u01c1\u01c6\5.\30\2\u01c2\u01c3\7\5\2\2"+ - "\u01c3\u01c5\5.\30\2\u01c4\u01c2\3\2\2\2\u01c5\u01c8\3\2\2\2\u01c6\u01c4"+ - "\3\2\2\2\u01c6\u01c7\3\2\2\2\u01c7\61\3\2\2\2\u01c8\u01c6\3\2\2\2\u01c9"+ - "\u01cb\7E\2\2\u01ca\u01cc\5\64\33\2\u01cb\u01ca\3\2\2\2\u01cb\u01cc\3"+ - "\2\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01ce\7P\2\2\u01ce\63\3\2\2\2\u01cf\u01d0"+ - "\7\7\2\2\u01d0\u01d5\5\66\34\2\u01d1\u01d2\7\5\2\2\u01d2\u01d4\5\66\34"+ - "\2\u01d3\u01d1\3\2\2\2\u01d4\u01d7\3\2\2\2\u01d5\u01d3\3\2\2\2\u01d5\u01d6"+ - "\3\2\2\2\u01d6\u01d8\3\2\2\2\u01d7\u01d5\3\2\2\2\u01d8\u01d9\7\b\2\2\u01d9"+ - "\65\3\2\2\2\u01da\u01db\7F\2\2\u01db\u01ea\7R\2\2\u01dc\u01dd\7G\2\2\u01dd"+ - "\u01ea\7^\2\2\u01de\u01df\7H\2\2\u01df\u01ea\7R\2\2\u01e0\u01e1\7I\2\2"+ - "\u01e1\u01ea\5.\30\2\u01e2\u01e3\7J\2\2\u01e3\u01ea\5.\30\2\u01e4\u01e7"+ - "\7K\2\2\u01e5\u01e8\7\17\2\2\u01e6\u01e8\5.\30\2\u01e7\u01e5\3\2\2\2\u01e7"+ - "\u01e6\3\2\2\2\u01e8\u01ea\3\2\2\2\u01e9\u01da\3\2\2\2\u01e9\u01dc\3\2"+ - "\2\2\u01e9\u01de\3\2\2\2\u01e9\u01e0\3\2\2\2\u01e9\u01e2\3\2\2\2\u01e9"+ - "\u01e4\3\2\2\2\u01ea\67\3\2\2\2\u01eb\u01ed\5:\36\2\u01ec\u01eb\3\2\2"+ - "\2\u01ed\u01f0\3\2\2\2\u01ee\u01ec\3\2\2\2\u01ee\u01ef\3\2\2\2\u01ef9"+ - "\3\2\2\2\u01f0\u01ee\3\2\2\2\u01f1\u01f5\5<\37\2\u01f2\u01f5\5> \2\u01f3"+ - "\u01f5\5@!\2\u01f4\u01f1\3\2\2\2\u01f4\u01f2\3\2\2\2\u01f4\u01f3\3\2\2"+ - "\2\u01f5;\3\2\2\2\u01f6\u01f7\7^\2\2\u01f7\u01fe\7\34\2\2\u01f8\u01fa"+ - "\7)\2\2\u01f9\u01fb\7^\2\2\u01fa\u01f9\3\2\2\2\u01fa\u01fb\3\2\2\2\u01fb"+ - "\u01fc\3\2\2\2\u01fc\u01fe\7\34\2\2\u01fd\u01f6\3\2\2\2\u01fd\u01f8\3"+ - "\2\2\2\u01fe=\3\2\2\2\u01ff\u0201\7O\2\2\u0200\u0202\5B\"\2\u0201\u0200"+ - "\3\2\2\2\u0201\u0202\3\2\2\2\u0202?\3\2\2\2\u0203\u0204\7L\2\2\u0204\u0209"+ - "\5D#\2\u0205\u0206\7\5\2\2\u0206\u0208\5D#\2\u0207\u0205\3\2\2\2\u0208"+ - "\u020b\3\2\2\2\u0209\u0207\3\2\2\2\u0209\u020a\3\2\2\2\u020aA\3\2\2\2"+ - "\u020b\u0209\3\2\2\2\u020c\u0224\5D#\2\u020d\u020e\7M\2\2\u020e\u0224"+ - "\5D#\2\u020f\u0210\5D#\2\u0210\u0211\7\5\2\2\u0211\u0212\7^\2\2\u0212"+ - "\u0224\3\2\2\2\u0213\u0214\7\7\2\2\u0214\u0215\5D#\2\u0215\u0216\7\b\2"+ - "\2\u0216\u0217\7\5\2\2\u0217\u0218\7^\2\2\u0218\u0224\3\2\2\2\u0219\u021a"+ - "\7\7\2\2\u021a\u021b\5D#\2\u021b\u021c\7\5\2\2\u021c\u021d\7^\2\2\u021d"+ - "\u021e\7\b\2\2\u021e\u0224\3\2\2\2\u021f\u0220\7\7\2\2\u0220\u0221\5D"+ - "#\2\u0221\u0222\7\b\2\2\u0222\u0224\3\2\2\2\u0223\u020c\3\2\2\2\u0223"+ - "\u020d\3\2\2\2\u0223\u020f\3\2\2\2\u0223\u0213\3\2\2\2\u0223\u0219\3\2"+ - "\2\2\u0223\u021f\3\2\2\2\u0224C\3\2\2\2\u0225\u0226\b#\1\2\u0226\u0227"+ - "\7!\2\2\u0227\u0228\5D#\2\u0228\u0229\7\"\2\2\u0229\u0234\3\2\2\2\u022a"+ - "\u022b\t\13\2\2\u022b\u0234\5D#\n\u022c\u0234\7^\2\2\u022d\u0234\7_\2"+ - "\2\u022e\u022f\7\t\2\2\u022f\u0230\7^\2\2\u0230\u0234\7\n\2\2\u0231\u0234"+ - "\7U\2\2\u0232\u0234\7S\2\2\u0233\u0225\3\2\2\2\u0233\u022a\3\2\2\2\u0233"+ - "\u022c\3\2\2\2\u0233\u022d\3\2\2\2\u0233\u022e\3\2\2\2\u0233\u0231\3\2"+ - "\2\2\u0233\u0232\3\2\2\2\u0234\u0243\3\2\2\2\u0235\u0236\f\f\2\2\u0236"+ - "\u0237\7N\2\2\u0237\u0242\5D#\r\u0238\u0239\f\13\2\2\u0239\u023a\t\6\2"+ - "\2\u023a\u0242\5D#\f\u023b\u023c\f\t\2\2\u023c\u023d\t\f\2\2\u023d\u0242"+ - "\5D#\n\u023e\u023f\f\b\2\2\u023f\u0240\t\b\2\2\u0240\u0242\5D#\t\u0241"+ - "\u0235\3\2\2\2\u0241\u0238\3\2\2\2\u0241\u023b\3\2\2\2\u0241\u023e\3\2"+ - "\2\2\u0242\u0245\3\2\2\2\u0243\u0241\3\2\2\2\u0243\u0244\3\2\2\2\u0244"+ - "E\3\2\2\2\u0245\u0243\3\2\2\2:PYafm{\u0081\u0087\u008c\u0095\u009c\u00b1"+ - "\u00b4\u00bd\u00c5\u00cc\u00d9\u00de\u00ea\u00f8\u0103\u010c\u0113\u011a"+ - "\u011d\u0125\u0128\u012b\u0135\u0137\u013e\u0144\u0146\u0151\u015d\u0165"+ - "\u017c\u0186\u01b2\u01bc\u01be\u01c6\u01cb\u01d5\u01e7\u01e9\u01ee\u01f4"+ - "\u01fa\u01fd\u0201\u0209\u0223\u0233\u0241\u0243"; + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\4\7"+ + "\4U\n\4\f\4\16\4X\13\4\3\5\3\5\3\5\3\6\6\6^\n\6\r\6\16\6_\3\7\3\7\3\7"+ + "\3\7\3\7\3\7\3\7\3\7\3\7\5\7k\n\7\3\b\7\bn\n\b\f\b\16\bq\13\b\3\b\3\b"+ + "\7\bu\n\b\f\b\16\bx\13\b\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\7\n\u0083"+ + "\n\n\f\n\16\n\u0086\13\n\3\13\3\13\3\13\5\13\u008b\n\13\3\f\3\f\3\f\3"+ + "\f\5\f\u0091\n\f\3\f\3\f\3\f\5\f\u0096\n\f\3\f\3\f\3\r\3\r\3\r\7\r\u009d"+ + "\n\r\f\r\16\r\u00a0\13\r\3\16\3\16\3\16\3\16\5\16\u00a6\n\16\3\17\3\17"+ + "\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20"+ + "\3\20\3\20\3\20\5\20\u00bb\n\20\3\20\5\20\u00be\n\20\3\21\3\21\3\21\3"+ + "\21\3\21\7\21\u00c5\n\21\f\21\16\21\u00c8\13\21\3\21\3\21\3\22\6\22\u00cd"+ + "\n\22\r\22\16\22\u00ce\3\23\3\23\3\23\3\23\3\23\5\23\u00d6\n\23\3\23\3"+ + "\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u00e3\n\23\3\23"+ + "\7\23\u00e6\n\23\f\23\16\23\u00e9\13\23\3\23\3\23\3\23\3\23\3\23\3\23"+ + "\3\23\7\23\u00f2\n\23\f\23\16\23\u00f5\13\23\3\23\3\23\3\23\3\23\3\23"+ + "\3\23\3\23\3\23\3\23\7\23\u0100\n\23\f\23\16\23\u0103\13\23\3\23\3\23"+ + "\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u010d\n\23\3\23\3\23\3\23\3\23\3\23"+ + "\3\23\3\23\5\23\u0116\n\23\3\23\3\23\3\23\3\23\3\23\5\23\u011d\n\23\3"+ + "\24\3\24\3\24\3\24\3\24\5\24\u0124\n\24\3\24\5\24\u0127\n\24\3\24\3\24"+ + "\3\24\3\24\3\24\3\24\5\24\u012f\n\24\3\25\5\25\u0132\n\25\3\25\5\25\u0135"+ + "\n\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\5\26\u013f\n\26\3\26\3\26"+ + "\5\26\u0143\n\26\3\26\3\26\3\26\3\26\3\26\5\26\u014a\n\26\3\26\3\26\3"+ + "\26\3\26\7\26\u0150\n\26\f\26\16\26\u0153\13\26\3\27\3\27\3\27\3\30\3"+ + "\30\5\30\u015a\n\30\3\30\3\30\6\30\u015e\n\30\r\30\16\30\u015f\3\30\3"+ + "\30\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\7\32\u016d\n\32\f\32"+ + "\16\32\u0170\13\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u017b"+ + "\n\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u0183\n\33\3\33\3\33\3\33\3\33"+ + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ + "\3\33\7\33\u0198\n\33\f\33\16\33\u019b\13\33\3\33\3\33\3\33\3\33\3\33"+ + "\6\33\u01a2\n\33\r\33\16\33\u01a3\3\33\3\33\5\33\u01a8\n\33\3\33\3\33"+ + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ + "\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ + "\3\33\3\33\3\33\3\33\5\33\u01da\n\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+ + "\3\33\7\33\u01e4\n\33\f\33\16\33\u01e7\13\33\3\34\3\34\3\34\7\34\u01ec"+ + "\n\34\f\34\16\34\u01ef\13\34\3\35\3\35\5\35\u01f3\n\35\3\35\3\35\3\36"+ + "\3\36\3\36\3\36\7\36\u01fb\n\36\f\36\16\36\u01fe\13\36\3\36\3\36\3\37"+ + "\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\5\37\u020f"+ + "\n\37\5\37\u0211\n\37\3 \7 \u0214\n \f \16 \u0217\13 \3!\3!\3!\5!\u021c"+ + "\n!\3\"\3\"\3\"\3\"\5\"\u0222\n\"\3\"\5\"\u0225\n\"\3#\3#\5#\u0229\n#"+ + "\3$\3$\3$\3$\7$\u022f\n$\f$\16$\u0232\13$\3%\3%\3%\3%\3%\3%\3%\3%\3%\3"+ + "%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\3%\5%\u024b\n%\3&\3&\3&\3&\3&\3"+ + "&\3&\3&\3&\3&\3&\3&\3&\3&\5&\u025b\n&\3&\3&\3&\3&\3&\3&\3&\3&\3&\3&\3"+ + "&\3&\7&\u0269\n&\f&\16&\u026c\13&\3&\2\7\22*\62\64J\'\2\4\6\b\n\f\16\20"+ + "\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJ\2\r\3\2\36\37\3\2"+ + "()\3\2*.\3\2\63\64\3\2/\60\4\2 \61\62\3\2*+\3\2\638\3\2>G\4\2*+\63\64"+ + "\4\2 \61\61\2\u02c5\2L\3\2\2\2\4P\3\2\2\2\6V\3\2\2\2\bY\3\2\2\2\n]\3"+ + "\2\2\2\fj\3\2\2\2\16o\3\2\2\2\20y\3\2\2\2\22|\3\2\2\2\24\u0087\3\2\2\2"+ + "\26\u008c\3\2\2\2\30\u0099\3\2\2\2\32\u00a5\3\2\2\2\34\u00a7\3\2\2\2\36"+ + "\u00bd\3\2\2\2 \u00bf\3\2\2\2\"\u00cc\3\2\2\2$\u011c\3\2\2\2&\u012e\3"+ + "\2\2\2(\u0134\3\2\2\2*\u0142\3\2\2\2,\u0154\3\2\2\2.\u0157\3\2\2\2\60"+ + "\u0163\3\2\2\2\62\u0166\3\2\2\2\64\u01a7\3\2\2\2\66\u01e8\3\2\2\28\u01f0"+ + "\3\2\2\2:\u01f6\3\2\2\2<\u0210\3\2\2\2>\u0215\3\2\2\2@\u021b\3\2\2\2B"+ + "\u0224\3\2\2\2D\u0226\3\2\2\2F\u022a\3\2\2\2H\u024a\3\2\2\2J\u025a\3\2"+ + "\2\2LM\5\6\4\2MN\5\n\6\2NO\7\2\2\3O\3\3\2\2\2PQ\5> \2QR\7\2\2\3R\5\3\2"+ + "\2\2SU\5\b\5\2TS\3\2\2\2UX\3\2\2\2VT\3\2\2\2VW\3\2\2\2W\7\3\2\2\2XV\3"+ + "\2\2\2YZ\7\3\2\2Z[\7T\2\2[\t\3\2\2\2\\^\5\f\7\2]\\\3\2\2\2^_\3\2\2\2_"+ + "]\3\2\2\2_`\3\2\2\2`\13\3\2\2\2ab\5\20\t\2bc\7\4\2\2ck\3\2\2\2de\5.\30"+ + "\2ef\7\4\2\2fk\3\2\2\2gk\5\26\f\2hk\58\35\2ik\5\34\17\2ja\3\2\2\2jd\3"+ + "\2\2\2jg\3\2\2\2jh\3\2\2\2ji\3\2\2\2k\r\3\2\2\2ln\5\36\20\2ml\3\2\2\2"+ + "nq\3\2\2\2om\3\2\2\2op\3\2\2\2pr\3\2\2\2qo\3\2\2\2rv\5*\26\2su\5\36\20"+ + "\2ts\3\2\2\2ux\3\2\2\2vt\3\2\2\2vw\3\2\2\2w\17\3\2\2\2xv\3\2\2\2yz\5\16"+ + "\b\2z{\5\22\n\2{\21\3\2\2\2|}\b\n\1\2}~\5\24\13\2~\u0084\3\2\2\2\177\u0080"+ + "\f\3\2\2\u0080\u0081\7\5\2\2\u0081\u0083\5\24\13\2\u0082\177\3\2\2\2\u0083"+ + "\u0086\3\2\2\2\u0084\u0082\3\2\2\2\u0084\u0085\3\2\2\2\u0085\23\3\2\2"+ + "\2\u0086\u0084\3\2\2\2\u0087\u008a\7`\2\2\u0088\u0089\7\6\2\2\u0089\u008b"+ + "\5\64\33\2\u008a\u0088\3\2\2\2\u008a\u008b\3\2\2\2\u008b\25\3\2\2\2\u008c"+ + "\u008d\5\16\b\2\u008d\u008e\7`\2\2\u008e\u0090\7\7\2\2\u008f\u0091\5\30"+ + "\r\2\u0090\u008f\3\2\2\2\u0090\u0091\3\2\2\2\u0091\u0092\3\2\2\2\u0092"+ + "\u0093\7\b\2\2\u0093\u0095\7\t\2\2\u0094\u0096\5\"\22\2\u0095\u0094\3"+ + "\2\2\2\u0095\u0096\3\2\2\2\u0096\u0097\3\2\2\2\u0097\u0098\7\n\2\2\u0098"+ + "\27\3\2\2\2\u0099\u009e\5\32\16\2\u009a\u009b\7\5\2\2\u009b\u009d\5\32"+ + "\16\2\u009c\u009a\3\2\2\2\u009d\u00a0\3\2\2\2\u009e\u009c\3\2\2\2\u009e"+ + "\u009f\3\2\2\2\u009f\31\3\2\2\2\u00a0\u009e\3\2\2\2\u00a1\u00a2\5\16\b"+ + "\2\u00a2\u00a3\7`\2\2\u00a3\u00a6\3\2\2\2\u00a4\u00a6\7S\2\2\u00a5\u00a1"+ + "\3\2\2\2\u00a5\u00a4\3\2\2\2\u00a6\33\3\2\2\2\u00a7\u00a8\5 \21\2\u00a8"+ + "\u00a9\7\4\2\2\u00a9\35\3\2\2\2\u00aa\u00be\7\13\2\2\u00ab\u00be\7\f\2"+ + "\2\u00ac\u00ad\7\r\2\2\u00ad\u00ae\7\7\2\2\u00ae\u00af\7W\2\2\u00af\u00be"+ + "\7\b\2\2\u00b0\u00b1\7\16\2\2\u00b1\u00b2\7\7\2\2\u00b2\u00b3\7`\2\2\u00b3"+ + "\u00be\7\b\2\2\u00b4\u00be\7\17\2\2\u00b5\u00be\7\20\2\2\u00b6\u00ba\7"+ + "\21\2\2\u00b7\u00b8\7\7\2\2\u00b8\u00b9\7`\2\2\u00b9\u00bb\7\b\2\2\u00ba"+ + "\u00b7\3\2\2\2\u00ba\u00bb\3\2\2\2\u00bb\u00be\3\2\2\2\u00bc\u00be\5 "+ + "\21\2\u00bd\u00aa\3\2\2\2\u00bd\u00ab\3\2\2\2\u00bd\u00ac\3\2\2\2\u00bd"+ + "\u00b0\3\2\2\2\u00bd\u00b4\3\2\2\2\u00bd\u00b5\3\2\2\2\u00bd\u00b6\3\2"+ + "\2\2\u00bd\u00bc\3\2\2\2\u00be\37\3\2\2\2\u00bf\u00c0\7\22\2\2\u00c0\u00c1"+ + "\7\7\2\2\u00c1\u00c6\7W\2\2\u00c2\u00c3\7\5\2\2\u00c3\u00c5\7W\2\2\u00c4"+ + "\u00c2\3\2\2\2\u00c5\u00c8\3\2\2\2\u00c6\u00c4\3\2\2\2\u00c6\u00c7\3\2"+ + "\2\2\u00c7\u00c9\3\2\2\2\u00c8\u00c6\3\2\2\2\u00c9\u00ca\7\b\2\2\u00ca"+ + "!\3\2\2\2\u00cb\u00cd\5$\23\2\u00cc\u00cb\3\2\2\2\u00cd\u00ce\3\2\2\2"+ + "\u00ce\u00cc\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf#\3\2\2\2\u00d0\u00d1\5"+ + "\20\t\2\u00d1\u00d2\7\4\2\2\u00d2\u011d\3\2\2\2\u00d3\u00d5\7\t\2\2\u00d4"+ + "\u00d6\5\"\22\2\u00d5\u00d4\3\2\2\2\u00d5\u00d6\3\2\2\2\u00d6\u00d7\3"+ + "\2\2\2\u00d7\u011d\7\n\2\2\u00d8\u00d9\5\62\32\2\u00d9\u00da\7\4\2\2\u00da"+ + "\u011d\3\2\2\2\u00db\u00dc\7\23\2\2\u00dc\u00dd\7\7\2\2\u00dd\u00de\5"+ + "\62\32\2\u00de\u00df\7\b\2\2\u00df\u00e2\5$\23\2\u00e0\u00e1\7\24\2\2"+ + "\u00e1\u00e3\5$\23\2\u00e2\u00e0\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\u011d"+ + "\3\2\2\2\u00e4\u00e6\5\36\20\2\u00e5\u00e4\3\2\2\2\u00e6\u00e9\3\2\2\2"+ + "\u00e7\u00e5\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8\u00ea\3\2\2\2\u00e9\u00e7"+ + "\3\2\2\2\u00ea\u00eb\7\25\2\2\u00eb\u00ec\7\7\2\2\u00ec\u00ed\5\62\32"+ + "\2\u00ed\u00ee\7\b\2\2\u00ee\u00ef\5$\23\2\u00ef\u011d\3\2\2\2\u00f0\u00f2"+ + "\5\36\20\2\u00f1\u00f0\3\2\2\2\u00f2\u00f5\3\2\2\2\u00f3\u00f1\3\2\2\2"+ + "\u00f3\u00f4\3\2\2\2\u00f4\u00f6\3\2\2\2\u00f5\u00f3\3\2\2\2\u00f6\u00f7"+ + "\7\26\2\2\u00f7\u00f8\5$\23\2\u00f8\u00f9\7\25\2\2\u00f9\u00fa\7\7\2\2"+ + "\u00fa\u00fb\5\62\32\2\u00fb\u00fc\7\b\2\2\u00fc\u00fd\7\4\2\2\u00fd\u011d"+ + "\3\2\2\2\u00fe\u0100\5\36\20\2\u00ff\u00fe\3\2\2\2\u0100\u0103\3\2\2\2"+ + "\u0101\u00ff\3\2\2\2\u0101\u0102\3\2\2\2\u0102\u0104\3\2\2\2\u0103\u0101"+ + "\3\2\2\2\u0104\u0105\7\27\2\2\u0105\u0106\7\7\2\2\u0106\u0107\5&\24\2"+ + "\u0107\u0108\7\b\2\2\u0108\u0109\5$\23\2\u0109\u011d\3\2\2\2\u010a\u010c"+ + "\7\30\2\2\u010b\u010d\5\62\32\2\u010c\u010b\3\2\2\2\u010c\u010d\3\2\2"+ + "\2\u010d\u010e\3\2\2\2\u010e\u011d\7\4\2\2\u010f\u0110\7\31\2\2\u0110"+ + "\u011d\7\4\2\2\u0111\u0112\7\32\2\2\u0112\u011d\7\4\2\2\u0113\u0115\7"+ + "\33\2\2\u0114\u0116\5:\36\2\u0115\u0114\3\2\2\2\u0115\u0116\3\2\2\2\u0116"+ + "\u0117\3\2\2\2\u0117\u0118\7\t\2\2\u0118\u0119\5> \2\u0119\u011a\7\n\2"+ + "\2\u011a\u011d\3\2\2\2\u011b\u011d\58\35\2\u011c\u00d0\3\2\2\2\u011c\u00d3"+ + "\3\2\2\2\u011c\u00d8\3\2\2\2\u011c\u00db\3\2\2\2\u011c\u00e7\3\2\2\2\u011c"+ + "\u00f3\3\2\2\2\u011c\u0101\3\2\2\2\u011c\u010a\3\2\2\2\u011c\u010f\3\2"+ + "\2\2\u011c\u0111\3\2\2\2\u011c\u0113\3\2\2\2\u011c\u011b\3\2\2\2\u011d"+ + "%\3\2\2\2\u011e\u011f\5(\25\2\u011f\u0120\7\4\2\2\u0120\u0121\5\62\32"+ + "\2\u0121\u0123\7\4\2\2\u0122\u0124\5\62\32\2\u0123\u0122\3\2\2\2\u0123"+ + "\u0124\3\2\2\2\u0124\u012f\3\2\2\2\u0125\u0127\5\16\b\2\u0126\u0125\3"+ + "\2\2\2\u0126\u0127\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u0129\7`\2\2\u0129"+ + "\u012a\7\34\2\2\u012a\u012b\5\64\33\2\u012b\u012c\7\35\2\2\u012c\u012d"+ + "\5\64\33\2\u012d\u012f\3\2\2\2\u012e\u011e\3\2\2\2\u012e\u0126\3\2\2\2"+ + "\u012f\'\3\2\2\2\u0130\u0132\5\20\t\2\u0131\u0130\3\2\2\2\u0131\u0132"+ + "\3\2\2\2\u0132\u0135\3\2\2\2\u0133\u0135\5\62\32\2\u0134\u0131\3\2\2\2"+ + "\u0134\u0133\3\2\2\2\u0135)\3\2\2\2\u0136\u0137\b\26\1\2\u0137\u0138\7"+ + "\7\2\2\u0138\u0139\5*\26\2\u0139\u013a\7\b\2\2\u013a\u0143\3\2\2\2\u013b"+ + "\u0143\7S\2\2\u013c\u013e\t\2\2\2\u013d\u013f\7S\2\2\u013e\u013d\3\2\2"+ + "\2\u013e\u013f\3\2\2\2\u013f\u0143\3\2\2\2\u0140\u0143\5.\30\2\u0141\u0143"+ + "\5,\27\2\u0142\u0136\3\2\2\2\u0142\u013b\3\2\2\2\u0142\u013c\3\2\2\2\u0142"+ + "\u0140\3\2\2\2\u0142\u0141\3\2\2\2\u0143\u0151\3\2\2\2\u0144\u0145\f\7"+ + "\2\2\u0145\u0150\7 \2\2\u0146\u0147\f\6\2\2\u0147\u0149\7!\2\2\u0148\u014a"+ + "\5\64\33\2\u0149\u0148\3\2\2\2\u0149\u014a\3\2\2\2\u014a\u014b\3\2\2\2"+ + "\u014b\u0150\7\"\2\2\u014c\u014d\f\5\2\2\u014d\u014e\7\7\2\2\u014e\u0150"+ + "\7\b\2\2\u014f\u0144\3\2\2\2\u014f\u0146\3\2\2\2\u014f\u014c\3\2\2\2\u0150"+ + "\u0153\3\2\2\2\u0151\u014f\3\2\2\2\u0151\u0152\3\2\2\2\u0152+\3\2\2\2"+ + "\u0153\u0151\3\2\2\2\u0154\u0155\7#\2\2\u0155\u0156\7`\2\2\u0156-\3\2"+ + "\2\2\u0157\u0159\7#\2\2\u0158\u015a\7`\2\2\u0159\u0158\3\2\2\2\u0159\u015a"+ + "\3\2\2\2\u015a\u015b\3\2\2\2\u015b\u015d\7\t\2\2\u015c\u015e\5\60\31\2"+ + "\u015d\u015c\3\2\2\2\u015e\u015f\3\2\2\2\u015f\u015d\3\2\2\2\u015f\u0160"+ + "\3\2\2\2\u0160\u0161\3\2\2\2\u0161\u0162\7\n\2\2\u0162/\3\2\2\2\u0163"+ + "\u0164\5\20\t\2\u0164\u0165\7\4\2\2\u0165\61\3\2\2\2\u0166\u0167\b\32"+ + "\1\2\u0167\u0168\5\64\33\2\u0168\u016e\3\2\2\2\u0169\u016a\f\3\2\2\u016a"+ + "\u016b\7\5\2\2\u016b\u016d\5\64\33\2\u016c\u0169\3\2\2\2\u016d\u0170\3"+ + "\2\2\2\u016e\u016c\3\2\2\2\u016e\u016f\3\2\2\2\u016f\63\3\2\2\2\u0170"+ + "\u016e\3\2\2\2\u0171\u0172\b\33\1\2\u0172\u0173\7\7\2\2\u0173\u0174\5"+ + "\62\32\2\u0174\u0175\7\b\2\2\u0175\u01a8\3\2\2\2\u0176\u0177\7&\2\2\u0177"+ + "\u017a\7\7\2\2\u0178\u017b\5*\26\2\u0179\u017b\5\64\33\2\u017a\u0178\3"+ + "\2\2\2\u017a\u0179\3\2\2\2\u017b\u017c\3\2\2\2\u017c\u017d\7\b\2\2\u017d"+ + "\u01a8\3\2\2\2\u017e\u017f\7\'\2\2\u017f\u0182\7\7\2\2\u0180\u0183\5*"+ + "\26\2\u0181\u0183\5\64\33\2\u0182\u0180\3\2\2\2\u0182\u0181\3\2\2\2\u0183"+ + "\u0184\3\2\2\2\u0184\u0185\7\b\2\2\u0185\u01a8\3\2\2\2\u0186\u0187\7\7"+ + "\2\2\u0187\u0188\5*\26\2\u0188\u0189\7\b\2\2\u0189\u018a\5\64\33\32\u018a"+ + "\u01a8\3\2\2\2\u018b\u018c\t\3\2\2\u018c\u01a8\5\64\33\31\u018d\u018e"+ + "\7 \2\2\u018e\u01a8\5\64\33\27\u018f\u0190\t\4\2\2\u0190\u01a8\5\64\33"+ + "\26\u0191\u0192\t\5\2\2\u0192\u01a8\5\64\33\22\u0193\u0194\7\t\2\2\u0194"+ + "\u0199\5\64\33\2\u0195\u0196\7\5\2\2\u0196\u0198\5\64\33\2\u0197\u0195"+ + "\3\2\2\2\u0198\u019b\3\2\2\2\u0199\u0197\3\2\2\2\u0199\u019a\3\2\2\2\u019a"+ + "\u019c\3\2\2\2\u019b\u0199\3\2\2\2\u019c\u019d\7\n\2\2\u019d\u01a8\3\2"+ + "\2\2\u019e\u01a8\7`\2\2\u019f\u01a8\7W\2\2\u01a0\u01a2\7T\2\2\u01a1\u01a0"+ + "\3\2\2\2\u01a2\u01a3\3\2\2\2\u01a3\u01a1\3\2\2\2\u01a3\u01a4\3\2\2\2\u01a4"+ + "\u01a8\3\2\2\2\u01a5\u01a8\7U\2\2\u01a6\u01a8\7V\2\2\u01a7\u0171\3\2\2"+ + "\2\u01a7\u0176\3\2\2\2\u01a7\u017e\3\2\2\2\u01a7\u0186\3\2\2\2\u01a7\u018b"+ + "\3\2\2\2\u01a7\u018d\3\2\2\2\u01a7\u018f\3\2\2\2\u01a7\u0191\3\2\2\2\u01a7"+ + "\u0193\3\2\2\2\u01a7\u019e\3\2\2\2\u01a7\u019f\3\2\2\2\u01a7\u01a1\3\2"+ + "\2\2\u01a7\u01a5\3\2\2\2\u01a7\u01a6\3\2\2\2\u01a8\u01e5\3\2\2\2\u01a9"+ + "\u01aa\f\25\2\2\u01aa\u01ab\t\6\2\2\u01ab\u01e4\5\64\33\26\u01ac\u01ad"+ + "\f\24\2\2\u01ad\u01ae\t\7\2\2\u01ae\u01e4\5\64\33\25\u01af\u01b0\f\23"+ + "\2\2\u01b0\u01b1\t\b\2\2\u01b1\u01e4\5\64\33\24\u01b2\u01b3\f\21\2\2\u01b3"+ + "\u01b4\t\t\2\2\u01b4\u01e4\5\64\33\22\u01b5\u01b6\f\20\2\2\u01b6\u01b7"+ + "\7-\2\2\u01b7\u01e4\5\64\33\21\u01b8\u01b9\f\17\2\2\u01b9\u01ba\79\2\2"+ + "\u01ba\u01e4\5\64\33\20\u01bb\u01bc\f\16\2\2\u01bc\u01bd\7:\2\2\u01bd"+ + "\u01e4\5\64\33\17\u01be\u01bf\f\r\2\2\u01bf\u01c0\7;\2\2\u01c0\u01e4\5"+ + "\64\33\16\u01c1\u01c2\f\f\2\2\u01c2\u01c3\7<\2\2\u01c3\u01e4\5\64\33\r"+ + "\u01c4\u01c5\f\13\2\2\u01c5\u01c6\7=\2\2\u01c6\u01c7\5\64\33\2\u01c7\u01c8"+ + "\7\34\2\2\u01c8\u01c9\5\64\33\f\u01c9\u01e4\3\2\2\2\u01ca\u01cb\f\n\2"+ + "\2\u01cb\u01cc\7\6\2\2\u01cc\u01e4\5\64\33\n\u01cd\u01ce\f\t\2\2\u01ce"+ + "\u01cf\t\n\2\2\u01cf\u01e4\5\64\33\t\u01d0\u01d1\f \2\2\u01d1\u01d2\7"+ + "$\2\2\u01d2\u01e4\7`\2\2\u01d3\u01d4\f\37\2\2\u01d4\u01d5\7%\2\2\u01d5"+ + "\u01e4\7`\2\2\u01d6\u01d7\f\36\2\2\u01d7\u01d9\7\7\2\2\u01d8\u01da\5\66"+ + "\34\2\u01d9\u01d8\3\2\2\2\u01d9\u01da\3\2\2\2\u01da\u01db\3\2\2\2\u01db"+ + "\u01e4\7\b\2\2\u01dc\u01dd\f\33\2\2\u01dd\u01de\7!\2\2\u01de\u01df\5\62"+ + "\32\2\u01df\u01e0\7\"\2\2\u01e0\u01e4\3\2\2\2\u01e1\u01e2\f\30\2\2\u01e2"+ + "\u01e4\t\3\2\2\u01e3\u01a9\3\2\2\2\u01e3\u01ac\3\2\2\2\u01e3\u01af\3\2"+ + "\2\2\u01e3\u01b2\3\2\2\2\u01e3\u01b5\3\2\2\2\u01e3\u01b8\3\2\2\2\u01e3"+ + "\u01bb\3\2\2\2\u01e3\u01be\3\2\2\2\u01e3\u01c1\3\2\2\2\u01e3\u01c4\3\2"+ + "\2\2\u01e3\u01ca\3\2\2\2\u01e3\u01cd\3\2\2\2\u01e3\u01d0\3\2\2\2\u01e3"+ + "\u01d3\3\2\2\2\u01e3\u01d6\3\2\2\2\u01e3\u01dc\3\2\2\2\u01e3\u01e1\3\2"+ + "\2\2\u01e4\u01e7\3\2\2\2\u01e5\u01e3\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6"+ + "\65\3\2\2\2\u01e7\u01e5\3\2\2\2\u01e8\u01ed\5\64\33\2\u01e9\u01ea\7\5"+ + "\2\2\u01ea\u01ec\5\64\33\2\u01eb\u01e9\3\2\2\2\u01ec\u01ef\3\2\2\2\u01ed"+ + "\u01eb\3\2\2\2\u01ed\u01ee\3\2\2\2\u01ee\67\3\2\2\2\u01ef\u01ed\3\2\2"+ + "\2\u01f0\u01f2\7H\2\2\u01f1\u01f3\5:\36\2\u01f2\u01f1\3\2\2\2\u01f2\u01f3"+ + "\3\2\2\2\u01f3\u01f4\3\2\2\2\u01f4\u01f5\7R\2\2\u01f59\3\2\2\2\u01f6\u01f7"+ + "\7\7\2\2\u01f7\u01fc\5<\37\2\u01f8\u01f9\7\5\2\2\u01f9\u01fb\5<\37\2\u01fa"+ + "\u01f8\3\2\2\2\u01fb\u01fe\3\2\2\2\u01fc\u01fa\3\2\2\2\u01fc\u01fd\3\2"+ + "\2\2\u01fd\u01ff\3\2\2\2\u01fe\u01fc\3\2\2\2\u01ff\u0200\7\b\2\2\u0200"+ + ";\3\2\2\2\u0201\u0202\7I\2\2\u0202\u0211\7T\2\2\u0203\u0204\7J\2\2\u0204"+ + "\u0211\7`\2\2\u0205\u0206\7K\2\2\u0206\u0211\7T\2\2\u0207\u0208\7L\2\2"+ + "\u0208\u0211\5\64\33\2\u0209\u020a\7M\2\2\u020a\u0211\5\64\33\2\u020b"+ + "\u020e\7N\2\2\u020c\u020f\7\17\2\2\u020d\u020f\5\64\33\2\u020e\u020c\3"+ + "\2\2\2\u020e\u020d\3\2\2\2\u020f\u0211\3\2\2\2\u0210\u0201\3\2\2\2\u0210"+ + "\u0203\3\2\2\2\u0210\u0205\3\2\2\2\u0210\u0207\3\2\2\2\u0210\u0209\3\2"+ + "\2\2\u0210\u020b\3\2\2\2\u0211=\3\2\2\2\u0212\u0214\5@!\2\u0213\u0212"+ + "\3\2\2\2\u0214\u0217\3\2\2\2\u0215\u0213\3\2\2\2\u0215\u0216\3\2\2\2\u0216"+ + "?\3\2\2\2\u0217\u0215\3\2\2\2\u0218\u021c\5B\"\2\u0219\u021c\5D#\2\u021a"+ + "\u021c\5F$\2\u021b\u0218\3\2\2\2\u021b\u0219\3\2\2\2\u021b\u021a\3\2\2"+ + "\2\u021cA\3\2\2\2\u021d\u021e\7`\2\2\u021e\u0225\7\34\2\2\u021f\u0221"+ + "\7,\2\2\u0220\u0222\7`\2\2\u0221\u0220\3\2\2\2\u0221\u0222\3\2\2\2\u0222"+ + "\u0223\3\2\2\2\u0223\u0225\7\34\2\2\u0224\u021d\3\2\2\2\u0224\u021f\3"+ + "\2\2\2\u0225C\3\2\2\2\u0226\u0228\7Q\2\2\u0227\u0229\5H%\2\u0228\u0227"+ + "\3\2\2\2\u0228\u0229\3\2\2\2\u0229E\3\2\2\2\u022a\u022b\7O\2\2\u022b\u0230"+ + "\5J&\2\u022c\u022d\7\5\2\2\u022d\u022f\5J&\2\u022e\u022c\3\2\2\2\u022f"+ + "\u0232\3\2\2\2\u0230\u022e\3\2\2\2\u0230\u0231\3\2\2\2\u0231G\3\2\2\2"+ + "\u0232\u0230\3\2\2\2\u0233\u024b\5J&\2\u0234\u0235\7P\2\2\u0235\u024b"+ + "\5J&\2\u0236\u0237\5J&\2\u0237\u0238\7\5\2\2\u0238\u0239\7`\2\2\u0239"+ + "\u024b\3\2\2\2\u023a\u023b\7\7\2\2\u023b\u023c\5J&\2\u023c\u023d\7\b\2"+ + "\2\u023d\u023e\7\5\2\2\u023e\u023f\7`\2\2\u023f\u024b\3\2\2\2\u0240\u0241"+ + "\7\7\2\2\u0241\u0242\5J&\2\u0242\u0243\7\5\2\2\u0243\u0244\7`\2\2\u0244"+ + "\u0245\7\b\2\2\u0245\u024b\3\2\2\2\u0246\u0247\7\7\2\2\u0247\u0248\5J"+ + "&\2\u0248\u0249\7\b\2\2\u0249\u024b\3\2\2\2\u024a\u0233\3\2\2\2\u024a"+ + "\u0234\3\2\2\2\u024a\u0236\3\2\2\2\u024a\u023a\3\2\2\2\u024a\u0240\3\2"+ + "\2\2\u024a\u0246\3\2\2\2\u024bI\3\2\2\2\u024c\u024d\b&\1\2\u024d\u024e"+ + "\7!\2\2\u024e\u024f\5J&\2\u024f\u0250\7\"\2\2\u0250\u025b\3\2\2\2\u0251"+ + "\u0252\t\13\2\2\u0252\u025b\5J&\n\u0253\u025b\7`\2\2\u0254\u025b\7a\2"+ + "\2\u0255\u0256\7\t\2\2\u0256\u0257\7`\2\2\u0257\u025b\7\n\2\2\u0258\u025b"+ + "\7W\2\2\u0259\u025b\7U\2\2\u025a\u024c\3\2\2\2\u025a\u0251\3\2\2\2\u025a"+ + "\u0253\3\2\2\2\u025a\u0254\3\2\2\2\u025a\u0255\3\2\2\2\u025a\u0258\3\2"+ + "\2\2\u025a\u0259\3\2\2\2\u025b\u026a\3\2\2\2\u025c\u025d\f\f\2\2\u025d"+ + "\u025e\7$\2\2\u025e\u0269\5J&\r\u025f\u0260\f\13\2\2\u0260\u0261\t\6\2"+ + "\2\u0261\u0269\5J&\f\u0262\u0263\f\t\2\2\u0263\u0264\t\f\2\2\u0264\u0269"+ + "\5J&\n\u0265\u0266\f\b\2\2\u0266\u0267\t\b\2\2\u0267\u0269\5J&\t\u0268"+ + "\u025c\3\2\2\2\u0268\u025f\3\2\2\2\u0268\u0262\3\2\2\2\u0268\u0265\3\2"+ + "\2\2\u0269\u026c\3\2\2\2\u026a\u0268\3\2\2\2\u026a\u026b\3\2\2\2\u026b"+ + "K\3\2\2\2\u026c\u026a\3\2\2\2=V_jov\u0084\u008a\u0090\u0095\u009e\u00a5"+ + "\u00ba\u00bd\u00c6\u00ce\u00d5\u00e2\u00e7\u00f3\u0101\u010c\u0115\u011c"+ + "\u0123\u0126\u012e\u0131\u0134\u013e\u0142\u0149\u014f\u0151\u0159\u015f"+ + "\u016e\u017a\u0182\u0199\u01a3\u01a7\u01d9\u01e3\u01e5\u01ed\u01f2\u01fc"+ + "\u020e\u0210\u0215\u021b\u0221\u0224\u0228\u0230\u024a\u025a\u0268\u026a"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/src/main/java/dk/camelot64/kickc/parser/KickCVisitor.java b/src/main/java/dk/camelot64/kickc/parser/KickCVisitor.java index 84d1ddcb7..0731b49ae 100644 --- a/src/main/java/dk/camelot64/kickc/parser/KickCVisitor.java +++ b/src/main/java/dk/camelot64/kickc/parser/KickCVisitor.java @@ -1,4 +1,4 @@ -// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickC.g4 by ANTLR 4.7 +// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickC.g4 by ANTLR 4.7 package dk.camelot64.kickc.parser; import org.antlr.v4.runtime.tree.ParseTreeVisitor; @@ -310,6 +310,13 @@ public interface KickCVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitTypeArray(KickCParser.TypeArrayContext ctx); + /** + * Visit a parse tree produced by the {@code typeStructRef} + * labeled alternative in {@link KickCParser#typeDecl}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTypeStructRef(KickCParser.TypeStructRefContext ctx); /** * Visit a parse tree produced by the {@code typeSimple} * labeled alternative in {@link KickCParser#typeDecl}. @@ -317,6 +324,13 @@ public interface KickCVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitTypeSimple(KickCParser.TypeSimpleContext ctx); + /** + * Visit a parse tree produced by the {@code typeStructDef} + * labeled alternative in {@link KickCParser#typeDecl}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTypeStructDef(KickCParser.TypeStructDefContext ctx); /** * Visit a parse tree produced by the {@code typeSignedSimple} * labeled alternative in {@link KickCParser#typeDecl}. @@ -324,6 +338,24 @@ public interface KickCVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx); + /** + * Visit a parse tree produced by {@link KickCParser#structRef}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructRef(KickCParser.StructRefContext ctx); + /** + * Visit a parse tree produced by {@link KickCParser#structDef}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructDef(KickCParser.StructDefContext ctx); + /** + * Visit a parse tree produced by {@link KickCParser#structMembers}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitStructMembers(KickCParser.StructMembersContext ctx); /** * Visit a parse tree produced by the {@code commaNone} * labeled alternative in {@link KickCParser#commaExpr}. @@ -394,6 +426,20 @@ public interface KickCVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitExprChar(KickCParser.ExprCharContext ctx); + /** + * Visit a parse tree produced by the {@code exprArrow} + * labeled alternative in {@link KickCParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprArrow(KickCParser.ExprArrowContext ctx); + /** + * Visit a parse tree produced by the {@code exprDot} + * labeled alternative in {@link KickCParser#expr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitExprDot(KickCParser.ExprDotContext ctx); /** * Visit a parse tree produced by the {@code initList} * labeled alternative in {@link KickCParser#expr}. diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 6889b48b4..f25f31473 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -431,6 +431,8 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { private List declVarDirectives = null; /** Holds the declared comments when descending into a Variable Declaration. */ private List declVarComments = null; + /** State specifying that we are currently populating struct members. */ + private boolean declVarStructMember = false; /** * Visit the type/directive part of a declaration. Setup the local decl-variables @@ -495,13 +497,21 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { // Add comments to constant lValue.setComments(ensureUnusedComments(comments)); } + if(type instanceof SymbolTypeStruct) { + lValue.setDeclaredVolatile(true); + } KickCParser.ExprContext initializer = ctx.expr(); + if(declVarStructMember) { + if(initializer != null) { + throw new CompileError("Initializers not supported inside structs " + type.getTypeName(), new StatementSource(ctx)); + } + } else { if(initializer != null) { addInitialAssignment(initializer, lValue, comments); } else { - if(type instanceof SymbolTypeInteger) { + if(type instanceof SymbolTypeIntegerFixed) { // Add an zero value initializer - ConstantInteger zero = new ConstantInteger(0L); + ConstantInteger zero = new ConstantInteger(0L, type); Statement stmt = new StatementAssignment(lValue.getRef(), zero, new StatementSource(ctx), ensureUnusedComments(comments)); sequence.addStatement(stmt); } else if(type instanceof SymbolTypeArray) { @@ -519,9 +529,15 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { ConstantValue zero = new ConstantPointer(0L, typePointer.getElementType()); Statement stmt = new StatementAssignment(lValue.getRef(), zero, new StatementSource(ctx), ensureUnusedComments(comments)); sequence.addStatement(stmt); + } else if(type instanceof SymbolTypeStruct) { + // Add an zero-struct initializer + SymbolTypeStruct typeStruct = (SymbolTypeStruct) type; + Statement stmt = new StatementAssignment(lValue.getRef(), new StructZero(typeStruct), new StatementSource(ctx), ensureUnusedComments(comments)); + sequence.addStatement(stmt); } else { throw new CompileError("Default initializer not implemented for type " + type.getTypeName(), new StatementSource(ctx)); } + } } return null; @@ -907,6 +923,10 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { // Assign loop variable with first value RValue rangeLastValue = (RValue) visit(rangeLastCtx); RValue rangeFirstValue = (RValue) visit(rangeFirstCtx); + if(varType!=null) { + if(rangeFirstValue instanceof ConstantInteger) ((ConstantInteger) rangeFirstValue).setType(SymbolType.NUMBER); + if(rangeLastValue instanceof ConstantInteger) ((ConstantInteger) rangeLastValue).setType(SymbolType.NUMBER); + } Statement stmtInit = new StatementAssignment(lValue.getRef(), rangeFirstValue, new StatementSource(ctx), Comment.NO_COMMENTS); sequence.addStatement(stmtInit); // Add label @@ -1115,6 +1135,35 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { return SymbolType.get(ctx.getText()); } + + + + @Override + public Object visitStructDef(KickCParser.StructDefContext ctx) { + String structDefName; + if(ctx.NAME()!=null) { + structDefName = ctx.NAME().getText(); + } else { + structDefName = getCurrentScope().allocateIntermediateVariableName(); + } + StructDefinition structDefinition = getCurrentScope().addStructDefinition(structDefName); + scopeStack.push(structDefinition); + declVarStructMember = true; + for(KickCParser.StructMembersContext memberCtx : ctx.structMembers()) { + visit(memberCtx); + } + declVarStructMember = false; + scopeStack.pop(); + return structDefinition.getType(); + } + + @Override + public Object visitStructRef(KickCParser.StructRefContext ctx) { + String structDefName = ctx.NAME().getText(); + StructDefinition structDefinition = getCurrentScope().getStructDefinition(structDefName); + return structDefinition.getType(); + } + @Override public SymbolType visitTypeSignedSimple(KickCParser.TypeSignedSimpleContext ctx) { String signedness = ctx.getChild(0).getText(); @@ -1210,6 +1259,13 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { } } + @Override + public Object visitExprDot(KickCParser.ExprDotContext ctx) { + RValue structExpr = (RValue) visit(ctx.expr()); + String name = ctx.NAME().getText(); + return new StructMemberRef(structExpr, name); + } + @Override public RValue visitExprCast(KickCParser.ExprCastContext ctx) { RValue child = (RValue) this.visit(ctx.expr()); @@ -1298,22 +1354,23 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { @Override public RValue visitExprNumber(KickCParser.ExprNumberContext ctx) { - Number number = NumberParser.parseLiteral(ctx.getText()); - if(number instanceof Long) { - return new ConstantInteger((Long) number); - } else { - return new ConstantDouble((Double) number); - } + return NumberParser.parseIntegerLiteral(ctx.getText()); } @Override public RValue visitExprString(KickCParser.ExprStringContext ctx) { - String text = ctx.getText(); - String stringValue; - if(text.endsWith("z")) { - stringValue = text.substring(1, text.length() - 2); - } else { - stringValue = text.substring(1, text.length() - 1)+"@"; + String stringValue =""; + String subText = ""; + for(TerminalNode stringNode : ctx.STRING()) { + subText = stringNode.getText(); + if(subText.endsWith("z")) { + stringValue += subText.substring(1, subText.length() - 2); + } else { + stringValue += subText.substring(1, subText.length() - 1); + } + } + if(!subText.endsWith("z")) { + stringValue += "@"; } return new ConstantString(stringValue); } @@ -1353,11 +1410,16 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor { RValue child = (RValue) this.visit(ctx.expr()); String op = ((TerminalNode) ctx.getChild(0)).getSymbol().getText(); Operator operator = Operators.getUnary(op); - VariableIntermediate tmpVar = getCurrentScope().addVariableIntermediate(); - VariableRef tmpVarRef = tmpVar.getRef(); - Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx))); - sequence.addStatement(stmt); - return tmpVarRef; + // Special handling of negative literal number + if(child instanceof ConstantInteger && operator.equals(Operators.NEG)) { + return new ConstantInteger(-((ConstantInteger) child).getInteger(), ((ConstantInteger) child).getType()); + } else { + VariableIntermediate tmpVar = getCurrentScope().addVariableIntermediate(); + VariableRef tmpVarRef = tmpVar.getRef(); + Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx))); + sequence.addStatement(stmt); + return tmpVarRef; + } } @Override diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1AddTypePromotions.java b/src/main/java/dk/camelot64/kickc/passes/Pass1AddTypePromotions.java deleted file mode 100644 index afe0863aa..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1AddTypePromotions.java +++ /dev/null @@ -1,102 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.statements.StatementSource; -import dk.camelot64.kickc.model.values.LValue; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypePointer; - -import java.util.List; -import java.util.ListIterator; - -/** - * Add casts in all assignments where types are not equal, but the rValue type can be promoted to the lValue type. - */ -public class Pass1AddTypePromotions extends Pass1Base { - - public Pass1AddTypePromotions(Program program) { - super(program); - } - - @Override - public boolean step() { - for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { - List statements = block.getStatements(); - ListIterator stmtIt = statements.listIterator(); - while(stmtIt.hasNext()) { - Statement statement = stmtIt.next(); - if(statement instanceof StatementAssignment) { - getPromotionAssignment((StatementAssignment) statement, stmtIt); - } - // TODO: Implement promotion for calls - } - } - return false; - } - - /** - * Examines an assignment to determine if a cast of the rValue is needed (the lvalue type and the rvalue type is not equal) - * and possible (the types are promotion compatible). - *

- * If a promotion is needed it is added by adding a new tmp-var with a cast and modifying the statement. - * - * @param assignment The assignment to examine - * @param stmtIt Iterator allowing the method to add a tmp-var-assignment. - */ - private void getPromotionAssignment(StatementAssignment assignment, ListIterator stmtIt) { - LValue lValue = assignment.getlValue(); - SymbolType lValueType = SymbolTypeInference.inferType(getScope(), lValue); - SymbolType rValueType = SymbolTypeInference.inferTypeRValue(getScope(), assignment); - if(SymbolTypeInference.typeMatch(lValueType, rValueType)) { - return; - } - // No direct type match - attempt promotion - if(canPromote(lValueType, rValueType)) { - // Promotion possible - add tmp-var and a cast - if(assignment.getOperator() == null) { - // No operator - add cast directly! - assignment.setOperator(Operators.getCastUnary(lValueType)); - if(getLog().isVerbosePass1CreateSsa()) { - getLog().append("Promoting " + rValueType + " to " + lValueType + " in " + assignment); - } - } else { - throw new RuntimeException("Tmp-var promotions not implemented yet " + assignment); - } - } else { - String msg = "ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). " + - "In " + assignment.toString(getProgram(), false); - getProgram().getLog().append(msg); - throw new CompileError(msg, assignment.getSource()); - } - } - - /** - * Determines if it is possible to promote (cast without loss) one type to another - * - * @param lValueType The type of the lValue - * @param rValueType The type of the rValue (that will be cast) - * @return True if a cast is possible without any loss - */ - private boolean canPromote(SymbolType lValueType, SymbolType rValueType) { - if(lValueType instanceof SymbolTypePointer && SymbolType.isWord(rValueType)) { - return true; - } - if(lValueType.equals(SymbolType.WORD) && SymbolType.isByte(rValueType)) { - return true; - } - if(lValueType.equals(SymbolType.DWORD) && SymbolType.isWord(rValueType)) { - return true; - } - if(lValueType.equals(SymbolType.DWORD) && SymbolType.isByte(rValueType)) { - return true; - } - // No type promotion found - return false; - } - - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java index faceeca37..8c8339dd9 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1EarlyConstantIdentification.java @@ -6,12 +6,15 @@ import dk.camelot64.kickc.model.operators.OperatorCastPtr; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementLValue; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.values.ConstantValue; import dk.camelot64.kickc.model.values.VariableRef; import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** Identify any variable that are clearly constant. */ public class Pass1EarlyConstantIdentification extends Pass1Base { @@ -26,18 +29,20 @@ public class Pass1EarlyConstantIdentification extends Pass1Base { for(Variable variable : getProgram().getScope().getAllVariables(true)) { VariableRef variableRef = variable.getRef(); if(!variable.isDeclaredConstant() && !variable.isDeclaredVolatile() && !variableRef.isIntermediate()) { - Collection assignments = getAssignments(variable); - if(assignments.size() == 1) { - if(!Pass2ConstantIdentification.isAddressOfUsed(variableRef, getProgram())) { - StatementLValue assignment = assignments.iterator().next(); - if(assignment instanceof StatementAssignment) { - StatementAssignment assign = (StatementAssignment) assignment; - if(assign.getrValue1() == null && assign.getOperator() == null && assign.getrValue2() instanceof ConstantValue) { - getLog().append("Identified constant variable " + variable.toString(getProgram())); - earlyConstants.add(variableRef); - } else if(assign.getrValue1() == null && assign.getOperator() instanceof OperatorCastPtr && assign.getrValue2() instanceof ConstantValue) { - getLog().append("Identified constant variable " + variable.toString(getProgram())); - earlyConstants.add(variableRef); + if(!isParameter(variableRef)) { + Collection assignments = getAssignments(variable); + if(assignments.size() == 1) { + if(!Pass2ConstantIdentification.isAddressOfUsed(variableRef, getProgram())) { + StatementLValue assignment = assignments.iterator().next(); + if(assignment instanceof StatementAssignment) { + StatementAssignment assign = (StatementAssignment) assignment; + if(assign.getrValue1() == null && assign.getOperator() == null && assign.getrValue2() instanceof ConstantValue) { + getLog().append("Identified constant variable " + variable.toString(getProgram())); + earlyConstants.add(variableRef); + } else if(assign.getrValue1() == null && assign.getOperator() instanceof OperatorCastPtr && assign.getrValue2() instanceof ConstantValue) { + getLog().append("Identified constant variable " + variable.toString(getProgram())); + earlyConstants.add(variableRef); + } } } } @@ -48,6 +53,23 @@ public class Pass1EarlyConstantIdentification extends Pass1Base { return false; } + /** + * Examines whether a variale is a procedure parameter + * @param variableRef The variable + * @return true if the variable is a procedure parameter + */ + public boolean isParameter(VariableRef variableRef) { + Variable var = getScope().getVariable(variableRef); + Scope varScope = var.getScope(); + if(varScope instanceof Procedure) { + List parameters = ((Procedure) varScope).getParameters(); + if(parameters.contains(var)) + return true; + + } + return false; + } + /** * Find all assignments of a variable. * diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1EliminateEmptyBlocks.java b/src/main/java/dk/camelot64/kickc/passes/Pass1EliminateEmptyBlocks.java deleted file mode 100644 index 9cfc9095d..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1EliminateEmptyBlocks.java +++ /dev/null @@ -1,66 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.CompileLog; -import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.symbols.Label; -import dk.camelot64.kickc.model.symbols.Symbol; -import dk.camelot64.kickc.model.values.LabelRef; -import dk.camelot64.kickc.model.values.SymbolRef; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Eliminate empty blocks in pass 1 (before creating SSA) - */ -public class Pass1EliminateEmptyBlocks extends Pass1Base { - - public Pass1EliminateEmptyBlocks(Program program) { - super(program); - } - - @Override - public boolean step() { - CompileLog log = getLog(); - ControlFlowGraph graph = getProgram().getGraph(); - Collection blocks = graph.getAllBlocks(); - List removeList = new ArrayList<>(); - for(ControlFlowBlock block : blocks) { - if(block.getLabel().getFullName().equals(SymbolRef.END_BLOCK_NAME)) { - continue; - } else if(block.getLabel().getFullName().equals(SymbolRef.BEGIN_BLOCK_NAME)) { - continue; - } - if(block.getStatements().isEmpty()) { - List predecessors = graph.getPredecessors(block); - boolean remove = true; - for(ControlFlowBlock predecessor : predecessors) { - if(predecessor.getDefaultSuccessor().equals(block.getLabel())) { - predecessor.setDefaultSuccessor(block.getDefaultSuccessor()); - } else { - remove = false; - } - } - if(remove) { - removeList.add(block.getLabel()); - } - } - } - boolean modified = false; - for(LabelRef labelRef : removeList) { - Symbol removeSymbol = getScope().getSymbol(labelRef); - if(removeSymbol instanceof Label) { - Label label = (Label) removeSymbol; - graph.remove(labelRef); - label.getScope().remove(label); - if(log.isVerbosePass1CreateSsa()) { - log.append("Removing empty block " + labelRef); - } - modified = true; - } - } - return modified; - } - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1FixLValuesLoHi.java b/src/main/java/dk/camelot64/kickc/passes/Pass1FixLValuesLoHi.java index 1b2f990e8..1e65038e9 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1FixLValuesLoHi.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1FixLValuesLoHi.java @@ -12,7 +12,6 @@ import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.VariableIntermediate; -import dk.camelot64.kickc.model.types.SymbolTypeInference; import java.util.ArrayList; import java.util.List; @@ -80,7 +79,7 @@ public class Pass1FixLValuesLoHi extends Pass1Base { VariableIntermediate tmpVar = currentScope.addVariableIntermediate(); VariableRef tmpVarRef = tmpVar.getRef(); statementLValue.setlValue(tmpVarRef); - SymbolTypeInference.inferLValue(getProgram(), statementLValue, false); + PassNTypeInference.updateInferedTypeLValue(getProgram(), statementLValue); // Insert an extra "set low" assignment statement Statement setLoHiAssignment = new StatementAssignment(loHiVar, loHiVar, loHiOperator, tmpVarRef, statementLValue.getSource(), new ArrayList<>()); statementsIt.add(setLoHiAssignment); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java index db834cb48..b1f4777da 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java @@ -96,7 +96,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base { programValue.set(version.getRef()); } // Update map of versions encountered in the block - if(currentStmt instanceof StatementAssignment && programValue instanceof ProgramValue.LValue) { + if(currentStmt instanceof StatementAssignment && programValue instanceof ProgramValue.ProgramValueLValue) { StatementAssignment assignment = (StatementAssignment) currentStmt; LValue lValue = assignment.getlValue(); if(lValue instanceof VariableRef) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1PointerSizeofFix.java b/src/main/java/dk/camelot64/kickc/passes/Pass1PointerSizeofFix.java index 9a840e3b4..c4caba00d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1PointerSizeofFix.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1PointerSizeofFix.java @@ -64,7 +64,7 @@ public class Pass1PointerSizeofFix extends Pass1Base { VariableRef idx2VarRef = handled.getOrDefault(currentStmt, new LinkedHashMap<>()).get(deref.getIndex()); if(idx2VarRef==null) { VariableIntermediate idx2Var = getScope().getScope(currentBlock.getScope()).addVariableIntermediate(); - idx2Var.setType(SymbolTypeInference.inferType(getScope(), deref.getIndex())); + idx2Var.setTypeInferred(SymbolTypeInference.inferType(getScope(), deref.getIndex())); ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType()); StatementAssignment idx2 = new StatementAssignment(idx2Var.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, currentStmt.getSource(), Comment.NO_COMMENTS); stmtIt.previous(); @@ -100,7 +100,7 @@ public class Pass1PointerSizeofFix extends Pass1Base { // Adding to a pointer - multiply by sizeof() getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false)); VariableIntermediate tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate(); - tmpVar.setType(SymbolTypeInference.inferType(getScope(), assignment.getrValue2())); + tmpVar.setTypeInferred(SymbolTypeInference.inferType(getScope(), assignment.getrValue2())); stmtIt.remove(); ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType()); stmtIt.add(new StatementAssignment(tmpVar.getRef(), assignment.getrValue2(), Operators.MULTIPLY, sizeOfTargetType, assignment.getSource(), Comment.NO_COMMENTS)); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1Procedures.java b/src/main/java/dk/camelot64/kickc/passes/Pass1Procedures.java new file mode 100644 index 000000000..8ba6364d2 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1Procedures.java @@ -0,0 +1,43 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementCall; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.symbols.Scope; + +/** + * Updates procedure calls to point to the actual procedure called. + */ +public class Pass1Procedures extends Pass2SsaOptimization { + + public Pass1Procedures(Program program) { + super(program); + } + + @Override + public boolean step() { + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementCall) { + StatementCall call = (StatementCall) statement; + String procedureName = call.getProcedureName(); + Scope currentScope = getScope().getScope(block.getScope()); + Procedure procedure = currentScope.getProcedure(procedureName); + if(procedure == null) { + throw new CompileError("Called procedure not found. " + call.toString(getProgram(), false), statement.getSource()); + } + call.setProcedure(procedure.getRef()); + if(procedure.getParameters().size() != call.getParameters().size()) { + throw new CompileError("Wrong number of parameters in call. Expected " + procedure.getParameters().size() + ". " + statement.toString(), statement.getSource()); + } + } + + } + } + return false; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1TypeIdSimplification.java b/src/main/java/dk/camelot64/kickc/passes/Pass1TypeIdSimplification.java deleted file mode 100644 index 736cb21ca..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1TypeIdSimplification.java +++ /dev/null @@ -1,44 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.operators.OperatorTypeId; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.values.ConstantRef; -import dk.camelot64.kickc.model.values.RValue; - -/** - * Converts typeid() operators to constants - */ -public class Pass1TypeIdSimplification extends Pass1Base { - - public Pass1TypeIdSimplification(Program program) { - super(program); - } - - @Override - public boolean step() { - boolean modified = false; - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - for(Statement statement : block.getStatements()) { - if(statement instanceof StatementAssignment) { - StatementAssignment assignment = (StatementAssignment) statement; - if(Operators.TYPEID.equals(assignment.getOperator())) { - RValue rValue = assignment.getrValue2(); - SymbolType symbolType = SymbolTypeInference.inferType(getScope(), rValue); - getLog().append("Resolving typeid() " + assignment.toString(getProgram(), false)); - ConstantRef typeIDConstantVar = OperatorTypeId.getTypeIdConstantVar(getScope(), symbolType); - assignment.setrValue2(typeIDConstantVar); - assignment.setOperator(null); - modified = true; - } - } - } - } - return modified; - } -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java b/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java deleted file mode 100644 index 0f296642d..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1TypeInference.java +++ /dev/null @@ -1,62 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.CompileError; -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.statements.*; -import dk.camelot64.kickc.model.symbols.Procedure; -import dk.camelot64.kickc.model.symbols.Scope; -import dk.camelot64.kickc.model.types.SymbolTypeInference; - -/** - * Pass through the generated statements inferring types of unresolved variables. - * Also updates procedure calls to point to the actual procedure called. - */ -public class Pass1TypeInference extends Pass1Base { - - public Pass1TypeInference(Program program) { - super(program); - } - - @Override - public boolean step() { - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - for(Statement statement : block.getStatements()) { - if(statement instanceof StatementAssignment) { - StatementAssignment assignment = (StatementAssignment) statement; - try { - SymbolTypeInference.inferAssignmentLValue(getProgram(), assignment, false); - } catch(CompileError e) { - throw new CompileError(e.getMessage(), statement.getSource()); - } - } else if(statement instanceof StatementPhiBlock) { - for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) { - try { - SymbolTypeInference.inferPhiVariable(getProgram(), phiVariable, false); - } catch(CompileError e) { - throw new CompileError(e.getMessage(), statement.getSource()); - } - } - } else if(statement instanceof StatementCall) { - StatementCall call = (StatementCall) statement; - String procedureName = call.getProcedureName(); - Scope currentScope = getScope().getScope(block.getScope()); - Procedure procedure = currentScope.getProcedure(procedureName); - if(procedure == null) { - throw new CompileError("Called procedure not found. " + call.toString(getProgram(), false), statement.getSource()); - } - call.setProcedure(procedure.getRef()); - if(procedure.getParameters().size() != call.getParameters().size()) { - throw new CompileError("Wrong number of parameters in call. Expected " + procedure.getParameters().size() + ". " + statement.toString(), statement.getSource()); - } - SymbolTypeInference.inferCallLValue(getProgram(), (StatementCall) statement, false); - } else if(statement instanceof StatementCallPointer) { - SymbolTypeInference.inferCallPointerLValue(getProgram(), (StatementCallPointer) statement, false); - } - - } - } - return false; - } - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertSymbols.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertSymbols.java index 9977d5211..55f1a9cd0 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertSymbols.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertSymbols.java @@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.symbols.ConstantVar; +import dk.camelot64.kickc.model.symbols.StructDefinition; import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.VariableUnversioned; import dk.camelot64.kickc.model.values.SymbolRef; @@ -42,6 +43,7 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion { for(Symbol tableSymbol : tableSymbols) { if(tableSymbol instanceof VariableUnversioned) continue; if(tableSymbol instanceof ConstantVar) continue; + if(tableSymbol instanceof StructDefinition) continue; Symbol codeSymbol = null; String codeSymbolFullName = tableSymbol.getFullName(); for(Symbol symbol : codeSymbols) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertTypeMatch.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertTypeMatch.java index ea2611f26..2a1e626af 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertTypeMatch.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertTypeMatch.java @@ -1,12 +1,16 @@ package dk.camelot64.kickc.passes; -import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.statements.StatementConditionalJump; -import dk.camelot64.kickc.model.values.LValue; +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.statements.StatementConditionalJump; import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.AssignmentRValue; +import dk.camelot64.kickc.model.values.LValue; import dk.camelot64.kickc.model.values.RValue; /** @@ -30,7 +34,7 @@ public class Pass2AssertTypeMatch extends Pass2SsaAssertion { if(conditionalJump.getOperator()==null) { RValue rValue = conditionalJump.getrValue2(); SymbolType rValueType = SymbolTypeInference.inferType(getScope(), rValue); - if(!SymbolTypeInference.typeMatch(SymbolType.BOOLEAN, rValueType)) { + if(!SymbolType.BOOLEAN.equals(rValueType)) { getLog().append("ERROR! Type mismatch non-boolean condition from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false)); throw new CompileError("ERROR! Type mismatch non-boolean condition from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false), statement.getSource()); } @@ -47,13 +51,8 @@ public class Pass2AssertTypeMatch extends Pass2SsaAssertion { private void checkAssignment(StatementAssignment statement) { LValue lValue = statement.getlValue(); SymbolType lValueType = SymbolTypeInference.inferType(getScope(), lValue); - SymbolType rValueType = SymbolTypeInference.inferTypeRValue(getScope(), statement); - if(SymbolTypeInference.typeMatch(lValueType, rValueType)) { - return; - } - if(SymbolTypeInference.typeMatch(rValueType, lValueType)) { - return; - } + SymbolType rValueType = SymbolTypeInference.inferType(getScope(), new AssignmentRValue(statement)); + if(SymbolTypeConversion.assignmentTypeMatch(lValueType, rValueType)) return; // Types do not match getLog().append("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false)); throw new CompileError("ERROR! Type mismatch (" + lValueType.getTypeName() + ") cannot be assigned from (" + rValueType.getTypeName() + "). In " + statement.toString(getProgram(), false), statement.getSource()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java index 3c9658e9c..0354d3104 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ComparisonOptimization.java @@ -9,7 +9,7 @@ import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementConditionalJump; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; +import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed; import dk.camelot64.kickc.model.values.ConstantBinary; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantLiteral; @@ -48,7 +48,7 @@ public class Pass2ComparisonOptimization extends Pass2SsaOptimization { } catch(ConstantNotLiteral e) { // Ignore } - if(Operators.GT.equals(operator) && valueType instanceof SymbolTypeInteger && constantLiteral instanceof ConstantInteger) { + if(Operators.GT.equals(operator) && valueType instanceof SymbolTypeIntegerFixed && constantLiteral instanceof ConstantInteger) { // Found > C - rewrite to >= C+1 if possible Long longValue = (Long) constantLiteral.getValue(); if(longValue > 0x00L && longValue < 0xffL) { @@ -58,7 +58,7 @@ public class Pass2ComparisonOptimization extends Pass2SsaOptimization { conditionalJump.setrValue2(new ConstantBinary(constantValue, Operators.PLUS, new ConstantInteger(1L))); } } - if(Operators.LE.equals(operator) && valueType instanceof SymbolTypeInteger && constantLiteral instanceof ConstantInteger) { + if(Operators.LE.equals(operator) && valueType instanceof SymbolTypeIntegerFixed && constantLiteral instanceof ConstantInteger) { // Found <= C - rewrite to < C+1 if possible Long longValue = (Long) constantLiteral.getValue(); if(longValue > 0x00L && longValue < 0xffL) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConditionalJumpSequenceImprovement.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConditionalJumpSequenceImprovement.java new file mode 100644 index 000000000..0bbd1fd33 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConditionalJumpSequenceImprovement.java @@ -0,0 +1,79 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.operators.Operator; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementConditionalJump; +import dk.camelot64.kickc.model.values.LabelRef; + +// If a conditional (on block A) jumps to a block (B) that has the same default successor (C) as the current block (A) then +// negate the conditional to ensure sequence A->B->C, which generates optimal ASM. +public class Pass2ConditionalJumpSequenceImprovement extends Pass2SsaOptimization { + + public Pass2ConditionalJumpSequenceImprovement(Program program) { + super(program); + } + + @Override + public boolean step() { + boolean modified = false; + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + ControlFlowBlock conditionalSuccessor = getGraph().getConditionalSuccessor(block); + ControlFlowBlock defaultSuccessor = getGraph().getDefaultSuccessor(block); + if(conditionalSuccessor != null && defaultSuccessor != null) { + if(conditionalSuccessor.getDefaultSuccessor().equals(defaultSuccessor.getLabel())) { + if(conditionalSuccessor.equals(block)) continue; + // conditional successor is current blocks default successor + // Negate condition and swap conditional/default successor. + modified = negateCondition(block); + } + + } + } + return modified; + } + + private boolean negateCondition(ControlFlowBlock block) { + LabelRef defaultSuccessor = block.getDefaultSuccessor(); + LabelRef conditionalSuccessor = block.getConditionalSuccessor(); + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementConditionalJump) { + StatementConditionalJump conditionalJump = (StatementConditionalJump) statement; + if(negateOperator(conditionalJump.getOperator()) != null) { + Operator negatedOperator = negateOperator(conditionalJump.getOperator()); + conditionalJump.setOperator(negatedOperator); + conditionalJump.setDestination(defaultSuccessor); + block.setConditionalSuccessor(defaultSuccessor); + block.setDefaultSuccessor(conditionalSuccessor); + getLog().append("Negating conditional jump and destination " + conditionalJump.toString(getProgram(), false)); + return true; + } + } + } + return false; + } + + /** + * Find the logic operator that returns the opposite result + * + * @param operator The operator to negate + * @return The opposite logic operator. Null if not found. + */ + private Operator negateOperator(Operator operator) { + if(Operators.EQ.equals(operator)) + return Operators.NEQ; + if(Operators.NEQ.equals(operator)) + return Operators.EQ; + if(Operators.LT.equals(operator)) + return Operators.GE; + if(Operators.LE.equals(operator)) + return Operators.GT; + if(Operators.GT.equals(operator)) + return Operators.LE; + if(Operators.GE.equals(operator)) + return Operators.LT; + return null; + } +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java index 0c5f23010..15dc207c3 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java @@ -93,6 +93,13 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { return true; } } + if(pointerDereferenceIndexed.getIndex() instanceof ConstantInteger ) { + if(((ConstantInteger)pointerDereferenceIndexed.getIndex()).getValue()==0L) { + value.set(new PointerDereferenceSimple(pointerDereferenceIndexed.getPointer())); + getLog().append("Simplified zero-index dereference" + value.get().toString()); + return true; + } + } return false; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java index 7ae4366dd..58cbc1719 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantIdentification.java @@ -4,7 +4,9 @@ import dk.camelot64.kickc.model.CompileError; import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.iterator.ProgramValueIterator; -import dk.camelot64.kickc.model.operators.*; +import dk.camelot64.kickc.model.operators.OperatorBinary; +import dk.camelot64.kickc.model.operators.OperatorUnary; +import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementPhiBlock; @@ -13,11 +15,14 @@ import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeArray; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.values.*; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; /** * Compiler Pass propagating constants in expressions eliminating constant variables @@ -50,7 +55,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { // If the assignment has an operator then replace it with the single constant value if(constVarVal.getAssignment() instanceof StatementAssignment) { StatementAssignment assignment = (StatementAssignment) constVarVal.getAssignment(); - if(assignment.getOperator()!=null) { + if(assignment.getOperator() != null) { getLog().append("Constant right-side identified " + assignment.toString(getProgram(), false)); assignment.setOperator(null); assignment.setrValue1(null); @@ -67,27 +72,27 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { ConstantValue constVal = constVarVal.getConstantValue(); SymbolType valueType = SymbolTypeInference.inferType(getScope(), constVal); SymbolType variableType = variable.getType(); - SymbolType constType = variableType; - if(!valueType.equals(variableType)) { - if(SymbolTypeInference.typeMatch(variableType, valueType)) { - constType = variableType; - } else if(SymbolTypeInference.typeMatch(valueType, variableType)) { - constType = valueType; - } else { + if(!SymbolType.NUMBER.equals(variableType) && SymbolType.NUMBER.equals(valueType)) { + // Value is number - wait til it is cast to a proper type + constants.remove(constRef); + continue; + } + + if(!SymbolTypeConversion.assignmentTypeMatch(variableType, valueType)) { throw new CompileError( "Constant variable has a non-matching type \n variable: " + variable.toString(getProgram()) + "\n value: (" + valueType.toString() + ") " + constVal.calculateLiteral(getScope()) + "\n value definition: " + constVal.toString(getProgram()) ); - } } ConstantVar constantVar = new ConstantVar( variable.getName(), constScope, - constType, + variableType, constVal); + constantVar.setInferredType(variable.isInferredType()); constantVar.setDeclaredAlignment(variable.getDeclaredAlignment()); constantVar.setDeclaredRegister(variable.getDeclaredRegister()); if(variable.getComments().size() > 0) { @@ -192,85 +197,12 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { // Volatile variables cannot be constant return; } - ConstantValue constant = getConstantAssignmentValue(assignment, var.getType()); - if(constant != null) { - constants.put(variable, new ConstantVariableValue(variable, constant, assignment)); + if(assignment.getrValue1()==null && assignment.getOperator()==null && assignment.getrValue2() instanceof ConstantValue) { + constants.put(variable, new ConstantVariableValue(variable, (ConstantValue) assignment.getrValue2(), assignment)); } } } - /** - * Examine the right side of an assignment and if it is constant then return the constant value. - * @param assignment The assignment to examine - * @param lValueType The type of the lvalue - * @return The constant value if the right side is constant - */ - private ConstantValue getConstantAssignmentValue(StatementAssignment assignment, SymbolType lValueType) { - if(assignment.getrValue1() == null && getConstant(assignment.getrValue2()) != null) { - if(assignment.getOperator() == null) { - // Constant assignment - return getConstant(assignment.getrValue2()); - } else { - // Constant unary expression - return createUnary( - (OperatorUnary) assignment.getOperator(), - getConstant(assignment.getrValue2()) - ); - } - } else if(getConstant(assignment.getrValue1()) != null && getConstant(assignment.getrValue2()) != null) { - // Constant binary expression - return createBinary( - getConstant(assignment.getrValue1()), - (OperatorBinary) assignment.getOperator(), - getConstant(assignment.getrValue2()), - getScope()); - } else if(assignment.getrValue2() instanceof ValueList && assignment.getOperator() == null && assignment.getrValue1() == null) { - // A candidate for a constant list - examine to confirm - if(lValueType instanceof SymbolTypeArray) { - ValueList valueList = (ValueList) assignment.getrValue2(); - List values = valueList.getList(); - boolean allConstant = true; - // Type of the elements of the list (deducted from the type of all elements) - SymbolType listType = null; - List elements = new ArrayList<>(); - for(RValue elmValue : values) { - if(elmValue instanceof ConstantValue) { - ConstantValue constantValue = (ConstantValue) elmValue; - SymbolType elmType = constantValue.getType(getScope()); - if(listType == null) { - listType = elmType; - } else { - if(!SymbolTypeInference.typeMatch(listType, elmType)) { - SymbolType intersectType = SymbolTypeInference.intersectTypes(listType, elmType); - if(intersectType == null) { - // No overlap between list type and element type - throw new RuntimeException("Array type " + listType + " does not match element type" + elmType + ". Array: " + valueList.toString(getProgram())); - } else { - listType = intersectType; - } - } - } - elements.add(constantValue); - } else { - allConstant = false; - listType = null; - break; - } - } - if(allConstant && listType != null) { - // Constant list confirmed! - return new ConstantArrayList(elements, listType); - } - } - } else if(Operators.ADDRESS_OF.equals(assignment.getOperator()) && assignment.getrValue1() == null) { - // Constant address-of variable - if(assignment.getrValue2() instanceof SymbolRef) { - return new ConstantSymbolPointer((SymbolRef) assignment.getrValue2()); - } - } - return null; - } - /** * If the rValue is a known constant return the constant value. * @@ -307,18 +239,24 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization { } static ConstantValue createBinary(ConstantValue c1, OperatorBinary operator, ConstantValue c2, ProgramScope programScope) { + + // Special handling of string append using + + if(Operators.PLUS.equals(operator) && SymbolType.STRING.equals(c1.getType(programScope))) { + if(c1 instanceof ConstantRef) { + c1 = programScope.getConstant((ConstantRef) c1).getValue(); + } + if(c2 instanceof ConstantRef) { + c2 = programScope.getConstant((ConstantRef) c2).getValue(); + } + return new ConstantBinary(c1, operator, c2); + } + + if(Operators.PLUS.equals(operator)) { + return new ConstantBinary(c1, operator, c2); + } + switch(operator.getOperator()) { case "-": - case "+": - if(SymbolType.STRING.equals(c1.getType(programScope))) { - if(c1 instanceof ConstantRef) { - c1 = programScope.getConstant((ConstantRef) c1).getValue(); - } - if(c2 instanceof ConstantRef) { - c2 = programScope.getConstant((ConstantRef) c2).getValue(); - } - return new ConstantBinary(c1, operator, c2); - } case "*": case "/": case "%": diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java index 4686b3df3..801a63bb4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java @@ -33,8 +33,9 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization { @Override public boolean step() { Map inline = new HashMap<>(); + Map aliasConstants = findAliasConstants(); + inline.putAll(aliasConstants); inline.putAll(findUnnamedConstants()); - inline.putAll(findAliasConstants()); inline.putAll(findConstVarVersions()); // Remove all string constants diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantRValueConsolidation.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantRValueConsolidation.java new file mode 100644 index 000000000..edf2a49c3 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantRValueConsolidation.java @@ -0,0 +1,125 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.operators.OperatorBinary; +import dk.camelot64.kickc.model.operators.OperatorUnary; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeArray; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * Compiler Pass consolidating R-values that are constant into a single {@link ConstantValue} + */ +public class Pass2ConstantRValueConsolidation extends Pass2SsaOptimization { + + public Pass2ConstantRValueConsolidation(Program program) { + super(program); + } + + /** + * Propagate constants, replacing variables with constants where possible. + * + * @return true optimization was performed. false if no optimization was possible. + */ + @Override + public boolean step() { + boolean modified = false; + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) statement; + if(assignment.getrValue1() != null || assignment.getOperator() != null || !(assignment.getrValue2() instanceof ConstantValue)) { + SymbolType lValueType = SymbolTypeInference.inferType(getScope(), assignment.getlValue()); + ConstantValue constant = getConstantAssignmentValue(assignment, lValueType); + if(constant != null) { + getLog().append("Constant right-side identified " + assignment.toString(getProgram(), false)); + assignment.setrValue2(constant); + assignment.setOperator(null); + assignment.setrValue1(null); + modified = true; + } + } + } + } + } + return modified; + } + + /** + * Examine the right side of an assignment and if it is constant then return the constant value. + * + * @param assignment The assignment to examine + * @param lValueType The type of the lvalue + * @return The constant value if the right side is constant + */ + private ConstantValue getConstantAssignmentValue(StatementAssignment assignment, SymbolType lValueType) { + + if(assignment.getrValue1() == null && Pass2ConstantIdentification.getConstant(assignment.getrValue2()) != null) { + if(assignment.getOperator() == null) { + // Constant assignment + return Pass2ConstantIdentification.getConstant(assignment.getrValue2()); + } else { + // Constant unary expression + return Pass2ConstantIdentification.createUnary( + (OperatorUnary) assignment.getOperator(), + Pass2ConstantIdentification.getConstant(assignment.getrValue2()) + ); + } + } else if(Pass2ConstantIdentification.getConstant(assignment.getrValue1()) != null && Pass2ConstantIdentification.getConstant(assignment.getrValue2()) != null) { + // Constant binary expression + return Pass2ConstantIdentification.createBinary( + Pass2ConstantIdentification.getConstant(assignment.getrValue1()), + (OperatorBinary) assignment.getOperator(), + Pass2ConstantIdentification.getConstant(assignment.getrValue2()), + getScope()); + } else if(assignment.getrValue2() instanceof ValueList && assignment.getOperator() == null && assignment.getrValue1() == null) { + // A candidate for a constant list - examine to confirm + if(lValueType instanceof SymbolTypeArray) { + ValueList valueList = (ValueList) assignment.getrValue2(); + List values = valueList.getList(); + boolean allConstant = true; + // Type of the elements of the list (deducted from the type of all elements) + SymbolType listType = null; + List elements = new ArrayList<>(); + for(RValue elmValue : values) { + if(elmValue instanceof ConstantValue) { + ConstantValue constantValue = (ConstantValue) elmValue; + SymbolType elmType = constantValue.getType(getScope()); + if(listType == null) { + listType = elmType; + } else { + if(!listType.equals(elmType)) { + // No overlap between list type and element type + throw new RuntimeException("Array type " + listType + " does not match element type " + elmType + ". Array: " + valueList.toString(getProgram())); + } + } + elements.add(constantValue); + } else { + allConstant = false; + listType = null; + break; + } + } + if(allConstant && listType != null) { + // Constant list confirmed! + return new ConstantArrayList(elements, listType); + } + } + } else if(Operators.ADDRESS_OF.equals(assignment.getOperator()) && assignment.getrValue1() == null) { + // Constant address-of variable + if(assignment.getrValue2() instanceof SymbolRef) { + return new ConstantSymbolPointer((SymbolRef) assignment.getrValue2()); + } + } + return null; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java index 8b748d28e..1ec335d23 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantSimplification.java @@ -6,13 +6,15 @@ import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.values.ConstantBinary; import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantUnary; +import dk.camelot64.kickc.model.values.ConstantValue; -/** Simplifies constant values +/** + * Simplifies constant values * - ++123 to 124 * - --123 to 122 * - x+0 to x * - x*0 to 0 - * */ + */ public class Pass2ConstantSimplification extends Pass2SsaOptimization { public Pass2ConstantSimplification(Program program) { @@ -28,25 +30,49 @@ public class Pass2ConstantSimplification extends Pass2SsaOptimization { if(Operators.INCREMENT.equals(unary.getOperator()) && unary.getOperand() instanceof ConstantInteger) { // Found a candidate!! ConstantInteger intOperand = (ConstantInteger) unary.getOperand(); - getLog().append("Simplifying constant integer increment "+unary); - programValue.set(new ConstantInteger(intOperand.getValue()+1)); + getLog().append("Simplifying constant integer increment " + unary); + programValue.set(new ConstantInteger(intOperand.getValue() + 1, intOperand.getType())); optimized[0] = true; } else if(Operators.DECREMENT.equals(unary.getOperator()) && unary.getOperand() instanceof ConstantInteger) { // Found a candidate!! ConstantInteger intOperand = (ConstantInteger) unary.getOperand(); - getLog().append("Simplifying constant integer decrement "+unary); - programValue.set(new ConstantInteger(intOperand.getValue()+1)); + getLog().append("Simplifying constant integer decrement " + unary); + programValue.set(new ConstantInteger(intOperand.getValue() - 1, intOperand.getType())); optimized[0] = true; } + if(Operators.INCREMENT.equals(unary.getOperator()) && unary.getOperand() instanceof ConstantBinary) { + ConstantBinary binary = (ConstantBinary) unary.getOperand(); + if(binary.getRight() instanceof ConstantInteger && binary.getOperator().equals(Operators.PLUS)) { + // Found a candidate!! + ConstantInteger intOperand = (ConstantInteger) binary.getRight(); + getLog().append("Simplifying constant integer increment " + unary); + programValue.set(new ConstantBinary(binary.getLeft(), Operators.PLUS, new ConstantInteger(intOperand.getValue() + 1, intOperand.getType()))); + optimized[0] = true; + } else { + ConstantValue subOperand = unary.getOperand(); + // Found a nested increment (that does nest another increment) + getLog().append("Simplifying constant integer increment " + unary); + programValue.set(new ConstantBinary(subOperand, Operators.PLUS, new ConstantInteger(1L))); + optimized[0] = true; + } + } + if(Operators.INCREMENT.equals(unary.getOperator())) + if((unary.getOperand() instanceof ConstantUnary) && !Operators.INCREMENT.equals(((ConstantUnary) unary.getOperand()).getOperator())) { + ConstantValue subOperand = unary.getOperand(); + // Found a nested increment (that does nest another increment) + getLog().append("Simplifying constant integer increment " + unary); + programValue.set(new ConstantBinary(subOperand, Operators.PLUS, new ConstantInteger(1L))); + optimized[0] = true; + } } else if(programValue.get() instanceof ConstantBinary) { ConstantBinary binary = (ConstantBinary) programValue.get(); if(Operators.MULTIPLY.equals(binary.getOperator())) { if(binary.getLeft() instanceof ConstantInteger && ((ConstantInteger) binary.getLeft()).getValue() == 0) { getLog().append("Simplifying constant multiply by zero " + binary); - programValue.set(new ConstantInteger(0L)); + programValue.set(new ConstantInteger(0L, binary.getType(getScope()))); } else if(binary.getRight() instanceof ConstantInteger && ((ConstantInteger) binary.getRight()).getValue() == 0) { getLog().append("Simplifying constant multiply by zero " + binary); - programValue.set(new ConstantInteger(0L)); + programValue.set(new ConstantInteger(0L, binary.getType(getScope()))); } } else if(Operators.PLUS.equals(binary.getOperator())) { if(binary.getLeft() instanceof ConstantInteger && ((ConstantInteger) binary.getLeft()).getValue() == 0) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantValues.java new file mode 100644 index 000000000..e81c7b10b --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantValues.java @@ -0,0 +1,36 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.values.*; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Compiler Pass identifying constants values + */ +public class Pass2ConstantValues extends Pass2SsaOptimization { + + public Pass2ConstantValues(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + + ProgramValueIterator.execute(getProgram().getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> { + Value value = programValue.get(); + if((value instanceof RValue) && !(value instanceof ConstantValue)) { + ConstantValue constant = Pass2ConstantIdentification.getConstant((RValue) value); + if(constant!=null) { + programValue.set(constant); + getLog().append("Constant value identified " + value+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + modified.set(true); + } + } + }); + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2DeInlineWordDerefIdx.java b/src/main/java/dk/camelot64/kickc/passes/Pass2DeInlineWordDerefIdx.java index 4bfcbac8a..267a085ab 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2DeInlineWordDerefIdx.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2DeInlineWordDerefIdx.java @@ -9,6 +9,7 @@ import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.VariableIntermediate; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.AssignmentRValue; import dk.camelot64.kickc.model.values.PointerDereferenceIndexed; import dk.camelot64.kickc.model.values.PointerDereferenceSimple; import dk.camelot64.kickc.model.values.RValue; @@ -35,12 +36,13 @@ public class Pass2DeInlineWordDerefIdx extends Pass2SsaOptimization { getLog().append("De-inlining pointer[w] to *(pointer+w) "+currentStmt.toString(getProgram(), false)); Scope currentScope = getScope().getScope(currentBlock.getScope()); VariableIntermediate tmpVar = currentScope.addVariableIntermediate(); - SymbolType pointerType = SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue); - tmpVar.setType(pointerType); stmtIt.previous(); - stmtIt.add(new StatementAssignment(tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, currentStmt.getSource(), Comment.NO_COMMENTS)); + StatementAssignment tmpVarAssignment = new StatementAssignment(tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, currentStmt.getSource(), Comment.NO_COMMENTS); + stmtIt.add(tmpVarAssignment); stmtIt.next(); programValue.set(new PointerDereferenceSimple(tmpVar.getRef())); + SymbolType pointerType = SymbolTypeInference.inferType(getScope(), new AssignmentRValue(tmpVarAssignment)); + tmpVar.setTypeInferred(pointerType); optimized.set(true); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2DuplicateRValueIdentification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2DuplicateRValueIdentification.java new file mode 100644 index 000000000..09f8fa690 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2DuplicateRValueIdentification.java @@ -0,0 +1,143 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValue; +import dk.camelot64.kickc.model.iterator.ProgramValueHandler; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.operators.Operator; +import dk.camelot64.kickc.model.operators.OperatorCast; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.values.ConstantValue; +import dk.camelot64.kickc.model.values.PointerDereference; +import dk.camelot64.kickc.model.values.RValue; +import dk.camelot64.kickc.model.values.VariableRef; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Compiler Pass identifying R-values that are duplicates of each other - and consolidates them to a single RValue. + */ +public class Pass2DuplicateRValueIdentification extends Pass2SsaOptimization { + + public Pass2DuplicateRValueIdentification(Program program) { + super(program); + } + + @Override + public boolean step() { + boolean modified = false; + + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + Set rValues = new HashSet<>(); + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) statement; + AssignmentRValue assignmentRValue = new AssignmentRValue(assignment, block); + if(!assignmentRValue.isConstant() && !assignmentRValue.isTrivial() && !assignmentRValue.isVolatile()) { + if(rValues.contains(assignmentRValue)) { + AssignmentRValue firstAssignment = rValues.stream().filter(assignmentRValue1 -> assignmentRValue1.equals(assignmentRValue)).findFirst().get(); + if(firstAssignment.assignment.getlValue() instanceof VariableRef) { + getLog().append("Identified duplicate assignment right side "+assignment.toString(getProgram(), false)); + assignment.setrValue1(null); + assignment.setOperator(null); + assignment.setrValue2(firstAssignment.assignment.getlValue()); + modified = true; + } else { + throw new InternalError("Complex lValue for duplicate rvalue "+firstAssignment.assignment.toString(getProgram(), false)); + } + } else { + rValues.add(assignmentRValue); + } + } + } + } + } + return modified; + } + + + /** + * Represents an RValue of an assignment. + * Implements equals() and hashcode() to allow identification of duplicate RValues + */ + private class AssignmentRValue { + private ControlFlowBlock block; + private StatementAssignment assignment; + private RValue rValue1; + private Operator operator; + private RValue rValue2; + + public AssignmentRValue(StatementAssignment assignment, ControlFlowBlock block) { + this.block = block; + this.assignment = assignment; + this.rValue1 = assignment.getrValue1(); + this.operator = assignment.getOperator(); + this.rValue2 = assignment.getrValue2(); + } + + private boolean isConstant() { + if(rValue1 != null && !(rValue1 instanceof ConstantValue)) + return false; + if(rValue2 != null && !(rValue2 instanceof ConstantValue)) + return false; + return true; + } + + private boolean isVolatile() { + AtomicBoolean isVol = new AtomicBoolean(false); + ProgramValueHandler identifyVolatiles = (programValue, currentStmt, stmtIt, currentBlock) -> { + if(programValue.get() instanceof PointerDereference) + isVol.set(true); + if(programValue.get() instanceof VariableRef) { + Variable variable = getScope().getVariable((VariableRef) programValue.get()); + if(variable.isDeclaredVolatile()) + isVol.set(true); + } + }; + ProgramValueIterator.execute(new ProgramValue.RValue1(assignment), identifyVolatiles, assignment, null, null); + ProgramValueIterator.execute(new ProgramValue.RValue2(assignment), identifyVolatiles, assignment, null, null); + if(Operators.DEREF.equals(operator) || Operators.DEREF_IDX.equals(operator)) + isVol.set(true); + return isVol.get(); + } + + private boolean isTrivial() { + if(operator == null) return true; + if(operator instanceof OperatorCast) return true; + if(operator.equals(Operators.PLUS)) return true; + if(operator.equals(Operators.MINUS)) return true; + if(operator.equals(Operators.LE)) return true; + if(operator.equals(Operators.LT)) return true; + if(operator.equals(Operators.GE)) return true; + if(operator.equals(Operators.GT)) return true; + if(operator.equals(Operators.EQ)) return true; + if(operator.equals(Operators.NEQ)) return true; + if(operator.equals(Operators.LOGIC_NOT)) return true; + if(operator.equals(Operators.LOGIC_AND)) return true; + if(operator.equals(Operators.LOGIC_OR)) return true; + return false; + } + + + @Override + public boolean equals(Object o) { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + AssignmentRValue that = (AssignmentRValue) o; + return Objects.equals(rValue1, that.rValue1) && + Objects.equals(operator, that.operator) && + Objects.equals(rValue2, that.rValue2); + } + + @Override + public int hashCode() { + return Objects.hash(rValue1, operator, rValue2); + } + + } +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateRedundantCasts.java b/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateRedundantCasts.java deleted file mode 100644 index 40731c99a..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2EliminateRedundantCasts.java +++ /dev/null @@ -1,75 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.operators.OperatorCastPtr; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.values.RValue; - -/** - * Eliminate casts that are not necessary - */ -public class Pass2EliminateRedundantCasts extends Pass2SsaOptimization { - - public Pass2EliminateRedundantCasts(Program program) { - super(program); - } - - @Override - public boolean step() { - boolean modified = false; - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - for(Statement statement : block.getStatements()) { - if(statement instanceof StatementAssignment) { - StatementAssignment assignment = (StatementAssignment) statement; - if(isRedundantCast(assignment)) { - // Redundant cast - getLog().append("Removing redundant cast " + statement.toString(getProgram(), false)); - assignment.setOperator(null); - modified = true; - } - } - } - } - return modified; - } - - /** - * Determines if the assignment is a redundant cast - * - * @param assignment The assignment to examine - * @return true if is is a redundant cast - */ - private boolean isRedundantCast(StatementAssignment assignment) { - RValue rValue2 = assignment.getrValue2(); - SymbolType rValue2Type = SymbolTypeInference.inferType(getScope(), rValue2); - if(Operators.CAST_BYTE.equals(assignment.getOperator()) && SymbolType.BYTE.equals(rValue2Type)) { - return true; - } else if(Operators.CAST_SBYTE.equals(assignment.getOperator()) && SymbolType.SBYTE.equals(rValue2Type)) { - return true; - } else if(Operators.CAST_WORD.equals(assignment.getOperator()) && SymbolType.WORD.equals(rValue2Type)) { - return true; - } else if(Operators.CAST_SWORD.equals(assignment.getOperator()) && SymbolType.SWORD.equals(rValue2Type)) { - return true; - } else if(Operators.CAST_DWORD.equals(assignment.getOperator()) && SymbolType.DWORD.equals(rValue2Type)) { - return true; - } else if(Operators.CAST_SDWORD.equals(assignment.getOperator()) && SymbolType.SDWORD.equals(rValue2Type)) { - return true; - } else if(Operators.CAST_BOOL.equals(assignment.getOperator()) && SymbolType.BOOLEAN.equals(rValue2Type)) { - return true; - } else if(assignment.getOperator() instanceof OperatorCastPtr) { - // Casting to a pointer - OperatorCastPtr operatorCastPtr = (OperatorCastPtr) assignment.getOperator(); - if(rValue2Type.equals(new SymbolTypePointer(operatorCastPtr.getElementType()))) { - return true; - } - } - return false; - } - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java deleted file mode 100644 index 1bdd74241..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java +++ /dev/null @@ -1,132 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.Comment; -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.iterator.ProgramValue; -import dk.camelot64.kickc.model.iterator.ProgramValueHandler; -import dk.camelot64.kickc.model.iterator.ProgramValueIterator; -import dk.camelot64.kickc.model.operators.Operator; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.symbols.Scope; -import dk.camelot64.kickc.model.symbols.VariableIntermediate; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeArray; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; -import dk.camelot64.kickc.model.values.Value; -import dk.camelot64.kickc.model.values.ValueList; - -import java.util.ListIterator; - -/** - * Identifies word constructors { b1, b2 } and replaces - * them with a binary operator word w = b1 w= b2 ; - */ -public class Pass2FixInlineConstructors extends Pass2SsaOptimization { - - public Pass2FixInlineConstructors(Program program) { - super(program); - } - - @Override - public boolean step() { - WordConstructor wordConstructor = new WordConstructor(); - ProgramValueIterator.execute(getGraph(), wordConstructor); - DWordConstructor dwordConstructor = new DWordConstructor(); - ProgramValueIterator.execute(getGraph(), dwordConstructor); - return wordConstructor.isOptimized() || dwordConstructor.isOptimized(); - } - - /** Replaces { b1, b2 } with a w= operator */ - private class WordConstructor extends InlineConstructor { - - public WordConstructor() { - super(SymbolType.WORD, Operators.WORD); - } - - @Override - protected boolean isSubType(SymbolType elmType) { - return SymbolType.isByte(elmType); - } - } - - /** Replaces { w1, w2 } with a dw= operator */ - private class DWordConstructor extends InlineConstructor { - - public DWordConstructor() { - super(SymbolType.DWORD, Operators.DWORD); - } - - @Override - protected boolean isSubType(SymbolType elmType) { - return SymbolType.isWord(elmType); - } - } - - - private abstract class InlineConstructor implements ProgramValueHandler { - private SymbolTypeInteger constructType; - private Operator constructOperator; - private boolean optimized; - - public InlineConstructor(SymbolTypeInteger constructType, Operator constructOperator) { - this.constructType = constructType; - this.constructOperator = constructOperator; - } - - protected abstract boolean isSubType(SymbolType elmType); - - public boolean isOptimized() { - return optimized; - } - - @Override - public void execute(ProgramValue programValue, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { - Value rValue = programValue.get(); - if(rValue instanceof ValueList) { - ValueList list = (ValueList) rValue; - if(list.getList().size() == 2) { - // We have a simple assignment of a length 2 value list to a variable - SymbolType elmType1 = SymbolTypeInference.inferType(Pass2FixInlineConstructors.this.getScope(), list.getList().get(0)); - SymbolType elmType2 = SymbolTypeInference.inferType(Pass2FixInlineConstructors.this.getScope(), list.getList().get(1)); - if(isSubType(elmType1) && isSubType(elmType2)) { - // We have a 2-element list { byte, byte } - - // Check if we are assigning into a declared byte array - if(currentStmt instanceof StatementAssignment) { - StatementAssignment assignment = (StatementAssignment) currentStmt; - if(assignment.getrValue1() == null && assignment.getOperator() == null && assignment.getrValue2().equals(rValue)) { - SymbolType lType = SymbolTypeInference.inferType(Pass2FixInlineConstructors.this.getScope(), assignment.getlValue()); - if(lType instanceof SymbolTypeArray && isSubType(((SymbolTypeArray) lType).getElementType())) { - // We are assigning into a declared byte array - do not convert! - return; - } - } - } - - // Convert list to a word constructor in a new tmp variable - Scope currentScope = Pass2FixInlineConstructors.this.getScope().getScope(currentBlock.getScope()); - VariableIntermediate tmpVar = currentScope.addVariableIntermediate(); - tmpVar.setTypeInferred(constructType); - // Move backward - to insert before the current statement - stmtIt.previous(); - // Add assignment of the new tmpVar - StatementAssignment assignment = new StatementAssignment(tmpVar.getRef(), list.getList().get(0), constructOperator, list.getList().get(1), currentStmt.getSource(), Comment.NO_COMMENTS); - stmtIt.add(assignment); - // Move back before the current statement - stmtIt.next(); - // Replace current value with the reference - programValue.set(tmpVar.getRef()); - Pass2FixInlineConstructors.this.getLog().append("Fixing inline constructor with " + assignment.toString()); - optimized = true; - } - } - } - } - } - - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructorsNew.java b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructorsNew.java new file mode 100644 index 000000000..9bb996f01 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructorsNew.java @@ -0,0 +1,94 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Comment; +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpression; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary; +import dk.camelot64.kickc.model.operators.OperatorBinary; +import dk.camelot64.kickc.model.operators.OperatorCastPtr; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.symbols.Scope; +import dk.camelot64.kickc.model.symbols.VariableIntermediate; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.values.CastValue; +import dk.camelot64.kickc.model.values.RValue; +import dk.camelot64.kickc.model.values.ValueList; + +import java.util.List; +import java.util.ListIterator; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Identifies word constructors (word) { b1, b2 } and replaces + * them with a binary operator word w = b1 w= b2 ; + */ +public class Pass2FixInlineConstructorsNew extends Pass2SsaOptimization { + + public Pass2FixInlineConstructorsNew(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean optimized = new AtomicBoolean(false); + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(programExpression instanceof ProgramExpressionUnary) { + if(((ProgramExpressionUnary) programExpression).getOperand() instanceof ValueList) { + ValueList list = (ValueList) ((ProgramExpressionUnary) programExpression).getOperand(); + List listValues = list.getList(); + if(listValues.size() == 2) { + if(programExpression.getOperator().equals(Operators.CAST_WORD)) { + addLiteralWordConstructor(Operators.WORD, SymbolType.WORD, SymbolType.BYTE, programExpression, listValues, currentStmt, stmtIt, currentBlock); + optimized.set(true); + } else if(programExpression.getOperator() instanceof OperatorCastPtr) { + SymbolType castType = ((OperatorCastPtr) programExpression.getOperator()).getToType(); + addLiteralWordConstructor(Operators.WORD, castType, SymbolType.BYTE, programExpression, listValues, currentStmt, stmtIt, currentBlock); + optimized.set(true); + } else if(programExpression.getOperator().equals(Operators.CAST_DWORD)) { + addLiteralWordConstructor(Operators.DWORD, SymbolType.DWORD, SymbolType.WORD, programExpression, listValues, currentStmt, stmtIt, currentBlock); + optimized.set(true); + } + } + } + } + }); + return optimized.get(); + + } + + /** + * Add a literal word/dword constructor. + * Converts a cast value-list with 2 items to a word/dword constructor. + * (word) { 1, 2 } -> 1 =w 2 + * @param constructOperator The operator to add + * @param constructType The type being constructed + * @param subType The sub-type + * @param programExpression The program expression containing the cast value list + * @param listValues + * @param currentStmt + * @param stmtIt + * @param currentBlock + */ + public void addLiteralWordConstructor(OperatorBinary constructOperator, SymbolType constructType, SymbolType subType, ProgramExpression programExpression, List listValues, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { + // Convert list to a word constructor in a new tmp variable + Scope currentScope = Pass2FixInlineConstructorsNew.this.getScope().getScope(currentBlock.getScope()); + VariableIntermediate tmpVar = currentScope.addVariableIntermediate(); + //tmpVar.setTypeInferred(constructType); + // Move backward - to insert before the current statement + stmtIt.previous(); + // Add assignment of the new tmpVar + StatementAssignment assignment = new StatementAssignment(tmpVar.getRef(), new CastValue(subType, listValues.get(0)), constructOperator, new CastValue(subType, listValues.get(1)), currentStmt.getSource(), Comment.NO_COMMENTS); + stmtIt.add(assignment); + // Move back before the current statement + stmtIt.next(); + // Replace current value with the reference + programExpression.set(tmpVar.getRef()); + Pass2FixInlineConstructorsNew.this.getLog().append("Fixing inline constructor with " + assignment.toString()); + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2InlineCast.java b/src/main/java/dk/camelot64/kickc/passes/Pass2InlineCast.java new file mode 100644 index 000000000..2ba632bed --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2InlineCast.java @@ -0,0 +1,39 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.operators.OperatorCast; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.values.CastValue; + +/** Identify unary casts */ +public class Pass2InlineCast extends Pass2SsaOptimization { + + public Pass2InlineCast(Program program) { + super(program); + } + + @Override + public boolean step() { + boolean optimized = false; + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) statement; + if(assignment.getrValue1()==null && assignment.getOperator() instanceof OperatorCast) { + SymbolType toType = ((OperatorCast) assignment.getOperator()).getToType(); + assignment.setrValue2(new CastValue(toType, assignment.getrValue2())); + assignment.setOperator(null); + getLog().append("Inlining cast "+assignment.toString(getProgram(), false)); + optimized = true; + } + } + } + } + return optimized; + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java b/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java index dd7b0a85e..3a8146be7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2InlineDerefIdx.java @@ -12,6 +12,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.values.*; +import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; /** Identify derefs of pointers that are defined as pointer + value - and inline them as derefidx instead */ @@ -71,6 +72,11 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization { public RValue attemptInlineDeref(StatementAssignment derefAssignment) { + VariableRef derefVar = (VariableRef) derefAssignment.getlValue(); + Collection varUseStatements = getProgram().getVariableReferenceInfos().getVarUseStatements(derefVar); + if(varUseStatements.size()>2) { + return null; + } if(Operators.PLUS.equals(derefAssignment.getOperator())) { SymbolType derefLeftType = SymbolTypeInference.inferType(getScope(), derefAssignment.getrValue1()); if(derefLeftType instanceof SymbolTypePointer) { @@ -83,7 +89,7 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization { } else if(derefAssignment.getOperator()==null) { return attemptInlineDeref(derefAssignment.getrValue2()); } else if(derefAssignment.getOperator() instanceof OperatorCastPtr) { - throw new CompileError("Not implemented!"); + //throw new CompileError("Not implemented!"); //return attemptInlineDeref(derefAssignment.getrValue2()); } return null; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java b/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java index 123efd721..5664593e6 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java @@ -6,14 +6,8 @@ import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.statements.StatementCall; -import dk.camelot64.kickc.model.statements.StatementCallPointer; -import dk.camelot64.kickc.model.symbols.ConstantVar; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeProcedure; import dk.camelot64.kickc.model.values.*; -import kickass.pass.expressions.expr.Constant; import java.util.ListIterator; @@ -34,7 +28,8 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { if(statement instanceof StatementAssignment) { StatementAssignment assignment = (StatementAssignment) statement; if(Operators.MULTIPLY.equals(assignment.getOperator()) || Operators.DIVIDE.equals(assignment.getOperator())) { - ConstantLiteral constantLiteral = getConstantLiteral(assignment); + if(assignment.getrValue1() instanceof ConstantValue) continue; + ConstantLiteral constantLiteral = getConstantLiteral2(assignment); if(constantLiteral instanceof ConstantInteger) { Long constantInt = ((ConstantInteger)constantLiteral).getInteger(); double power2 = Math.log(constantInt) / Math.log(2); @@ -50,12 +45,12 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { if(Operators.MULTIPLY.equals(assignment.getOperator())) { getLog().append("Rewriting multiplication to use shift "+statement.toString(getProgram(), false)); assignment.setOperator(Operators.SHIFT_LEFT); - assignment.setrValue2(new ConstantInteger((long)power2)); + assignment.setrValue2(new ConstantInteger((long)power2, SymbolType.BYTE)); optimized = true; } else if(Operators.DIVIDE.equals(assignment.getOperator())) { getLog().append("Rewriting division to use shift "+statement.toString(getProgram(), false)); assignment.setOperator(Operators.SHIFT_RIGHT); - assignment.setrValue2(new ConstantInteger((long)power2)); + assignment.setrValue2(new ConstantInteger((long)power2, SymbolType.BYTE)); optimized = true; } } @@ -72,7 +67,7 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { * @param assignment The Assignment * @return The constant literal value for RValue2 (or null) */ - private ConstantLiteral getConstantLiteral(StatementAssignment assignment) { + private ConstantLiteral getConstantLiteral2(StatementAssignment assignment) { if(assignment.getrValue2() instanceof ConstantValue) { ConstantValue constantValue = (ConstantValue) assignment.getrValue2(); try { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java deleted file mode 100644 index a298ad251..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastElimination.java +++ /dev/null @@ -1,87 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.operators.OperatorCastPtr; -import dk.camelot64.kickc.model.operators.Operators; -import dk.camelot64.kickc.model.values.*; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInference; -import dk.camelot64.kickc.model.types.SymbolTypePointer; - -import java.util.LinkedHashMap; -import java.util.ListIterator; - -/** - * Compiler Pass eliminating cast assignments that has no effect (byte to/from signed byte, word to/from signed word) - */ -public class Pass2NopCastElimination extends Pass2SsaOptimization { - - public Pass2NopCastElimination(Program program) { - super(program); - } - - /** - * Eliminate cast assignments that has no effect (byte to/from signed byte, word to/from signed word) - */ - @Override - public boolean step() { - LinkedHashMap castAliasses = new LinkedHashMap<>(); - - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - ListIterator stmtIt = block.getStatements().listIterator(); - while(stmtIt.hasNext()) { - Statement stmt = stmtIt.next(); - if(stmt instanceof StatementAssignment) { - StatementAssignment assignment = (StatementAssignment) stmt; - if(assignment.getlValue() instanceof VariableRef && assignment.getrValue1()==null && assignment.getOperator()!=null ) { - // It is a simple cast assignment - check if it is no-op - SymbolType rValType = SymbolTypeInference.inferType(getScope(), assignment.getrValue2()); - boolean isNopCast = false; - SymbolType toType = null; - if(SymbolType.isByte(rValType) && Operators.CAST_SBYTE.equals(assignment.getOperator())) { - isNopCast = true; - toType = SymbolType.SBYTE; - } else if(SymbolType.isSByte(rValType) && Operators.CAST_BYTE.equals(assignment.getOperator())) { - isNopCast = true; - toType = SymbolType.BYTE; - } else if(SymbolType.isWord(rValType) && Operators.CAST_SWORD.equals(assignment.getOperator())) { - isNopCast = true; - toType = SymbolType.SWORD; - } else if(SymbolType.isSWord(rValType) && Operators.CAST_WORD.equals(assignment.getOperator())) { - isNopCast = true; - toType = SymbolType.WORD; - } else if(SymbolType.isWord(rValType) && assignment.getOperator() instanceof OperatorCastPtr) { - isNopCast = true; - OperatorCastPtr castOperator = (OperatorCastPtr) (assignment.getOperator()); - toType = new SymbolTypePointer(castOperator.getElementType()); - } else if(rValType instanceof SymbolTypePointer && Operators.CAST_WORD.equals(assignment.getOperator())) { - isNopCast = true; - toType = SymbolType.WORD; - } else if(rValType instanceof SymbolTypePointer && assignment.getOperator() instanceof OperatorCastPtr) { - isNopCast = true; - toType = new SymbolTypePointer(((OperatorCastPtr) assignment.getOperator()).getElementType()); - } - if(isNopCast) { - getLog().append("Eliminating Noop Cast "+assignment.toString(getProgram(), false)); - // Add the alias for replacement - if(assignment.getrValue2() instanceof ConstantValue) { - castAliasses.put((VariableRef) assignment.getlValue(), new ConstantCastValue(toType, (ConstantValue) assignment.getrValue2())); - } else { - castAliasses.put((VariableRef) assignment.getlValue(), new CastValue(toType, assignment.getrValue2())); - } - // Remove the assignment - stmtIt.remove(); - } - } - } - } - } - replaceVariables(castAliasses); - deleteSymbols(getScope(), castAliasses.keySet()); - return (castAliasses.size() > 0); - } - - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastInlining.java b/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastInlining.java new file mode 100644 index 000000000..8d1fe6a05 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2NopCastInlining.java @@ -0,0 +1,78 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.types.SymbolTypePointer; +import dk.camelot64.kickc.model.values.CastValue; +import dk.camelot64.kickc.model.values.RValue; +import dk.camelot64.kickc.model.values.SymbolRef; +import dk.camelot64.kickc.model.values.VariableRef; + +import java.util.LinkedHashMap; +import java.util.ListIterator; + +/** + * Compiler Pass inlineng cast assignments that has no effect (byte to/from signed byte, word to/from signed word) + */ +public class Pass2NopCastInlining extends Pass2SsaOptimization { + + public Pass2NopCastInlining(Program program) { + super(program); + } + + /** + * Inline cast assignments that has no effect (byte to/from signed byte, word to/from signed word) + */ + @Override + public boolean step() { + LinkedHashMap castAliasses = new LinkedHashMap<>(); + + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + ListIterator stmtIt = block.getStatements().listIterator(); + while(stmtIt.hasNext()) { + Statement stmt = stmtIt.next(); + if(stmt instanceof StatementAssignment) { + StatementAssignment assignment = (StatementAssignment) stmt; + // TODO: Handle constant values? + if(assignment.getOperator()==null && assignment.getrValue2() instanceof CastValue) { + CastValue castValue = (CastValue) assignment.getrValue2(); + SymbolType subValType = SymbolTypeInference.inferType(getScope(), castValue.getValue()); + boolean isNopCast = false; + if(SymbolType.BYTE.equals(castValue.getToType()) && SymbolType.SBYTE.equals(subValType)) { + isNopCast = true; + } else if(SymbolType.SBYTE.equals(castValue.getToType()) && SymbolType.BYTE.equals(subValType)) { + isNopCast = true; + } else if(SymbolType.WORD.equals(castValue.getToType()) && SymbolType.SWORD.equals(subValType)) { + isNopCast = true; + } else if(SymbolType.SWORD.equals(castValue.getToType()) && SymbolType.WORD.equals(subValType)) { + isNopCast = true; + } else if(castValue.getToType() instanceof SymbolTypePointer && SymbolType.WORD.equals(subValType)) { + isNopCast = true; + } else if(SymbolType.WORD.equals(castValue.getToType()) && subValType instanceof SymbolTypePointer) { + isNopCast = true; + } else if(castValue.getToType() instanceof SymbolTypePointer && subValType instanceof SymbolTypePointer) { + isNopCast = true; + } + if(isNopCast && assignment.getlValue() instanceof VariableRef) { + getLog().append("Inlining Noop Cast " + assignment.toString(getProgram(), false)); + // Add the alias for replacement + castAliasses.put((VariableRef) assignment.getlValue(), assignment.getrValue2()); + // Remove the assignment + stmtIt.remove(); + } + + } + } + } + } + replaceVariables(castAliasses); + deleteSymbols(getScope(), castAliasses.keySet()); + return (castAliasses.size() > 0); + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java b/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java index b5694442d..5bc71e830 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java @@ -6,7 +6,7 @@ import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeInteger; +import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed; import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.values.*; @@ -51,9 +51,9 @@ public class Pass2RangeResolving extends Pass2SsaOptimization { if(rangeValue instanceof RangeComparison) { SymbolType type = ((RangeComparison) rangeValue).getType(); - SymbolTypeInteger valueType; - if(type instanceof SymbolTypeInteger) { - valueType = (SymbolTypeInteger) type; + SymbolTypeIntegerFixed valueType; + if(type instanceof SymbolTypeIntegerFixed) { + valueType = (SymbolTypeIntegerFixed) type; } else if(type instanceof SymbolTypePointer) { valueType = SymbolType.WORD; } else { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2RedundantPhiElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2RedundantPhiElimination.java deleted file mode 100644 index 74371da2e..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2RedundantPhiElimination.java +++ /dev/null @@ -1,75 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.values.LValue; -import dk.camelot64.kickc.model.values.RValue; -import dk.camelot64.kickc.model.values.VariableRef; -import dk.camelot64.kickc.model.statements.StatementPhiBlock; - -import java.util.LinkedHashMap; -import java.util.Map; - -/** Compiler Pass eliminating redundant phi functions */ -public class Pass2RedundantPhiElimination extends Pass2SsaOptimization { - - public Pass2RedundantPhiElimination(Program program) { - super(program); - } - - /** - * Eliminate alias assignments replacing them with the aliased variable. - */ - @Override - public boolean step() { - final Map aliases = findRedundantPhis(); - removeAssignments(getGraph(), aliases.keySet()); - replaceVariables(aliases); - for(VariableRef var : aliases.keySet()) { - RValue alias = aliases.get(var); - getLog().append("Redundant Phi " + var.toString(getProgram()) + " " + alias.toString(getProgram())); - } - deleteSymbols(getScope(), aliases.keySet()); - return aliases.size() > 0; - } - - /** - * Find phi variables where all previous symbols are identical. - * - * @return Map from (phi) Variable to the previous value - */ - private Map findRedundantPhis() { - final Map aliases = new LinkedHashMap<>(); - ControlFlowGraphBaseVisitor visitor = new ControlFlowGraphBaseVisitor() { - - @Override - public Void visitPhiBlock(StatementPhiBlock phi) { - for(StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) { - boolean found = true; - RValue rValue = null; - for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { - if(rValue == null) { - rValue = phiRValue.getrValue(); - } else { - if(!rValue.equals(phiRValue.getrValue())) { - found = false; - break; - } - } - } - if(found) { - VariableRef variable = phiVariable.getVariable(); - if(rValue == null) { - rValue = LValue.VOID; - } - aliases.put(variable, rValue); - } - } - return null; - } - - }; - visitor.visitGraph(getGraph()); - return aliases; - } - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2SizeOfSimplification.java b/src/main/java/dk/camelot64/kickc/passes/Pass2SizeOfSimplification.java index e2c1e6f2c..3121da890 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2SizeOfSimplification.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2SizeOfSimplification.java @@ -76,12 +76,12 @@ public class Pass2SizeOfSimplification extends Pass2SsaOptimization { SymbolTypeArray arrayType = (SymbolTypeArray) symbolType; RValue arraySize = arrayType.getSize(); if(arraySize instanceof ConstantValue) { - getLog().append("Resolving sizeof() " + unary.toString(getProgram())); + getLog().append("Resolving array sizeof() " + unary.toString(getProgram())); ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType()); programValue.set(new ConstantBinary((ConstantValue) arraySize, Operators.MULTIPLY, sizeOfConstantVar)); modified.set(true); } else if(constant.getValue() instanceof ConstantArrayList) { - getLog().append("Resolving sizeof() " + unary.toString(getProgram())); + getLog().append("Resolving array sizeof() " + unary.toString(getProgram())); int size = ((ConstantArrayList) constant.getValue()).getElements().size(); ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType()); programValue.set(new ConstantBinary(new ConstantInteger((long) size), Operators.MULTIPLY, sizeOfConstantVar)); @@ -97,6 +97,7 @@ public class Pass2SizeOfSimplification extends Pass2SsaOptimization { if(stringLiteral instanceof ConstantString) { ConstantString constString = (ConstantString) stringLiteral; int length = constString.getString().length(); + getLog().append("Resolving string sizeof() " + unary.toString(getProgram())); ConstantRef sizeOfChar = OperatorSizeOf.getSizeOfConstantVar(getScope(), SymbolType.BYTE); programValue.set(new ConstantBinary(new ConstantInteger((long) length), Operators.MULTIPLY, sizeOfChar)); modified.set(true); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2TypeInference.java b/src/main/java/dk/camelot64/kickc/passes/Pass2TypeInference.java deleted file mode 100644 index b59532300..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2TypeInference.java +++ /dev/null @@ -1,33 +0,0 @@ -package dk.camelot64.kickc.passes; - -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.Program; -import dk.camelot64.kickc.model.statements.Statement; -import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.statements.StatementCall; -import dk.camelot64.kickc.model.types.SymbolTypeInference; - -/** - * Pass through the all statements (re-)inferring types of variables. - */ -public class Pass2TypeInference extends Pass2SsaOptimization { - - public Pass2TypeInference(Program program) { - super(program); - } - - @Override - public boolean step() { - for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { - for(Statement statement : block.getStatements()) { - if(statement instanceof StatementAssignment) { - SymbolTypeInference.inferAssignmentLValue(getProgram(), (StatementAssignment) statement, true); - } else if(statement instanceof StatementCall) { - SymbolTypeInference.inferCallLValue(getProgram(), (StatementCall) statement, true); - } - } - } - return false; - } - -} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoNumbers.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoNumbers.java new file mode 100644 index 000000000..2a92f6d79 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoNumbers.java @@ -0,0 +1,63 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.InternalError; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.statements.StatementAssignment; +import dk.camelot64.kickc.model.statements.StatementConditionalJump; +import dk.camelot64.kickc.model.statements.StatementPhiBlock; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.RValue; + +/** + * Assert that all values with type number have been resolved to fixed size in pass 2. + */ +public class Pass3AssertNoNumbers extends Pass2SsaAssertion { + + public Pass3AssertNoNumbers(Program program) { + super(program); + } + + @Override + public void check() throws AssertionFailed { + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + if(statement instanceof StatementAssignment) { + checkValue(((StatementAssignment) statement).getlValue(), statement); + checkValue(((StatementAssignment) statement).getrValue1(), statement); + checkValue(((StatementAssignment) statement).getrValue2(), statement); + } else if(statement instanceof StatementPhiBlock) { + for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) { + for(StatementPhiBlock.PhiRValue value : phiVariable.getValues()) { + checkValue(value.getrValue(), statement); + } + } + } else if(statement instanceof StatementConditionalJump) { + checkValue(((StatementConditionalJump) statement).getrValue1(), statement); + checkValue(((StatementConditionalJump) statement).getrValue2(), statement); + } + } + } + } + + /** + * Check a value to ensure it is does not have the {@link SymbolType#NUMBER}. + * + * @param rValue The value to check + * @param statement The statement containing the value + */ + public void checkValue(RValue rValue, Statement statement) { + if(rValue == null) return; + SymbolType symbolType = SymbolTypeInference.inferType(getScope(), rValue); + if(SymbolType.NUMBER.equals(symbolType)) { + throw new InternalError( + "Error! Number integer type not resolved to fixed size integer type " + + "\n value: " + rValue.toString(getProgram()) + + "\n statement: " + statement.toString(getProgram(), false) + , statement.getSource() + ); + } + } +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoTypeId.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoTypeId.java new file mode 100644 index 000000000..fa8c01773 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertNoTypeId.java @@ -0,0 +1,34 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.InternalError; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.values.ConstantUnary; +import dk.camelot64.kickc.model.values.Value; + +/** + * Assert that no typeid() expressions exist in the code anymore (they must have been resolved to constants in phase 1-2) + */ +public class Pass3AssertNoTypeId extends Pass2SsaAssertion { + + public Pass3AssertNoTypeId(Program program) { + super(program); + } + + @Override + public void check() throws AssertionFailed { + ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { + Value value = programValue.get(); + if(value instanceof ConstantUnary) { + if(Operators.TYPEID.equals(((ConstantUnary) value).getOperator())) { + throw new InternalError( + "Error! Typeid() not resolved during compile. " + + "\n statement: " + currentStmt.toString(getProgram(), false) + , currentStmt.getSource() + ); + } + } + }); + } +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java index 70a4e99f8..b0b9cdf05 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java @@ -1,6 +1,6 @@ package dk.camelot64.kickc.passes; -import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.values.RangeValue; @@ -24,7 +24,7 @@ public class Pass3AssertRValues extends Pass2SsaAssertion { ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> { Value value = programValue.get(); if(value instanceof ValueList) { - throw new CompileError( + throw new InternalError( "Error! Value list not resolved to word constructor or array initializer" + "\n value list: " + value.toString(getProgram()) + "\n statement: " + currentStmt.toString(getProgram(), false) @@ -32,7 +32,7 @@ public class Pass3AssertRValues extends Pass2SsaAssertion { ); } if(value instanceof RangeValue) { - throw new CompileError( + throw new InternalError( "Error! Ranged for() not resolved to constants" + "\n Range: " + value.toString(getProgram()) + "\n statement: " + currentStmt.toString(getProgram(), false) diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3PhiMemCoalesce.java b/src/main/java/dk/camelot64/kickc/passes/Pass3PhiMemCoalesce.java index 65b5fae89..2e0f1547d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3PhiMemCoalesce.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3PhiMemCoalesce.java @@ -1,10 +1,14 @@ package dk.camelot64.kickc.passes; -import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.values.ConstantValue; -import dk.camelot64.kickc.model.values.VariableRef; +import dk.camelot64.kickc.model.ControlFlowGraphBaseVisitor; +import dk.camelot64.kickc.model.LiveRangeEquivalenceClass; +import dk.camelot64.kickc.model.LiveRangeEquivalenceClassSet; +import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementPhiBlock; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.values.ConstantValue; +import dk.camelot64.kickc.model.values.VariableRef; import java.util.ArrayList; import java.util.HashMap; @@ -49,9 +53,12 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization { */ public static class EquivalenceClassPhiInitializer extends ControlFlowGraphBaseVisitor { + private Program program; + private LiveRangeEquivalenceClassSet phiEquivalenceClasses; public EquivalenceClassPhiInitializer(Program program) { + this.program = program; this.phiEquivalenceClasses = new LiveRangeEquivalenceClassSet(program); } @@ -65,7 +72,13 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization { VariableRef phiRVar = (VariableRef) phiRValue.getrValue(); LiveRangeEquivalenceClass rValEquivalenceClass = phiEquivalenceClasses.getOrCreateEquivalenceClass(phiRVar); if(!rValEquivalenceClass.equals(equivalenceClass)) { - phiEquivalenceClasses.consolidate(equivalenceClass, rValEquivalenceClass); + SymbolType varType = program.getScope().getVariable(variable).getType(); + SymbolType rVarType = program.getScope().getVariable(phiRVar).getType(); + if(varType.getSizeBytes()==rVarType.getSizeBytes()) { + phiEquivalenceClasses.consolidate(equivalenceClass, rValEquivalenceClass); + } else { + program.getLog().append("Not consolidating phi with different size "+variable.toString()+" "+phiRVar.toString()); + } } } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 630581697..8a3920906 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -6,10 +6,7 @@ import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.statements.*; import dk.camelot64.kickc.model.symbols.*; -import dk.camelot64.kickc.model.types.SymbolType; -import dk.camelot64.kickc.model.types.SymbolTypeArray; -import dk.camelot64.kickc.model.types.SymbolTypePointer; -import dk.camelot64.kickc.model.types.SymbolTypeProcedure; +import dk.camelot64.kickc.model.types.*; import dk.camelot64.kickc.model.values.*; import java.util.*; @@ -387,13 +384,13 @@ public class Pass4CodeGeneration { String asmElement = AsmFormat.getAsmConstant(program, element, 99, scopeRef); asmElements.add(asmElement); } - if(SymbolType.isByte(elementType) || SymbolType.isSByte(elementType)) { + if(SymbolType.BYTE.equals(elementType) || SymbolType.SBYTE.equals(elementType)) { asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmElements); added.add(asmName); - } else if(SymbolType.isWord(elementType) || SymbolType.isSWord(elementType)) { + } else if(SymbolType.WORD.equals(elementType) || SymbolType.SWORD.equals(elementType)) { asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmElements); added.add(asmName); - } else if(SymbolType.isDWord(elementType) || SymbolType.isSDWord(elementType)) { + } else if(SymbolType.DWORD.equals(elementType) || SymbolType.SDWORD.equals(elementType)) { asm.addDataNumeric(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmElements); added.add(asmName); } else if(elementType instanceof SymbolTypePointer) { @@ -410,27 +407,27 @@ public class Pass4CodeGeneration { throw new Pass2SsaAssertion.AssertionFailed("Error! Array size is not constant integer " + constantVar.toString(program)); } int size = ((ConstantInteger) arraySizeConst).getInteger().intValue(); - if(SymbolType.isByte(constantArrayFilled.getElementType())) { + if(SymbolType.BYTE.equals(constantArrayFilled.getElementType())) { String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmSize, size, "0"); added.add(asmName); - } else if(SymbolType.isSByte(constantArrayFilled.getElementType())) { + } else if(SymbolType.SBYTE.equals(constantArrayFilled.getElementType())) { String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmSize, size, "0"); added.add(asmName); - } else if(SymbolType.isWord(constantArrayFilled.getElementType())) { + } else if(SymbolType.WORD.equals(constantArrayFilled.getElementType())) { String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0"); added.add(asmName); - } else if(SymbolType.isSWord(constantArrayFilled.getElementType())) { + } else if(SymbolType.SWORD.equals(constantArrayFilled.getElementType())) { String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0"); added.add(asmName); - } else if(SymbolType.isDWord(constantArrayFilled.getElementType())) { + } else if(SymbolType.DWORD.equals(constantArrayFilled.getElementType())) { String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(4L), Operators.MULTIPLY, arraySize), 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmSize, size, "0"); added.add(asmName); - } else if(SymbolType.isSDWord(constantArrayFilled.getElementType())) { + } else if(SymbolType.SDWORD.equals(constantArrayFilled.getElementType())) { String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(4L), Operators.MULTIPLY, arraySize), 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmSize, size, "0"); added.add(asmName); @@ -438,6 +435,11 @@ public class Pass4CodeGeneration { String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef); asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0"); added.add(asmName); + } else if(constantArrayFilled.getElementType() instanceof SymbolTypeStruct) { + SymbolTypeStruct structElementType = (SymbolTypeStruct) constantArrayFilled.getElementType(); + String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) structElementType.getSizeBytes()), Operators.MULTIPLY, arraySize), 99, scopeRef); + asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0"); + added.add(asmName); } else { throw new RuntimeException("Unhandled constant array element type " + constantArrayFilled.toString(program)); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java index 6e023bbb0..7e4f48ee0 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java @@ -18,12 +18,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base { LiveRangeEquivalenceClassSet equivalenceClassSet = getProgram().getLiveRangeEquivalenceClassSet(); List equivalenceClasses = new ArrayList<>(equivalenceClassSet.getEquivalenceClasses()); final VariableRegisterWeights registerWeights = getProgram().getVariableRegisterWeights(); - Collections.sort(equivalenceClasses, new Comparator() { - @Override - public int compare(LiveRangeEquivalenceClass o1, LiveRangeEquivalenceClass o2) { - return Double.compare(registerWeights.getTotalWeight(o2), registerWeights.getTotalWeight(o1)); - } - }); + Collections.sort(equivalenceClasses, (o1, o2) -> Double.compare(registerWeights.getTotalWeight(o2), registerWeights.getTotalWeight(o1))); Set unknownFragments = new LinkedHashSet<>(); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java index 157b04ca7..f181b9eb1 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java @@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.types.SymbolTypeStruct; import dk.camelot64.kickc.model.values.VariableRef; import dk.camelot64.kickc.model.symbols.ConstantVar; import dk.camelot64.kickc.model.symbols.Scope; @@ -195,23 +196,23 @@ public class Pass4RegistersFinalize extends Pass2Base { */ private Registers.Register allocateNewRegisterZp(Variable variable) { SymbolType varType = variable.getType(); - if(SymbolType.isByte(varType)) { + if(SymbolType.BYTE.equals(varType)) { return new Registers.RegisterZpByte(allocateZp((1))); - } else if(SymbolType.isSByte(varType)) { + } else if(SymbolType.SBYTE.equals(varType)) { return new Registers.RegisterZpByte(allocateZp(1)); - } else if(SymbolType.isWord(varType)) { + } else if(SymbolType.WORD.equals(varType)) { Registers.RegisterZpWord registerZpWord = new Registers.RegisterZpWord(allocateZp(2)); return registerZpWord; - } else if(SymbolType.isSWord(varType)) { + } else if(SymbolType.SWORD.equals(varType)) { Registers.RegisterZpWord registerZpWord = new Registers.RegisterZpWord(allocateZp(2)); return registerZpWord; - } else if(SymbolType.isDWord(varType)) { + } else if(SymbolType.DWORD.equals(varType)) { Registers.RegisterZpDWord registerZpDWord = new Registers.RegisterZpDWord(allocateZp(4)); return registerZpDWord; - } else if(SymbolType.isSDWord(varType)) { + } else if(SymbolType.SDWORD.equals(varType)) { Registers.RegisterZpDWord registerZpDWord = new Registers.RegisterZpDWord(allocateZp(4)); return registerZpDWord; @@ -224,6 +225,10 @@ public class Pass4RegistersFinalize extends Pass2Base { Registers.RegisterZpWord registerZpWord = new Registers.RegisterZpWord(allocateZp(2)); return registerZpWord; + } else if(varType instanceof SymbolTypeStruct) { + Registers.RegisterZpStruct registerZpStruct = + new Registers.RegisterZpStruct(allocateZp(varType.getSizeBytes())); + return registerZpStruct; } else { throw new RuntimeException("Unhandled variable type " + varType); } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddArrayNumberTypeConversions.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddArrayNumberTypeConversions.java new file mode 100644 index 000000000..fb3599b09 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddArrayNumberTypeConversions.java @@ -0,0 +1,63 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeArray; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.*; + +import java.util.ListIterator; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Add casts to {@link SymbolType#NUMBER} expressions that are inside array initializers based on the type of the array + */ +public class PassNAddArrayNumberTypeConversions extends Pass2SsaOptimization { + + public PassNAddArrayNumberTypeConversions(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + ProgramExpressionIterator.execute(getProgram(), (binaryExpression, currentStmt, stmtIt, currentBlock) -> { + if(binaryExpression instanceof ProgramExpressionBinary) { + ProgramExpressionBinary binary = (ProgramExpressionBinary) binaryExpression; + RValue left = binary.getLeft(); + RValue right = binary.getRight(); + SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); + if(leftType instanceof SymbolTypeArray && right instanceof ValueList) { + SymbolType declaredElmType = ((SymbolTypeArray) leftType).getElementType(); + ListIterator elmIterator = ((ValueList) right).getList().listIterator(); + while(elmIterator.hasNext()) { + RValue elm = elmIterator.next(); + SymbolType elmType = SymbolTypeInference.inferType(getProgram().getScope(), elm); + if(SymbolType.NUMBER.equals(elmType)) { + // Add a cast - if the value fits. + if(!SymbolTypeConversion.assignmentTypeMatch(declaredElmType, elmType)) { + throw new CompileError("Array type " + declaredElmType + " does not match element type " + elmType , currentStmt); + } + // TODO: Test if the value matches the declared type! + if(elm instanceof ConstantValue) { + elmIterator.set(new ConstantCastValue(declaredElmType, (ConstantValue) elm)); + } else { + elmIterator.set(new CastValue(declaredElmType, elm)); + } + modified.set(true); + } + } + if(modified.get()) { + getLog().append("Adding number conversion cast (" + declaredElmType+ ") to elements in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + } + } + } + }); + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java new file mode 100644 index 000000000..7f05fe4f3 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java @@ -0,0 +1,52 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.RValue; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Add casts to {@link SymbolType#NUMBER} expressions that meet a typed value in a binary expression (including assignment) + */ +public class PassNAddNumberTypeConversions extends Pass2SsaOptimization { + + public PassNAddNumberTypeConversions(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + ProgramExpressionIterator.execute(getProgram(), (binaryExpression, currentStmt, stmtIt, currentBlock) -> { + if(binaryExpression instanceof ProgramExpressionBinary) { + ProgramExpressionBinary binary = (ProgramExpressionBinary) binaryExpression; + RValue left = binary.getLeft(); + RValue right = binary.getRight(); + SymbolType castType = SymbolTypeConversion.getNumberCastType(left, right, getScope(), currentStmt); + if(castType != null) { + // Convert both left and right to the found type + SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); + if(SymbolType.NUMBER.equals(leftType)) { + getLog().append("Adding number conversion cast (" + castType + ") " + binary.getLeft().toString() + " in " + (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + binary.addLeftCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); + modified.set(true); + } + SymbolType rightType = SymbolTypeInference.inferType(getProgram().getScope(), right); + if(SymbolType.NUMBER.equals(rightType)) { + getLog().append("Adding number conversion cast (" + castType + ") " + binary.getRight().toString() + " in " + ((currentStmt==null)?"":currentStmt.toString(getProgram(), false))); + binary.addRightCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); + + modified.set(true); + } + } + } + }); + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java new file mode 100644 index 000000000..d34690762 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddTypeConversionAssignment.java @@ -0,0 +1,82 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.RValue; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Add a cast a variable is assigned something of a convertible type. + * Also allows pointers to be assigned integer values. + */ +public class PassNAddTypeConversionAssignment extends Pass2SsaOptimization { + + public PassNAddTypeConversionAssignment(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(programExpression instanceof ProgramExpressionBinary) { + ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression; + RValue left = binary.getLeft(); + RValue right = binary.getRight(); + SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); + SymbolType rightType = SymbolTypeInference.inferType(getProgram().getScope(), right); + + if(!SymbolTypeConversion.assignmentTypeMatch(leftType, rightType)) { + // Assigning a pointer from an unsigned word + if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryAssignmentLValue) { + if((leftType instanceof SymbolTypePointer) && SymbolType.isInteger(rightType)) { + getLog().append("Adding pointer type conversion cast (" + leftType + ") " + binary.getLeft().toString() + " in " + currentStmt.toString(getProgram(), false)); + binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope()); + modified.set(true); + } + + // Detect word literal constructor + if(SymbolType.WORD.equals(leftType) && isLiteralWordCandidate(rightType)) { + SymbolType conversionType = SymbolType.WORD; + getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope()); + modified.set(true); + } + // Detect word literal constructor + if(leftType instanceof SymbolTypePointer && isLiteralWordCandidate(rightType)) { + SymbolType conversionType = SymbolType.WORD; + getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope()); + modified.set(true); + } + + // Detect dword literal constructor + if(SymbolType.DWORD.equals(leftType) && isLiteralWordCandidate(rightType)) { + SymbolType conversionType = SymbolType.DWORD; + getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false))); + binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope()); + modified.set(true); + } + + } + } + } + }); + return modified.get(); + } + + public static boolean isLiteralWordCandidate(SymbolType rightType) { + if(rightType instanceof SymbolTypeArray) { + SymbolTypeArray rightArray = (SymbolTypeArray) rightType; + if(new ConstantInteger(2L, SymbolType.BYTE).equals(rightArray.getSize())) + if(SymbolType.isInteger(rightArray.getElementType())) + return true; + } + return false; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java b/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java index 810de150a..f020476a6 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNBlockSequencePlanner.java @@ -39,11 +39,25 @@ public class PassNBlockSequencePlanner extends Pass2SsaOptimization { if(block.getCallSuccessor() != null) { pushTodo(getGraph().getCallSuccessor(block)); } - if(block.getConditionalSuccessor() != null) { + ControlFlowBlock conditionalSuccessor = getGraph().getConditionalSuccessor(block); + ControlFlowBlock defaultSuccessor = getGraph().getDefaultSuccessor(block); + if(conditionalSuccessor != null && defaultSuccessor != null) { + // Both conditional and default successor + if(conditionalSuccessor.getDefaultSuccessor().equals(defaultSuccessor.getLabel())) { + // Best sequence is cond->default (resulting in better code locality) + pushTodo(defaultSuccessor); + pushTodo(getGraph().getConditionalSuccessor(block)); + } else { + // Best sequence is default->cond + pushTodo(getGraph().getConditionalSuccessor(block)); + pushTodo(defaultSuccessor); + } + } else if(conditionalSuccessor != null) { + // Only a conditional successor pushTodo(getGraph().getConditionalSuccessor(block)); - } - if(getGraph().getDefaultSuccessor(block) != null) { - pushTodo(getGraph().getDefaultSuccessor(block)); + } else if(defaultSuccessor != null) { + // Only a default successor + pushTodo(defaultSuccessor); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNCastSimplification.java b/src/main/java/dk/camelot64/kickc/passes/PassNCastSimplification.java new file mode 100644 index 000000000..743d7cfe1 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCastSimplification.java @@ -0,0 +1,70 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary; +import dk.camelot64.kickc.model.operators.OperatorCast; +import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.ConstantPointer; +import dk.camelot64.kickc.model.values.RValue; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Simplifies casts + * - Inlines casts of (number) constants + * - Removes unnecessary casts + */ +public class PassNCastSimplification extends Pass2SsaOptimization { + + public PassNCastSimplification(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean optimized = new AtomicBoolean(false); + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(programExpression.getOperator() instanceof OperatorCast) { + OperatorCast operatorCast = (OperatorCast) programExpression.getOperator(); + ProgramExpressionUnary unary = (ProgramExpressionUnary) programExpression; + SymbolType castType = operatorCast.getToType(); + SymbolType operandType = SymbolTypeInference.inferType(getScope(), ((ProgramExpressionUnary) programExpression).getOperand()); + RValue unaryOperand = unary.getOperand(); + if(!SymbolTypeConversion.assignmentCastNeeded(castType, operandType)) { + // Cast Not needed + programExpression.set(unaryOperand); + getLog().append("Simplifying constant integer cast " + unaryOperand.toString(getProgram())); + optimized.set(true); + } else if(unaryOperand instanceof ConstantInteger) { + ConstantInteger constantInteger = (ConstantInteger) unaryOperand; + if(SymbolType.NUMBER.equals(constantInteger.getType())) { + if(castType instanceof SymbolTypeIntegerFixed || SymbolType.UNUMBER.equals(castType) || SymbolType.SNUMBER.equals(castType)) { + ConstantInteger newConstInt = new ConstantInteger(constantInteger.getInteger(), castType); + programExpression.set(newConstInt); + getLog().append("Simplifying constant integer cast " + newConstInt.toString()); + optimized.set(true); + } else if(castType instanceof SymbolTypePointer) { + ConstantPointer newConstPointer = new ConstantPointer(constantInteger.getInteger(), ((SymbolTypePointer) castType).getElementType()); + programExpression.set(newConstPointer); + getLog().append("Simplifying constant pointer cast " + newConstPointer.toString()); + optimized.set(true); + } + } else if(castType instanceof SymbolTypeIntegerFixed) { + if(((SymbolTypeIntegerFixed) castType).contains(constantInteger.getValue())) { + // Cast type contains the value - cast not needed + ConstantInteger newConstInt = new ConstantInteger(constantInteger.getInteger(), castType); + programExpression.set(newConstInt); + getLog().append("Simplifying constant integer cast " + newConstInt.toString()); + optimized.set(true); + } + } + } + } + }); + return optimized.get(); + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2CullEmptyBlocks.java b/src/main/java/dk/camelot64/kickc/passes/PassNCullEmptyBlocks.java similarity index 97% rename from src/main/java/dk/camelot64/kickc/passes/Pass2CullEmptyBlocks.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCullEmptyBlocks.java index 679d87eb3..c9c067215 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2CullEmptyBlocks.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCullEmptyBlocks.java @@ -12,9 +12,9 @@ import java.util.List; import java.util.Map; /** Pass that culls empty control flow blocks from the program */ -public class Pass2CullEmptyBlocks extends Pass2SsaOptimization { +public class PassNCullEmptyBlocks extends Pass2SsaOptimization { - public Pass2CullEmptyBlocks(Program program) { + public PassNCullEmptyBlocks(Program program) { super(program); } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNFinalizeNumberTypeConversions.java b/src/main/java/dk/camelot64/kickc/passes/PassNFinalizeNumberTypeConversions.java new file mode 100644 index 000000000..b4f45b8f9 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNFinalizeNumberTypeConversions.java @@ -0,0 +1,78 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.InternalError; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.symbols.ConstantVar; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeConversion; +import dk.camelot64.kickc.model.values.*; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Finalize any constant integers to the smallest fixed size signed/unsigned type - if they have been resolved as snumber/unumber. + */ +public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization { + + public PassNFinalizeNumberTypeConversions(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { + if(programValue.get() instanceof ConstantInteger) { + ConstantInteger constantInteger = (ConstantInteger) programValue.get(); + if(SymbolType.UNUMBER.equals(constantInteger.getType())) { + SymbolType integerType = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantInteger, getScope()); + programValue.set(new ConstantInteger(constantInteger.getValue(), integerType)); + getLog().append("Finalized unsigned number type "+programValue.get().toString(getProgram())); + modified.set(true); + } else if(SymbolType.SNUMBER.equals(constantInteger.getType())) { + SymbolType integerType = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantInteger, getScope()); + programValue.set(new ConstantInteger(constantInteger.getValue(), integerType)); + getLog().append("Finalized signed number type "+programValue.get().toString(getProgram())); + modified.set(true); + } + } else if(programValue.get() instanceof ConstantCastValue) { + ConstantCastValue constantCastValue = (ConstantCastValue) programValue.get(); + SymbolType toType = constantCastValue.getToType(); + if(SymbolType.UNUMBER.equals(toType)) { + if(constantCastValue.getValue() instanceof ConstantRef) { + ConstantRef constRef = (ConstantRef) constantCastValue.getValue(); + ConstantVar constant = getScope().getConstant(constRef); + if(constant.isInferredType()) + constant.setTypeInferred(toType); + else + throw new InternalError("Cannot cast declared type!" + constant.toString()); + } else { + ConstantLiteral constantLiteral = constantCastValue.getValue().calculateLiteral(getProgram().getScope()); + SymbolType smallestUnsigned = SymbolTypeConversion.getSmallestUnsignedFixedIntegerType(constantLiteral, getScope()); + if(smallestUnsigned!=null) { + constantCastValue.setToType(smallestUnsigned); + } + } + } else if(SymbolType.SNUMBER.equals(toType)) { + if(constantCastValue.getValue() instanceof ConstantRef) { + ConstantRef constRef = (ConstantRef) constantCastValue.getValue(); + ConstantVar constant = getScope().getConstant(constRef); + if(constant.isInferredType()) + constant.setTypeInferred(toType); + else + throw new InternalError("Cannot cast declared type!" + constant.toString()); + } else { + ConstantLiteral constantLiteral = constantCastValue.getValue().calculateLiteral(getProgram().getScope()); + SymbolType smallestSigned = SymbolTypeConversion.getSmallestSignedFixedIntegerType(constantLiteral, getScope()); + if(smallestSigned!=null) { + constantCastValue.setToType(smallestSigned); + } + } + } + } + }); + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java new file mode 100644 index 000000000..6b01d695d --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyConstantZero.java @@ -0,0 +1,44 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.ConstantNotLiteral; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramValueIterator; +import dk.camelot64.kickc.model.values.*; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Simplify any constant expression evaluating to zero + */ +public class PassNSimplifyConstantZero extends Pass2SsaOptimization { + + public PassNSimplifyConstantZero(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + + ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { + Value value = programValue.get(); + if(value instanceof ConstantValue && !(value instanceof ConstantInteger) &&!(value instanceof ConstantRef)) { + ConstantLiteral literal; + try { + literal = ((ConstantValue) value).calculateLiteral(getProgram().getScope()); + } catch( ConstantNotLiteral e) { + return; + } + if(literal instanceof ConstantInteger) { + if(((ConstantInteger) literal).getInteger()==0L) { + getLog().append("Simplifying constant evaluating to zero "+value.toString(getProgram()) + " in "+(currentStmt==null?"":currentStmt.toString(getProgram(), false))); + programValue.set(new ConstantInteger(0L, ((ConstantInteger) literal).getType())); + modified.set(true); + } + } + } + }); + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java new file mode 100644 index 000000000..c59ea0bd1 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNSimplifyExpressionWithZero.java @@ -0,0 +1,58 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.operators.Operator; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.values.ConstantInteger; +import dk.camelot64.kickc.model.values.PointerDereferenceSimple; +import dk.camelot64.kickc.model.values.RValue; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Simplify any binary expression containing a zero value (if possible + */ +public class PassNSimplifyExpressionWithZero extends Pass2SsaOptimization { + + public PassNSimplifyExpressionWithZero(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(programExpression instanceof ProgramExpressionBinary) { + ProgramExpressionBinary binary = (ProgramExpressionBinary) programExpression; + RValue left = binary.getLeft(); + RValue right = binary.getRight(); + Operator operator = programExpression.getOperator(); + if(Operators.PLUS.equals(operator) || Operators.MINUS.equals(operator) || Operators.BOOL_OR.equals(operator) || Operators.BOOL_XOR.equals(operator)) { + if(left instanceof ConstantInteger && ((ConstantInteger) left).getInteger() == 0) { + getLog().append("Simplifying expression containing zero " + binary.getRight().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) { + programExpression.set(new PointerDereferenceSimple(binary.getRight())); + } else { + programExpression.set(binary.getRight()); + } + modified.set(true); + } else if(right instanceof ConstantInteger && ((ConstantInteger) right).getInteger() == 0) { + getLog().append("Simplifying expression containing zero " + binary.getLeft().toString()+ " in "+ (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + if(programExpression instanceof ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed) { + programExpression.set(new PointerDereferenceSimple(binary.getLeft())); + } else { + programExpression.set(binary.getLeft()); + } + modified.set(true); + } + } + } + }); + + return modified.get(); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNTypeIdSimplification.java b/src/main/java/dk/camelot64/kickc/passes/PassNTypeIdSimplification.java new file mode 100644 index 000000000..1e6b5ffd0 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNTypeIdSimplification.java @@ -0,0 +1,47 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator; +import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary; +import dk.camelot64.kickc.model.operators.OperatorTypeId; +import dk.camelot64.kickc.model.operators.Operators; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.values.ConstantRef; +import dk.camelot64.kickc.model.values.RValue; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Converts typeid() operators to constants + */ +public class PassNTypeIdSimplification extends Pass2SsaOptimization { + + public PassNTypeIdSimplification(Program program) { + super(program); + } + + @Override + public boolean step() { + AtomicBoolean modified = new AtomicBoolean(false); + ProgramExpressionIterator.execute(getProgram(), (programExpression, currentStmt, stmtIt, currentBlock) -> { + if(programExpression instanceof ProgramExpressionUnary) { + ProgramExpressionUnary unary = (ProgramExpressionUnary) programExpression; + if(Operators.TYPEID.equals(unary.getOperator())) { + RValue rValue = unary.getOperand(); + SymbolType symbolType = SymbolTypeInference.inferType(getScope(), rValue); + if(SymbolType.VAR.equals(symbolType) || SymbolType.NUMBER.equals(symbolType)) { + + } else { + getLog().append("Resolving typeid() " + currentStmt.toString(getProgram(), false)); + ConstantRef typeIDConstantVar = OperatorTypeId.getTypeIdConstantVar(getScope(), symbolType); + unary.set(typeIDConstantVar); + modified.set(true); + } + } + } + }); + + return modified.get(); + } +} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNTypeInference.java b/src/main/java/dk/camelot64/kickc/passes/PassNTypeInference.java new file mode 100644 index 000000000..39c586a4e --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassNTypeInference.java @@ -0,0 +1,136 @@ +package dk.camelot64.kickc.passes; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.*; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.symbols.ProgramScope; +import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.types.*; +import dk.camelot64.kickc.model.values.AssignmentRValue; +import dk.camelot64.kickc.model.values.LValue; +import dk.camelot64.kickc.model.values.RValue; +import dk.camelot64.kickc.model.values.VariableRef; + +/** + * Pass through the generated statements inferring types of unresolved variables. + */ +public class PassNTypeInference extends Pass2SsaOptimization { + + public PassNTypeInference(Program program) { + super(program); + } + + @Override + public boolean step() { + for(ControlFlowBlock block : getGraph().getAllBlocks()) { + for(Statement statement : block.getStatements()) { + try { + if(statement instanceof StatementLValue) { + updateInferedTypeLValue(getProgram(), (StatementLValue) statement); + } else if(statement instanceof StatementPhiBlock) { + for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) { + updateInferedTypePhiVariable(getProgram(), phiVariable); + } + } + } catch(CompileError e) { + throw new CompileError(e.getMessage(), statement.getSource()); + } + } + } + return false; + } + + static void updateInferedTypeLValue(Program program, StatementLValue statementLValue) { + if(statementLValue instanceof StatementAssignment) { + updateInferedTypeAssignmentLValue(program, (StatementAssignment) statementLValue); + } else if(statementLValue instanceof StatementCall) { + updateInferedTypeCallLValue(program, (StatementCall) statementLValue); + } else if(statementLValue instanceof StatementCallPointer) { + updateInferedTypeCallPointerLValue(program, (StatementCallPointer) statementLValue); + } else { + throw new RuntimeException("LValue statement not implemented " + statementLValue); + } + } + + + private static void updateInferedTypeCallLValue(Program program, StatementCall call) { + ProgramScope programScope = program.getScope(); + LValue lValue = call.getlValue(); + if(lValue instanceof VariableRef) { + Variable symbol = programScope.getVariable((VariableRef) lValue); + if(SymbolType.VAR.equals(symbol.getType()) || SymbolType.NUMBER.equals(symbol.getType())|| SymbolType.UNUMBER.equals(symbol.getType())|| SymbolType.SNUMBER.equals(symbol.getType())) { + Procedure procedure = programScope.getProcedure(call.getProcedure()); + SymbolType type = procedure.getReturnType(); + setInferedType(program, call, symbol, type); + } + } + } + + private static void updateInferedTypeCallPointerLValue(Program program, StatementCallPointer call) { + ProgramScope programScope = program.getScope(); + LValue lValue = call.getlValue(); + if(lValue instanceof VariableRef) { + Variable symbol = programScope.getVariable((VariableRef) lValue); + if(SymbolType.VAR.equals(symbol.getType()) || SymbolType.NUMBER.equals(symbol.getType())|| SymbolType.UNUMBER.equals(symbol.getType())|| SymbolType.SNUMBER.equals(symbol.getType())) { + SymbolType procedureType = SymbolTypeInference.inferType(programScope, call.getProcedure()); + if(procedureType instanceof SymbolTypeProcedure) { + SymbolType returnType = ((SymbolTypeProcedure) procedureType).getReturnType(); + setInferedType(program, call, symbol, returnType); + } + } + } + } + + private static void updateInferedTypePhiVariable(Program program, StatementPhiBlock.PhiVariable phiVariable) { + ProgramScope programScope = program.getScope(); + Variable symbol = programScope.getVariable(phiVariable.getVariable()); + if(SymbolType.VAR.equals(symbol.getType()) || SymbolType.NUMBER.equals(symbol.getType())|| SymbolType.UNUMBER.equals(symbol.getType())|| SymbolType.SNUMBER.equals(symbol.getType())) { + SymbolType type = null; + for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { + RValue rValue = phiRValue.getrValue(); + SymbolType valueType = SymbolTypeInference.inferType(programScope, rValue); + if(type == null) { + type = valueType; + } else if(!type.equals(valueType)) + if(valueType instanceof SymbolTypeInteger && type instanceof SymbolTypeInteger) { + type = SymbolTypeConversion.convertedMathType((SymbolTypeInteger) valueType, (SymbolTypeInteger) type); + } else { + throw new CompileError("Phi value has type mismatch " + phiRValue.toString() + " not matching type " + type.getTypeName()); + } + } + if(!SymbolType.VAR.equals(symbol.getType()) && !type.equals(symbol.getType())) { + program.getLog().append("Inferred type updated to " + type + " for " + symbol.toString(program)); + } + symbol.setTypeInferred(type); + } + } + + private static void updateInferedTypeAssignmentLValue(Program program, StatementAssignment assignment) { + ProgramScope programScope = program.getScope(); + LValue lValue = assignment.getlValue(); + if(lValue instanceof VariableRef) { + Variable symbol = programScope.getVariable((VariableRef) lValue); + if(SymbolType.VAR.equals(symbol.getType()) || SymbolType.NUMBER.equals(symbol.getType())|| SymbolType.UNUMBER.equals(symbol.getType()) || SymbolType.SNUMBER.equals(symbol.getType())) { + SymbolType type = SymbolTypeInference.inferType(programScope, new AssignmentRValue(assignment)); + setInferedType(program, assignment, symbol, type); + // If the type is an array or a string the symbol is constant + if(symbol.getType() instanceof SymbolTypeArray) { + symbol.setDeclaredConstant(true); + } else if(SymbolType.STRING.equals(symbol.getType())) { + symbol.setDeclaredConstant(true); + } + } + } + } + + private static void setInferedType(Program program, Statement statement, Variable symbol, SymbolType type) { + if(!SymbolType.VAR.equals(symbol.getType()) && !type.equals(symbol.getType())) { + program.getLog().append("Inferred type updated to " + type + " in " + statement.toString(program, false)); + } + symbol.setTypeInferred(type); + } + + +} diff --git a/src/main/kc/stdlib/stdlib.kc b/src/main/kc/stdlib/stdlib.kc new file mode 100644 index 000000000..bd6686a8f --- /dev/null +++ b/src/main/kc/stdlib/stdlib.kc @@ -0,0 +1,20 @@ +// Implementation of functions found int C stdlib.h / stdlib.c + +// Start of the heap used by malloc() +unsigned char* HEAP_START = 0xc000; + +// Head of the heap. Moved forward for each malloc() +unsigned char* heap_head = HEAP_START; + +// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. +// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values. +unsigned char* malloc(unsigned int size) { + unsigned char* mem = heap_head; + heap_head+= size; + return mem; +} + +// A block of memory previously allocated by a call to malloc is deallocated, making it available again for further allocations. +// If ptr is a null pointer, the function does nothing. +void free(unsigned char* ptr) { +} \ No newline at end of file diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index c9ac8c94e..aaf9d2264 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -32,6 +32,226 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testNoopCastElimination() throws IOException, URISyntaxException { + compileAndCompare("noop-cast-elimination"); + } + + @Test + public void testSignedWordMinusByte2() throws IOException, URISyntaxException { + compileAndCompare("signed-word-minus-byte-2"); + } + + @Test + public void testStruct5() throws IOException, URISyntaxException { + compileAndCompare("struct-5", log().verboseParse().verboseCreateSsa().verboseStatementSequence()); + } + + @Test + public void testStruct4() throws IOException, URISyntaxException { + compileAndCompare("struct-4", log().verboseParse().verboseCreateSsa().verboseStatementSequence()); + } + + @Test + public void testStruct3() throws IOException, URISyntaxException { + compileAndCompare("struct-3"); + } + + @Test + public void testStruct2() throws IOException, URISyntaxException { + compileAndCompare("struct-2"); + } + + @Test + public void testStruct1() throws IOException, URISyntaxException { + compileAndCompare("struct-1"); + } + + @Test + public void testStruct0() throws IOException, URISyntaxException { + compileAndCompare("struct-0"); + } + + @Test + public void testForTwoVars() throws IOException, URISyntaxException { + compileAndCompare("for-two-vars"); + } + + @Test + public void testC64DtvGfxExplorer() throws IOException, URISyntaxException { + compileAndCompare("c64dtv-gfxexplorer", 10); + } + + @Test + public void testC64DtvGfxModes() throws IOException, URISyntaxException { + compileAndCompare("c64dtv-gfxmodes", 10); + } + + @Test + public void testConstantStringConcat0() throws IOException, URISyntaxException { + compileAndCompare("constant-string-concat-0"); + } + + @Test + public void testLiterals() throws IOException, URISyntaxException { + compileAndCompare("literals"); + } + + @Test + public void testConstantStringConcat() throws IOException, URISyntaxException { + compileAndCompare("constant-string-concat"); + } + + @Test + public void testStatementSequence1() throws IOException, URISyntaxException { + compileAndCompare("statement-sequence-1"); + } + + @Test + public void testSubExprOptimize1() throws IOException, URISyntaxException { + compileAndCompare("subexpr-optimize-1"); + } + + @Test + public void testSubExprOptimize0() throws IOException, URISyntaxException { + compileAndCompare("subexpr-optimize-0"); + } + + @Test + public void testPtrPtrOptimize2() throws IOException, URISyntaxException { + compileAndCompare("ptrptr-optimize-2"); + } + + @Test + public void testPtrPtrOptimize1() throws IOException, URISyntaxException { + compileAndCompare("ptrptr-optimize-1"); + } + + @Test + public void testPtrPtrOptimize0() throws IOException, URISyntaxException { + compileAndCompare("ptrptr-optimize-0"); + } + + @Test + public void testHex2DecPtrPtr() throws IOException, URISyntaxException { + compileAndCompare("hex2dec-ptrptr"); + } + + @Test + public void testHex2Dec() throws IOException, URISyntaxException { + compileAndCompare("hex2dec"); + } + + @Test + public void testMemoryHeap() throws IOException, URISyntaxException { + compileAndCompare("memory-heap"); + } + + @Test + public void testTernaryInference() throws IOException, URISyntaxException { + compileAndCompare("ternary-inference"); + } + + @Test + public void testMul8uMin() throws IOException, URISyntaxException { + compileAndCompare("mul8u-min"); + } + + @Test + public void testNumberInferenceSum() throws IOException, URISyntaxException { + compileAndCompare("number-inference-sum"); + } + + @Test + public void testGfxBankOptimization() throws IOException, URISyntaxException { + compileAndCompare("gfxbank"); + } + + @Test + public void testDoubleIndexingArrays() throws IOException, URISyntaxException { + compileAndCompare("double-indexing-arrays"); + } + + @Test + public void testDerefidxWord2() throws IOException, URISyntaxException { + compileAndCompare("derefidx-word-2"); + } + + @Test + public void testDerefidxWord1() throws IOException, URISyntaxException { + compileAndCompare("derefidx-word-1"); + } + + @Test + public void testDerefidxWord0() throws IOException, URISyntaxException { + compileAndCompare("derefidx-word-0"); + } + + @Test + public void testFragmentVariations() throws IOException, URISyntaxException { + compileAndCompare("fragment-variations"); + } + + @Test + public void testTypeInference() throws IOException, URISyntaxException { + compileAndCompare("type-inference"); + } + + @Test + public void testMixedArray1() throws IOException, URISyntaxException { + compileAndCompare("mixed-array-1"); + } + + @Test + public void testMixedArray0() throws IOException, URISyntaxException { + compileAndCompare("mixed-array-0"); + } + + @Test + public void testInlinePointer2() throws IOException, URISyntaxException { + compileAndCompare("inline-pointer-2"); + } + + @Test + public void testInlinePointer1() throws IOException, URISyntaxException { + compileAndCompare("inline-pointer-1"); + } + + @Test + public void testInlinePointer0() throws IOException, URISyntaxException { + compileAndCompare("inline-pointer-0"); + } + + @Test + public void testToD018Problem() throws IOException, URISyntaxException { + compileAndCompare("tod018-problem"); + } + + @Test + public void testHelloWorld0() throws IOException, URISyntaxException { + compileAndCompare("helloworld0"); + } + + @Test + public void testNumberConversion() throws IOException, URISyntaxException { + compileAndCompare("number-conversion"); + } + + @Test + public void testNumberType() throws IOException, URISyntaxException { + compileAndCompare("number-type"); + } + + @Test + public void testIntegerConversion() throws IOException, URISyntaxException { + compileAndCompare("int-conversion"); + } + + @Test + public void testIntegerLiterals() throws IOException, URISyntaxException { + compileAndCompare("int-literals"); + } + @Test public void testSimpleLoop() throws IOException, URISyntaxException { compileAndCompare("simple-loop"); @@ -44,7 +264,7 @@ public class TestPrograms { @Test public void testPaulNelsenSandboxTernaryError() throws IOException, URISyntaxException { - compileAndCompare("sandbox-ternary-error", log().verboseParse().verboseCreateSsa().setVerboseSSAOptimize().verboseStatementSequence()); + compileAndCompare("sandbox-ternary-error"); } @Test @@ -52,21 +272,20 @@ public class TestPrograms { compileAndCompare("sandbox"); } - //@Test //public void testPointerCast3() throws IOException, URISyntaxException { // compileAndCompare("pointer-cast-3"); //} - //@Test - //public void testTypeIdPlusByteProblem() throws IOException, URISyntaxException { - // compileAndCompare("typeid-plus-byte-problem"); - //} + @Test + public void testTypeIdPlusByteProblem() throws IOException, URISyntaxException { + compileAndCompare("typeid-plus-byte-problem"); + } - //@Test - //public void testTypeIdPlusBytes() throws IOException, URISyntaxException { - // compileAndCompare("typeid-plus-bytes"); - //} + @Test + public void testTypeIdPlusBytes() throws IOException, URISyntaxException { + compileAndCompare("typeid-plus-bytes"); + } @Test public void testTypeIdSimple() throws IOException, URISyntaxException { @@ -78,6 +297,11 @@ public class TestPrograms { compileAndCompare("type-signed"); } + @Test + public void testConstIntCastProblem() throws IOException, URISyntaxException { + compileAndCompare("const-int-cast-problem"); + } + @Test public void testPointerPlus0() throws IOException, URISyntaxException { compileAndCompare("pointer-plus-0"); @@ -468,11 +692,6 @@ public class TestPrograms { compileAndCompare("irq-idx-problem"); } - @Test - public void testDoubleIndexingArrays() throws IOException, URISyntaxException { - compileAndCompare("double-indexing-arrays"); - } - @Test public void testInlineKickAsmClobber() throws IOException, URISyntaxException { compileAndCompare("inline-kasm-clobber"); @@ -994,11 +1213,6 @@ public class TestPrograms { compileAndCompare("assignment-chained"); } - @Test - public void testConcatChar() throws IOException, URISyntaxException { - compileAndCompare("concat-char"); - } - @Test public void testConstMultDiv() throws IOException, URISyntaxException { compileAndCompare("const-mult-div"); @@ -1109,6 +1323,11 @@ public class TestPrograms { compileAndCompare("c64dtv-blittermin"); } + @Test + public void testC64DtvBlitterBox() throws IOException, URISyntaxException { + compileAndCompare("c64dtv-blitter-box"); + } + @Test public void testC64Dtv8bppChunkyStretch() throws IOException, URISyntaxException { compileAndCompare("c64dtv-8bppchunkystretch"); @@ -1119,11 +1338,6 @@ public class TestPrograms { compileAndCompare("c64dtv-8bppcharstretch"); } - @Test - public void testC64DtvGfxExplorer() throws IOException, URISyntaxException { - compileAndCompare("c64dtv-gfxexplorer", 10); - } - @Test public void testInlineString2() throws IOException, URISyntaxException { compileAndCompare("inline-string-2"); @@ -1144,11 +1358,6 @@ public class TestPrograms { compileAndCompare("keyboard-glitch"); } - @Test - public void testC64DtvGfxModes() throws IOException, URISyntaxException { - compileAndCompare("c64dtv-gfxmodes", 10); - } - @Test public void testNoromCharset() throws IOException, URISyntaxException { compileAndCompare("norom-charset"); @@ -1294,11 +1503,6 @@ public class TestPrograms { compileAndCompare("arrays-init"); } - @Test - public void testConstantStringConcat() throws IOException, URISyntaxException { - compileAndCompare("constant-string-concat"); - } - @Test public void testTrueInlineWords() throws IOException, URISyntaxException { compileAndCompare("true-inline-words"); @@ -1324,6 +1528,21 @@ public class TestPrograms { compileAndCompare("inline-assignment"); } + @Test + public void testInlineWord0() throws IOException, URISyntaxException { + compileAndCompare("inline-word-0"); + } + + @Test + public void testInlineWord1() throws IOException, URISyntaxException { + compileAndCompare("inline-word-1"); + } + + @Test + public void testInlineWord2() throws IOException, URISyntaxException { + compileAndCompare("inline-word-2"); + } + @Test public void testInlineWord() throws IOException, URISyntaxException { compileAndCompare("inline-word"); @@ -1499,10 +1718,6 @@ public class TestPrograms { compileAndCompare("halfscii"); } - @Test - public void testLiterals() throws IOException, URISyntaxException { - compileAndCompare("literals"); - } @Test public void testScroll() throws IOException, URISyntaxException { @@ -1699,11 +1914,6 @@ public class TestPrograms { assertError("invalid-consttype", "Constant variable has a non-matching type", false); } - @Test - public void testValueListError() throws IOException, URISyntaxException { - assertError("valuelist-error", "Value list not resolved to word constructor"); - } - @Test public void testArrayUninitialized() throws IOException, URISyntaxException { assertError("array-uninitialized", "Array has no declared size."); @@ -1859,9 +2069,9 @@ public class TestPrograms { boolean success = true; ReferenceHelper helper = new ReferenceHelperFolder(refPath); success &= helper.testOutput(fileName, ".asm", program.getAsm().toString(false)); - success &= helper.testOutput(fileName, ".sym", program.getScope().getSymbolTableContents(program)); - success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program)); - success &= helper.testOutput(fileName, ".log", program.getLog().toString()); + //success &= helper.testOutput(fileName, ".sym", program.getScope().getSymbolTableContents(program)); + //success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program)); + //success &= helper.testOutput(fileName, ".log", program.getLog().toString()); if(!success) { //System.out.println("\nCOMPILE LOG"); //System.out.println(program.getLog().toString()); diff --git a/src/test/kc/bitwise-not.kc b/src/test/kc/bitwise-not.kc index 282da557c..1da5f5af6 100644 --- a/src/test/kc/bitwise-not.kc +++ b/src/test/kc/bitwise-not.kc @@ -1,7 +1,7 @@ void main() { byte* SCREEN = $400; - *SCREEN = ~1; + *SCREEN = ~1ub; for(byte c : 1..26) { SCREEN[c] = ~c; diff --git a/src/test/kc/c64dtv-blitter-box.kc b/src/test/kc/c64dtv-blitter-box.kc new file mode 100644 index 000000000..df9ab614f --- /dev/null +++ b/src/test/kc/c64dtv-blitter-box.kc @@ -0,0 +1,57 @@ +// Fill a box on the screen using the blitter + +import "c64dtv.kc" + +const byte* SCREEN = $400; +const byte[] SRCA = "camelot rules!"; +const byte[] SRCB = { $80 }; + +void main() { + + *DTV_FEATURE = DTV_FEATURE_ENABLE; + + // Instruct blitter not to continue previous blit + *DTV_BLITTER_CONTROL2 = DTV_BLIT_CLEAR_IRQ; + + *DTV_BLITTER_SRCA_LO = SRCA; + *DTV_BLITTER_SRCA_HI = 0; + *DTV_BLITTER_SRCA_MOD_LO = 0; + *DTV_BLITTER_SRCA_MOD_HI = 0; + *DTV_BLITTER_SRCA_LIN_LO = <$100uw; + *DTV_BLITTER_SRCA_LIN_HI = >$100uw; + *DTV_BLITTER_SRCA_STEP = 01; // Step 0.0 + + *DTV_BLITTER_SRCB_LO = SRCB; + *DTV_BLITTER_SRCB_HI = 0; + *DTV_BLITTER_SRCB_MOD_LO = 0; + *DTV_BLITTER_SRCB_MOD_HI = 0; + *DTV_BLITTER_SRCB_LIN_LO = <$100uw; + *DTV_BLITTER_SRCB_LIN_HI = >$100uw; + *DTV_BLITTER_SRCB_STEP = $00; // Step 0.0 + + *DTV_BLITTER_DEST_LO = SCREEN+40+5; + *DTV_BLITTER_DEST_HI = 0; + *DTV_BLITTER_DEST_MOD_LO = <21uw; + *DTV_BLITTER_DEST_MOD_HI = >21uw; + *DTV_BLITTER_DEST_LIN_LO = <19uw; + *DTV_BLITTER_DEST_LIN_HI = >19uw; + *DTV_BLITTER_DEST_STEP = $10; // Step 1.0 + + *DTV_BLITTER_LEN_LO = <20*10uw; + *DTV_BLITTER_LEN_HI = >20*10uw; + + *DTV_BLITTER_ALU = DTV_BLIT_ADD; + *DTV_BLITTER_TRANSPARANCY = DTV_BLIT_TRANSPARANCY_NONE; + + // Start blitter + *DTV_BLITTER_CONTROL = DTV_BLIT_FORCE_START | DTV_BLIT_SRCA_FWD | DTV_BLIT_SRCB_FWD| DTV_BLIT_DEST_FWD; + // Instruct blitter to continue at DEST and restart SRC A/B + *DTV_BLITTER_CONTROL2 = DTV_BLIT_DEST_CONT; + + // wait til blitter is ready + do {} while((*DTV_BLITTER_CONTROL2 & DTV_BLIT_STATUS_BUSY)!=0); + +} \ No newline at end of file diff --git a/src/test/kc/c64dtv-blittermin.kc b/src/test/kc/c64dtv-blittermin.kc index ee0002776..ffc43fa90 100644 --- a/src/test/kc/c64dtv-blittermin.kc +++ b/src/test/kc/c64dtv-blittermin.kc @@ -17,8 +17,8 @@ void main() { *DTV_BLITTER_SRCA_HI = 0; *DTV_BLITTER_SRCA_MOD_LO = 0; *DTV_BLITTER_SRCA_MOD_HI = 0; - *DTV_BLITTER_SRCA_LIN_LO = <$100; - *DTV_BLITTER_SRCA_LIN_HI = >$100; + *DTV_BLITTER_SRCA_LIN_LO = <$100uw; + *DTV_BLITTER_SRCA_LIN_HI = >$100uw; *DTV_BLITTER_SRCA_STEP = $10; // Step 1.0 *DTV_BLITTER_SRCB_LO = $100; + *DTV_BLITTER_SRCB_LIN_LO = <$100uw; + *DTV_BLITTER_SRCB_LIN_HI = >$100uw; *DTV_BLITTER_SRCB_STEP = $00; // Step 0.0 *DTV_BLITTER_DEST_LO = $100; + *DTV_BLITTER_DEST_LIN_LO = <$100uw; + *DTV_BLITTER_DEST_LIN_HI = >$100uw; *DTV_BLITTER_DEST_STEP = $10; // Step 1.0 *DTV_BLITTER_LEN_LO = SRCA_LEN; diff --git a/src/test/kc/c64dtv-gfxexplorer.kc b/src/test/kc/c64dtv-gfxexplorer.kc index 0eba729d9..6c35edfb6 100644 --- a/src/test/kc/c64dtv-gfxexplorer.kc +++ b/src/test/kc/c64dtv-gfxexplorer.kc @@ -115,40 +115,40 @@ const byte* FORM_SCREEN = $0400; const byte* FORM_CHARSET = $1800; // Charset ROM byte[] FORM_TEXT = - " C64 DTV Graphics Mode Explorer @"z + - " @"z + - " PRESET 0 Standard Charset @"z + - " @"z + - " CONTROL PLANE A VIC II @"z + - " bmm 0 pattern p0 screen s0 @"z + - " mcm 0 start 00 gfx g0 @"z + - " ecm 0 step 00 colors c0 @"z + - " hicolor 0 modulo 00 @"z + - " linear 0 COLORS @"z + - " color off 0 PLANE B palet 0 @"z + - " chunky 0 pattern p0 bgcol0 00 @"z + - " border off 0 start 00 bgcol1 00 @"z + - " overscan 0 step 00 bgcol2 00 @"z + - " modulo 00 bgcol3 00 @"z + - "@"z ; + " C64 DTV Graphics Mode Explorer @" + " @" + " PRESET 0 Standard Charset @" + " @" + " CONTROL PLANE A VIC II @" + " bmm 0 pattern p0 screen s0 @" + " mcm 0 start 00 gfx g0 @" + " ecm 0 step 00 colors c0 @" + " hicolor 0 modulo 00 @" + " linear 0 COLORS @" + " color off 0 PLANE B palet 0 @" + " chunky 0 pattern p0 bgcol0 00 @" + " border off 0 start 00 bgcol1 00 @" + " overscan 0 step 00 bgcol2 00 @" + " modulo 00 bgcol3 00 @" + ; byte[] FORM_COLS = - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@"z + - " @"z + - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@"z + - " @"z + - " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"z + - " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"z + - " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"z + - " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @"z + - " nnnnnnnnnnnn mmmmmmmmmm @"z + - " nnnnnnnnnnnn jjjjjjjjj @"z + - " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"z + - " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"z + - " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"z + - " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"z + - " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"z + - " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @"z + - "@"z ; + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@" + " @" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@" + " @" + " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @" + " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @" + " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @" + " nnnnnnnnnnnn mmmmmmmmmm ooooooooo @" + " nnnnnnnnnnnn mmmmmmmmmm @" + " nnnnnnnnnnnn jjjjjjjjj @" + " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @" + " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @" + " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @" + " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @" + " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @" + " nnnnnnnnnnnn mmmmmmmmmm jjjjjjjjj @" + ; // Number of form fields byte form_fields_cnt = 36; diff --git a/src/test/kc/c64dtv-gfxmodes.kc b/src/test/kc/c64dtv-gfxmodes.kc index 79a3bd30c..87dcd7a88 100644 --- a/src/test/kc/c64dtv-gfxmodes.kc +++ b/src/test/kc/c64dtv-gfxmodes.kc @@ -18,27 +18,28 @@ void main() { } byte[] MENU_TEXT = - "C64DTV Graphics Modes CCLHBME@"z + - " OHIIMCC@"z + - " LUNCMMM@"z + - "----------------------------------------@"z + - "1. Standard Char (V) 0000000@"z + - "2. Extended Color Char (V) 0000001@"z + - "3. Multicolor Char (V) 0000010@"z + - "4. Standard Bitmap (V) 0000100@"z + - "5. Multicolor Bitmap (V) 0000110@"z + - "6. High Color Standard Char (H) 0001000@"z + - "7. High Extended Color Char (H) 0001001@"z + - "8. High Multicolor Char (H) 0001010@"z + - "9. High Multicolor Bitmap (H) 0001110@"z + - "a. Sixs Fred 2 (D) 0010111@"z + - "b. Two Plane Bitmap (D) 0011101@"z + - "c. Sixs Fred (2 Plane MC BM) (D) 0011111@"z + - "d. 8bpp Pixel Cell (D) 0111011@"z + - "e. Chunky 8bpp Bitmap (D) 1111011@"z + - "----------------------------------------@"z + - " (V) vicII (H) vicII+hicol (D) c64dtv@"z + - "@"z ; + "C64DTV Graphics Modes CCLHBME@" + " OHIIMCC@" + " LUNCMMM@" + "----------------------------------------@" + "1. Standard Char (V) 0000000@" + "2. Extended Color Char (V) 0000001@" + "3. Multicolor Char (V) 0000010@" + "4. Standard Bitmap (V) 0000100@" + "5. Multicolor Bitmap (V) 0000110@" + "6. High Color Standard Char (H) 0001000@" + "7. High Extended Color Char (H) 0001001@" + "8. High Multicolor Char (H) 0001010@" + "9. High Multicolor Bitmap (H) 0001110@" + "a. Sixs Fred 2 (D) 0010111@" + "b. Two Plane Bitmap (D) 0011101@" + "c. Sixs Fred (2 Plane MC BM) (D) 0011111@" + "d. 8bpp Pixel Cell (D) 0111011@" + "e. Chunky 8bpp Bitmap (D) 1111011@" + "----------------------------------------@" + " (V) vicII (H) vicII+hicol (D) c64dtv@" + ; + void menu() { const byte* SCREEN = $8000; diff --git a/src/test/kc/concat-char.kc b/src/test/kc/concat-char.kc deleted file mode 100644 index c51f6ae5c..000000000 --- a/src/test/kc/concat-char.kc +++ /dev/null @@ -1,10 +0,0 @@ -// Concatenate a char to a string - -void main() { - byte* screen = $400; - byte l = 'l'; - byte[] msg = "cm"z+l; - for( byte i: 0..2 ) { - screen[i] = msg[i]; - } -} \ No newline at end of file diff --git a/src/test/kc/const-int-cast-problem.kc b/src/test/kc/const-int-cast-problem.kc new file mode 100644 index 000000000..01a8dea74 --- /dev/null +++ b/src/test/kc/const-int-cast-problem.kc @@ -0,0 +1,8 @@ +// Test a problem with converting casted constant numbers to fixed type constant integers +const byte* SCREEN = $0400; + +void main() { + for( byte i: 121..122) { + SCREEN[i] = i>>4; + } +} diff --git a/src/test/kc/constant-string-concat-0.kc b/src/test/kc/constant-string-concat-0.kc new file mode 100644 index 000000000..f3b35771b --- /dev/null +++ b/src/test/kc/constant-string-concat-0.kc @@ -0,0 +1,8 @@ +// Concatenates string constants in different ways +void main() { + byte[] msg = "camel" "ot"; + byte* SCREEN = 0x0400; + for( byte i=0;msg[i]!=0;i++) { + SCREEN[i] = msg[i]; + } +} \ No newline at end of file diff --git a/src/test/kc/constant-string-concat.kc b/src/test/kc/constant-string-concat.kc index 218825e62..0acbe2a1a 100644 --- a/src/test/kc/constant-string-concat.kc +++ b/src/test/kc/constant-string-concat.kc @@ -1,13 +1,10 @@ // Concatenates string constants in different ways void main() { - byte[] s = "e"z+"l"z; - byte[] s2 = s+'o'; - byte[] s3 = "cam"z+s2; - byte e = '!'; - byte[] s4 = ""z+'t'+ e; - byte[] s5 = s3+s4; + byte[] s = "c" + "ame" + "lot"; byte* SCREEN = $400; for( byte i: 0..7) { - SCREEN[i] = s5[i]; + SCREEN[i] = s[i]; } } \ No newline at end of file diff --git a/src/test/kc/derefidx-word-0.kc b/src/test/kc/derefidx-word-0.kc new file mode 100644 index 000000000..7b5117853 --- /dev/null +++ b/src/test/kc/derefidx-word-0.kc @@ -0,0 +1,10 @@ +// Tests that array-indexing by a word variable is turned into pointer addition + +void main() { + const byte* screen = 0x0400; + for( word i=0;i<1000;i+=40) { + screen[i] = 'a'; + } + +} + diff --git a/src/test/kc/derefidx-word-1.kc b/src/test/kc/derefidx-word-1.kc new file mode 100644 index 000000000..5124674fa --- /dev/null +++ b/src/test/kc/derefidx-word-1.kc @@ -0,0 +1,7 @@ +// Tests that array-indexing by a constant word is turned into a constant pointer + +void main() { + const byte* screen = 0x0400; + screen[40*10] = 'a'; +} + diff --git a/src/test/kc/derefidx-word-2.kc b/src/test/kc/derefidx-word-2.kc new file mode 100644 index 000000000..af8417918 --- /dev/null +++ b/src/test/kc/derefidx-word-2.kc @@ -0,0 +1,9 @@ +// Tests that array-indexing by a word variable that is a sum of a constant word and a byte is turned back into derefidx + +void main() { + const byte* screen = 0x0400; + for( byte i : 0..39) { + screen[40*10+i] = 'a'; + } +} + diff --git a/src/test/kc/examples/sinsprites/sinus-sprites.kc b/src/test/kc/examples/sinsprites/sinus-sprites.kc index d27f76bb9..a81055760 100644 --- a/src/test/kc/examples/sinsprites/sinus-sprites.kc +++ b/src/test/kc/examples/sinsprites/sinus-sprites.kc @@ -104,7 +104,7 @@ void place_sprites() { *SPRITES_EXPAND_X = %01111111; *SPRITES_EXPAND_Y = %01111111; byte* sprites_ptr = SCREEN+$3f8; - byte spr_id = (byte)(sprites/$40); + byte spr_id = (byte)((word)sprites/$40); byte spr_x = 60; byte j2 = 0; byte col = $5; diff --git a/src/test/kc/for-two-vars.kc b/src/test/kc/for-two-vars.kc new file mode 100644 index 000000000..10cf1e510 --- /dev/null +++ b/src/test/kc/for-two-vars.kc @@ -0,0 +1,9 @@ +// Test a for-loop with two iterating variables +// Illustrates that for()-loops currently cannot contain two variable declarations. + +void main() { + const byte* SCREEN = 0x400; + byte *sc=SCREEN+39; + for( byte i=0; i<40; i++, sc--) + *sc = i; +} diff --git a/src/test/kc/fragment-variations.kc b/src/test/kc/fragment-variations.kc new file mode 100644 index 000000000..ded7edfd4 --- /dev/null +++ b/src/test/kc/fragment-variations.kc @@ -0,0 +1,16 @@ +// Tests that ASM fragment variations works +// ASM fragment variations "cast" constants to different types + +void main() { + dword* screen = 0x400; + word w = 10; + screen[0] = mul16u(w, w); + w = 1000; + screen[1] = mul16u(w, w); +} + +dword mul16u(word b, word a) { + dword mb = b; + return mb+a; +} + diff --git a/src/test/kc/gfxbank.kc b/src/test/kc/gfxbank.kc new file mode 100644 index 000000000..990aaa585 --- /dev/null +++ b/src/test/kc/gfxbank.kc @@ -0,0 +1,8 @@ +// Test minimization of constants + +import "c64" + +void main() { + const byte* PLAYFIELD_CHARSET = $2800; + vicSelectGfxBank(PLAYFIELD_CHARSET); +} diff --git a/src/test/kc/helloworld0.kc b/src/test/kc/helloworld0.kc new file mode 100644 index 000000000..b3136af56 --- /dev/null +++ b/src/test/kc/helloworld0.kc @@ -0,0 +1,8 @@ +// Tests minimal hello world + +byte[] msg = "hello world!"; +byte* SCREEN = 0x0400; + +void main() { + for( byte i: 0..11) SCREEN[i] = msg[i]; +} \ No newline at end of file diff --git a/src/test/kc/hex2dec-ptrptr.kc b/src/test/kc/hex2dec-ptrptr.kc new file mode 100644 index 000000000..18665be48 --- /dev/null +++ b/src/test/kc/hex2dec-ptrptr.kc @@ -0,0 +1,38 @@ +// Testing binary to hex conversion using pointer to pointer + +void main() { + cls(); + unsigned char *screen = 0x0400; + utoa16w(00000, screen); screen += 40; + utoa16w(01234, screen); screen += 40; + utoa16w(05678, screen); screen += 40; + utoa16w(09999, screen); screen += 40; + utoa16w(58888, screen); +} + +void cls() { + unsigned char *screen = 0x0400; + for( unsigned char *sc: screen..screen+999) *sc=' '; +} + +// Digits used for utoa() +unsigned char[] DIGITS = "0123456789abcdef"; + +// Hexadecimal utoa() for an unsigned int (16bits) +void utoa16w(unsigned int value, unsigned char* dst) { + unsigned char started = 0; + started = utoa16n((>value)>>4, &dst, started); + started = utoa16n((>value)&0x0f, &dst, started); + started = utoa16n((>4, &dst, started); + utoa16n((>1); + } while (rst!=0x30); + unsigned char *screen = 0x0400; + *bordercol = 1; + unsigned char time_start = *raster; + utoa16w(00000, screen); (*bordercol)++; screen += 40; + utoa16w(01234, screen); (*bordercol)++; screen += 40; + utoa16w(05678, screen); (*bordercol)++; screen += 40; + utoa16w(09999, screen); (*bordercol)++; screen += 40; + utoa16w(58888, screen); + unsigned char time_end = *raster; + *bordercol = 0; + unsigned char time = time_end - time_start; + utoa10w((unsigned int)time, screen+80); + byte[] msg = "raster lines"; + for( byte i=0; msg[i]!=0; i++ ) (screen+80+3)[i] = msg[i]; + //for( byte* m="lines", s=screen+80+6 ;*m!=0;m++,s++) *s = *m; + } + +} + +void cls() { + unsigned char *screen = 0x0400; + for( unsigned char *sc: screen..screen+999) *sc=' '; +} + +const unsigned char RADIX_BINARY = 2; +const unsigned char RADIX_OCTAL = 8; +const unsigned char RADIX_DECIMAL = 10; +const unsigned char RADIX_HEX = 16; + +// Digits used for utoa() +unsigned char[] DIGITS = "0123456789abcdef"; + +// Subtraction values used for decimal utoa() +unsigned int[] UTOA10_SUB = { 30000, 10000, 3000, 1000, 300, 100, 30, 10 }; +// Digit addition values used for decimal utoa() +unsigned char[] UTOA10_VAL = { 3, 1, 3, 1, 3, 1, 3, 1 }; + +// Decimal utoa() without using multiply or divide +void utoa10w(unsigned int value, unsigned char* dst) { + unsigned char bStarted = 0; + unsigned char digit = 0; + for( unsigned char i: 0..7) { + while(value>=UTOA10_SUB[i]) { digit += UTOA10_VAL[i]; value -= UTOA10_SUB[i]; bStarted = 1; } + if((i&1)!=0) { + if(bStarted!=0) { + *dst++ = DIGITS[digit]; + } + digit = 0; + } + } + *dst++ = DIGITS[(unsigned char) value]; + *dst = 0; +} + +// Hexadecimal utoa() for an unsigned int (16bits) +void utoa16w(unsigned int value, unsigned char* dst) { + unsigned char started = 0; + started = utoa16n((>value)>>4, &dst, started); + started = utoa16n((>value)&0x0f, &dst, started); + started = utoa16n((>4, &dst, started); + utoa16n((255) *bgcol = RED; + +} \ No newline at end of file diff --git a/src/test/kc/number-type.kc b/src/test/kc/number-type.kc new file mode 100644 index 000000000..74f270661 --- /dev/null +++ b/src/test/kc/number-type.kc @@ -0,0 +1,44 @@ +// Tests the number type used for constant expressions + + +void main() { + testBytes(); + testSBytes(); +} + +void testBytes() { + // Constant values resolvable to bytes + const byte* SCREEN = 0x0400; + byte idx = 0; + SCREEN[idx++] = 12; + SCREEN[idx++] = 6+6; + SCREEN[idx++] = 18-6; + SCREEN[idx++] = 1812-1800; + SCREEN[idx++] = 1+2+3+6; + SCREEN[idx++] = 2*6; + SCREEN[idx++] = 3<<2; + SCREEN[idx++] = 24>>1; + SCREEN[idx++] = 15&28; + SCREEN[idx++] = 4|8; + SCREEN[idx++] = 5^9; + SCREEN[idx++] = (2+2)*(15/5); + SCREEN[idx++] = (byte)(4096+12); +} + +void testSBytes() { + // Constant values resolvable to signed bytes + const signed byte* SCREEN = 0x0428; + byte idx = 0; + SCREEN[idx++] = -12; + SCREEN[idx++] = -6-6; + SCREEN[idx++] = -18+6; + SCREEN[idx++] = -1812+1800; + SCREEN[idx++] = -1-2-3-6; + SCREEN[idx++] = -2*6; + SCREEN[idx++] = -3<<2; + SCREEN[idx++] = -24>>1; + SCREEN[idx++] = -4&-9; + SCREEN[idx++] = -0x10|-0xfc; + SCREEN[idx++] = (-2-2)*(15/5); + SCREEN[idx++] = (signed byte)(4096-12); +} diff --git a/src/test/kc/ptrptr-optimize-0.kc b/src/test/kc/ptrptr-optimize-0.kc new file mode 100644 index 000000000..c615190e5 --- /dev/null +++ b/src/test/kc/ptrptr-optimize-0.kc @@ -0,0 +1,8 @@ +// Tests optimization of constant pointers to pointers +void main() { + byte* screen = 0x400; + byte** pscreen = &screen; + **pscreen = 'a'; + (*pscreen)++; + **pscreen = 'b'; +} \ No newline at end of file diff --git a/src/test/kc/ptrptr-optimize-1.kc b/src/test/kc/ptrptr-optimize-1.kc new file mode 100644 index 000000000..5e78562a3 --- /dev/null +++ b/src/test/kc/ptrptr-optimize-1.kc @@ -0,0 +1,11 @@ +// Tests optimization of constant pointers to pointers +void main() { + byte* screen = 0x400; + byte** pscreen = &screen; + sub('a',pscreen); + sub('b',pscreen); +} + +void sub(unsigned char ch, unsigned char **dst) { + *(*dst)++ = ch; +} diff --git a/src/test/kc/ptrptr-optimize-2.kc b/src/test/kc/ptrptr-optimize-2.kc new file mode 100644 index 000000000..5b76ac29e --- /dev/null +++ b/src/test/kc/ptrptr-optimize-2.kc @@ -0,0 +1,11 @@ +// Tests (non-)optimization of constant pointers to pointers +// The two examples of &screen is not detected as identical leading to ASM that could be optimized more +void main() { + byte* screen = 0x400; + sub('a',&screen); + sub('b',&screen); +} + +void sub(unsigned char ch, unsigned char **dst) { + *(*dst)++ = ch; +} diff --git a/src/test/kc/sandbox.kc b/src/test/kc/sandbox.kc index 403776835..d84bb18f5 100644 --- a/src/test/kc/sandbox.kc +++ b/src/test/kc/sandbox.kc @@ -47,9 +47,11 @@ byte myprintf(byte *dst, byte *str, word w1, word w2, word w3) { for (digit = 0; digit < b; ++digit) dst[bLen++] = buf6[digit]; if (bTrailing != 0 && bDigits > b) for (; bDigits > b; --bDigits) dst[bLen++] = ' '; } else if (b == 'x' || b == 'X'){ // hex - b = (w >> 4) & 0xF; - dst[bLen++] = (b < 10 ? '0' : 0x57) + b; // "('a' - 10)" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/184 [FIXED] - b = w & 0xF; dst[bLen++] = (b < 10 ? '0' : 0x57) + b; + b = ((byte)w >> 4) & 0xF; + dst[bLen++] = (b < 10 ? '0' : 0x57) + b; + // "('a' - 10)" is the normal way -- not supported -- https://gitlab.com/camelot/kickc/issues/184 [FIXED] + // (b < 10 ? '0' : 0x57) not supported + b = (byte)w & 0xF; dst[bLen++] = (b < 10 ? '0' : 0x57) + b; } bFormat = 0; continue; diff --git a/src/test/kc/signed-word-minus-byte-2.kc b/src/test/kc/signed-word-minus-byte-2.kc new file mode 100644 index 000000000..e35709acd --- /dev/null +++ b/src/test/kc/signed-word-minus-byte-2.kc @@ -0,0 +1,12 @@ +// Tests subtracting bytes from signed words + +void main() { + signed word w1 = 1234; + signed word* screen = 0x0400; + for( byte i: 0..10 ) { + w1 = w1 - 41; + screen[i] = w1; + } + + +} \ No newline at end of file diff --git a/src/test/kc/sizeof-expr.kc b/src/test/kc/sizeof-expr.kc index d48116db5..adc8538ac 100644 --- a/src/test/kc/sizeof-expr.kc +++ b/src/test/kc/sizeof-expr.kc @@ -19,7 +19,7 @@ void main() { byte[] bc = { 1, 2, 3, 4 }; // Strings byte[] sa = "camelot"; - byte[] sb = "cml"+" "+"rules"; + //byte[] sb = { 'a', 'b', 'c', 0}; SCREEN[idx++] = '0'+sizeof(0); SCREEN[idx++] = '0'+sizeof(idx); @@ -37,6 +37,6 @@ void main() { SCREEN[idx++] = '0'+sizeof(bb); SCREEN[idx++] = '0'+sizeof(bc); SCREEN[idx++] = '0'+sizeof(sa); - SCREEN[idx++] = '0'+sizeof(sb); + //SCREEN[idx++] = '0'+sizeof(sb); } \ No newline at end of file diff --git a/src/test/kc/statement-sequence-1.kc b/src/test/kc/statement-sequence-1.kc new file mode 100644 index 000000000..396b7b3cf --- /dev/null +++ b/src/test/kc/statement-sequence-1.kc @@ -0,0 +1,15 @@ +// Tests statement sequence generation + +void main() { + + const byte* SCREEN = 0x0400; + + for(byte i: 0..10) { + byte c = i+5; + if((i&1)==0 || i>5) + c++; + SCREEN[i] = c; + } + + +} diff --git a/src/test/kc/struct-0.kc b/src/test/kc/struct-0.kc new file mode 100644 index 000000000..fd81f7594 --- /dev/null +++ b/src/test/kc/struct-0.kc @@ -0,0 +1,14 @@ +// Minimal struct - declaration, instantiation and usage + +struct Point { + byte x; + byte y; +} point; + +void main() { + point.x = 2; + point.y = 3; + const byte* SCREEN = 0x0400; + SCREEN[0] = point.x; + SCREEN[1] = point.y; +} \ No newline at end of file diff --git a/src/test/kc/struct-1.kc b/src/test/kc/struct-1.kc new file mode 100644 index 000000000..ddbd4a942 --- /dev/null +++ b/src/test/kc/struct-1.kc @@ -0,0 +1,18 @@ +// Minimal struct - two instances being used. + +struct Point { + byte x; + byte y; +}; + +struct Point point1, point2; + +void main() { + point1.x = 2; + point1.y = 3; + point2.x = point1.y; + point2.y = point1.x; + const byte* SCREEN = 0x0400; + SCREEN[0] = point2.x; + SCREEN[1] = point2.y; +} \ No newline at end of file diff --git a/src/test/kc/struct-2.kc b/src/test/kc/struct-2.kc new file mode 100644 index 000000000..a52a169db --- /dev/null +++ b/src/test/kc/struct-2.kc @@ -0,0 +1,20 @@ +// Minimal struct - different instances and copying + +struct Point { + byte x; + byte y; +}; + +struct Point point1, point2; + +void main() { + point1.x = 2; + point1.y = 3; + point2 = point1; + point2.x = 4; + const byte* SCREEN = 0x0400; + SCREEN[0] = point1.x; + SCREEN[1] = point1.y; + SCREEN[2] = point2.x; + SCREEN[3] = point2.y; +} \ No newline at end of file diff --git a/src/test/kc/struct-3.kc b/src/test/kc/struct-3.kc new file mode 100644 index 000000000..d6d25f7df --- /dev/null +++ b/src/test/kc/struct-3.kc @@ -0,0 +1,20 @@ +// Minimal struct - array of struct + +struct Point { + byte x; + byte y; +}; + +struct Point[4] points; + +void main() { + for( byte i: 0..4) { + points[i].x = i; + points[i].y = i+1; + } + const byte* SCREEN = 0x0400; + for( byte i: 0..4) { + SCREEN[i] = points[i].x; + (SCREEN+40)[i] = points[i].y; + } +} \ No newline at end of file diff --git a/src/test/kc/struct-4.kc b/src/test/kc/struct-4.kc new file mode 100644 index 000000000..504bb7265 --- /dev/null +++ b/src/test/kc/struct-4.kc @@ -0,0 +1,24 @@ +// Minimal struct - array of struct - near pointer math indexing + +struct Point { + byte x; + byte y; +}; + +struct Point[4] points; + +const byte SIZEOF_POINT = 2; +const byte OFFS_X = 0; +const byte OFFS_Y = 1; + +void main() { + for( byte i: 0..3) { + *((byte*)points+OFFS_X+i*SIZEOF_POINT) = i; // points[i].x = i; + *((byte*)points+OFFS_Y+i*SIZEOF_POINT) = i+4; // points[i].y = i+4; + } + const byte* SCREEN = 0x0400; + for( byte i: 0..3) { + SCREEN[i] = *((byte*)points+OFFS_X+i*SIZEOF_POINT); // SCREEN[i] = points[i].x; + (SCREEN+40)[i] = *((byte*)points+OFFS_Y+i*SIZEOF_POINT); // (SCREEN+40)[i] = points[i].y; + } +} \ No newline at end of file diff --git a/src/test/kc/struct-5.kc b/src/test/kc/struct-5.kc new file mode 100644 index 000000000..1d2cf6cd5 --- /dev/null +++ b/src/test/kc/struct-5.kc @@ -0,0 +1,26 @@ +// Minimal struct - array of struct - far pointer math indexing + +struct Point { + byte x; + byte y; +}; + +struct Point[4] points; + +const byte SIZEOF_POINT = 2; +const byte OFFS_X = 0; +const byte OFFS_Y = 1; + +void main() { + for( byte i: 0..3) { + struct Point* point_i = points+i; + *((byte*)point_i+OFFS_X) = i; // points[i].x = i; + *((byte*)point_i+OFFS_Y) = i+4; // points[i].y = i+4; + } + const byte* SCREEN = 0x0400; + for( byte i: 0..3) { + struct Point* point_i = points+i; + SCREEN[i] = *((byte*)point_i+OFFS_X); // SCREEN[i] = points[i].x; + (SCREEN+40)[i] = *((byte*)point_i+OFFS_Y); // (SCREEN+40)[i] = points[i].y; + } +} \ No newline at end of file diff --git a/src/test/kc/subexpr-optimize-0.kc b/src/test/kc/subexpr-optimize-0.kc new file mode 100644 index 000000000..78ec0430f --- /dev/null +++ b/src/test/kc/subexpr-optimize-0.kc @@ -0,0 +1,10 @@ +// Tests (non-)optimization of identical sub-expressions +// The two examples of i+1 is not detected as identical leading to ASM that could be optimized more +void main() { + byte* screen = 0x400; + for( byte i: 0..2) { + *screen++ = i*2; + *screen++ = i*2; + } +} + diff --git a/src/test/kc/subexpr-optimize-1.kc b/src/test/kc/subexpr-optimize-1.kc new file mode 100644 index 000000000..4fdabcfce --- /dev/null +++ b/src/test/kc/subexpr-optimize-1.kc @@ -0,0 +1,12 @@ +// A sub-expression that should not be optimized (+1 to a pointer) + +void main() { + byte* SCREEN = 0x0400; + for(byte i: 0..38) { + SCREEN[i] = SCREEN[i+1]; + (SCREEN+40)[i] = (SCREEN+40)[i+1]; + (SCREEN+80)[i] = (SCREEN+80)[i+1]; + (SCREEN+120)[i] = (SCREEN+120)[i+1]; + } + +} \ No newline at end of file diff --git a/src/test/kc/ternary-inference.kc b/src/test/kc/ternary-inference.kc new file mode 100644 index 000000000..30b892c79 --- /dev/null +++ b/src/test/kc/ternary-inference.kc @@ -0,0 +1,8 @@ +// Type inference into the ternary operator + +void main() { + const byte* screen = 0x400; + for(byte i: 0..10) { + screen[i] = (i<5?0x57:'0')+i; + } +} \ No newline at end of file diff --git a/src/test/kc/tod018-problem.kc b/src/test/kc/tod018-problem.kc new file mode 100644 index 000000000..cb6b2e5c7 --- /dev/null +++ b/src/test/kc/tod018-problem.kc @@ -0,0 +1,9 @@ +// Tests a problem with tod018 not calculating types correctly + +void main() { + const byte *D018 = 0xd018; + const byte* screen = 0x0400; + byte d018val = >((word)screen&$3fff); + *D018 = d018val; +} + diff --git a/src/test/kc/true-inline-words.kc b/src/test/kc/true-inline-words.kc index b9d96a0b6..cc701f1e0 100644 --- a/src/test/kc/true-inline-words.kc +++ b/src/test/kc/true-inline-words.kc @@ -3,7 +3,7 @@ void main() { byte[] bs = { 'c', 'm' }; // constant byte array byte b = 4; // constant byte word w = { b, 0 }; // constant inline word - word w2 = { 1, 1 } + w + { 0, 0 }; // constant inline words inside expression + word w2 = (word){ 1, 1 } + w + (word){ 0, 0 }; // constant inline words inside expression byte* sc = w2; // implicit cast to (byte*) *sc = bs[1]; // In the end $501 is set to 'c' diff --git a/src/test/kc/type-inference.kc b/src/test/kc/type-inference.kc new file mode 100644 index 000000000..968ecdf1d --- /dev/null +++ b/src/test/kc/type-inference.kc @@ -0,0 +1,9 @@ +// Test inference of integer types in expressions + +void main() { + const word* screen = 0x0400; + for( byte b: 0..20) { + screen[b] = -0x30+b; + } +} + diff --git a/src/test/kc/typeid-plus-byte-problem.kc b/src/test/kc/typeid-plus-byte-problem.kc index c4ddec78f..1b7cc98c6 100644 --- a/src/test/kc/typeid-plus-byte-problem.kc +++ b/src/test/kc/typeid-plus-byte-problem.kc @@ -3,7 +3,8 @@ const byte* SCREEN = $400; void main() { - unsigned byte ubc1 = 250; - SCREEN[0] = ubc1+250; + unsigned byte ubc1 = 12+13+14; + unsigned byte ubc2 = 250; + SCREEN[0] = ubc1+ubc2; } diff --git a/src/test/kc/typeid-plus-bytes.kc b/src/test/kc/typeid-plus-bytes.kc index 646e50087..d30efed35 100644 --- a/src/test/kc/typeid-plus-bytes.kc +++ b/src/test/kc/typeid-plus-bytes.kc @@ -7,11 +7,11 @@ byte idx = 0; void main() { idx = 0; testUnsigned(); - idx += $28; + idx = $28; testUnsignedVals(); - idx += $28; + idx = $28*2; testSigned(); - idx += $28; + idx = $28*3; testSignedVals(); } diff --git a/src/test/kc/typemismatch.kc b/src/test/kc/typemismatch.kc index d4d1f8b7c..d391e89a0 100644 --- a/src/test/kc/typemismatch.kc +++ b/src/test/kc/typemismatch.kc @@ -2,4 +2,6 @@ void main() { word w = 5000; byte b = w; + const byte* screen = 0x0400; + screen[0] = b; } \ No newline at end of file diff --git a/src/test/kc/valuelist-error.kc b/src/test/kc/valuelist-error.kc deleted file mode 100644 index 4463c8ebd..000000000 --- a/src/test/kc/valuelist-error.kc +++ /dev/null @@ -1,5 +0,0 @@ -void main() { - word w = { -1, -1}; - byte* screen = $400; - *screen = SCREEN sta DTV_PLANEA_START_MI @@ -89,7 +89,6 @@ main: { sta DTV_PLANEA_MODULO_LO sta DTV_PLANEA_MODULO_HI // Plane B: CHARSET8 - lda #CHARSET8 sta DTV_PLANEB_START_MI @@ -233,9 +232,9 @@ gfx_init_plane_charset8: { lda #0 sta ch sta col - lda #<$4000+(CHARSET8&$3fff) + lda #<$4000 sta gfxa - lda #>$4000+(CHARSET8&$3fff) + lda #>$4000 sta gfxa+1 lda #CHUNKY sta DTV_PLANEB_START_MI @@ -84,9 +84,9 @@ main: { sta CIA2_PORT_A // Set VIC Bank // VIC memory - lda #(CHUNKY&$3fff)/$40|(0)/4 + lda #0 sta VIC_MEMORY - ldx #0 + tax // DTV Palette - Grey Tones b1: txa @@ -195,7 +195,7 @@ gfx_init_chunky: { .label gfxb = 5 .label x = 3 .label y = 2 - lda #$ff&CHUNKY/$4000 + lda #CHUNKY/$4000 jsr dtvSetCpuBankSegment1 ldx #($ff&CHUNKY/$4000)+1 lda #0 diff --git a/src/test/ref/c64dtv-blitter-box.asm b/src/test/ref/c64dtv-blitter-box.asm new file mode 100644 index 000000000..36d9a9a77 --- /dev/null +++ b/src/test/ref/c64dtv-blitter-box.asm @@ -0,0 +1,148 @@ +// Fill a box on the screen using the blitter +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Feature enables or disables the extra C64 DTV features + .label DTV_FEATURE = $d03f + .const DTV_FEATURE_ENABLE = 1 + // Blitter Source A Start + .label DTV_BLITTER_SRCA_LO = $d320 + .label DTV_BLITTER_SRCA_MI = $d321 + .label DTV_BLITTER_SRCA_HI = $d322 + // Blitter Source A Modulo + .label DTV_BLITTER_SRCA_MOD_LO = $d323 + .label DTV_BLITTER_SRCA_MOD_HI = $d324 + // Blitter Source A Line Length + .label DTV_BLITTER_SRCA_LIN_LO = $d325 + .label DTV_BLITTER_SRCA_LIN_HI = $d326 + // Blitter Source A Step ([7:4] integral part, [3:0] fractional part) + .label DTV_BLITTER_SRCA_STEP = $d327 + // Blitter Source B Start + .label DTV_BLITTER_SRCB_LO = $d328 + .label DTV_BLITTER_SRCB_MI = $d329 + .label DTV_BLITTER_SRCB_HI = $d32a + // Blitter Source B Modulo + .label DTV_BLITTER_SRCB_MOD_LO = $d32b + .label DTV_BLITTER_SRCB_MOD_HI = $d32c + // Blitter Source B Line Length + .label DTV_BLITTER_SRCB_LIN_LO = $d32d + .label DTV_BLITTER_SRCB_LIN_HI = $d32e + // Blitter Source B Step ([7:4] integral part, [3:0] fractional part) + .label DTV_BLITTER_SRCB_STEP = $d32f + // Blitter Destination Start + .label DTV_BLITTER_DEST_LO = $d330 + .label DTV_BLITTER_DEST_MI = $d331 + .label DTV_BLITTER_DEST_HI = $d332 + // Blitter Source B Modulo + .label DTV_BLITTER_DEST_MOD_LO = $d333 + .label DTV_BLITTER_DEST_MOD_HI = $d334 + // Blitter Source B Line Length + .label DTV_BLITTER_DEST_LIN_LO = $d335 + .label DTV_BLITTER_DEST_LIN_HI = $d336 + // Blitter Source B Step ([7:4] integral part, [3:0] fractional part) + .label DTV_BLITTER_DEST_STEP = $d337 + // Blitter Blit Length + .label DTV_BLITTER_LEN_LO = $d338 + .label DTV_BLITTER_LEN_HI = $d339 + // Blitter Control + .label DTV_BLITTER_CONTROL = $d33a + // Bit[0] Force Start Strobe when set + .const DTV_BLIT_FORCE_START = 1 + // Bit[1] Source A Direction Positive when set + .const DTV_BLIT_SRCA_FWD = 2 + // Bit[2] Source B Direction Positive when set + .const DTV_BLIT_SRCB_FWD = 4 + // Bit[3] Destination Direction Positive when set + .const DTV_BLIT_DEST_FWD = 8 + // Blitter Transparency + .label DTV_BLITTER_TRANSPARANCY = $d33b + // No transparancy + // Bit[2]==Bit[1]==0: write in any case + .const DTV_BLIT_TRANSPARANCY_NONE = 0 + // Controls the ALU operation + .label DTV_BLITTER_ALU = $d33e + .const DTV_BLIT_ADD = $30 + // Blitter Control 2 + .label DTV_BLITTER_CONTROL2 = $d33f + // Bit[0] Clear Blitter IRQ + .const DTV_BLIT_CLEAR_IRQ = 1 + // Bit[3] Destination Continue + .const DTV_BLIT_DEST_CONT = 8 + // Bit[0] Busy when set (When reading) + .const DTV_BLIT_STATUS_BUSY = 1 + .label SCREEN = $400 +main: { + lda #DTV_FEATURE_ENABLE + sta DTV_FEATURE + // Instruct blitter not to continue previous blit + lda #DTV_BLIT_CLEAR_IRQ + sta DTV_BLITTER_CONTROL2 + lda #SRCA + sta DTV_BLITTER_SRCA_MI + lda #0 + sta DTV_BLITTER_SRCA_HI + sta DTV_BLITTER_SRCA_MOD_LO + sta DTV_BLITTER_SRCA_MOD_HI + sta DTV_BLITTER_SRCA_LIN_LO + lda #>$100 + sta DTV_BLITTER_SRCA_LIN_HI + lda #1 + sta DTV_BLITTER_SRCA_STEP + // Step 0.0 + lda #SRCB + sta DTV_BLITTER_SRCB_MI + lda #0 + sta DTV_BLITTER_SRCB_HI + sta DTV_BLITTER_SRCB_MOD_LO + sta DTV_BLITTER_SRCB_MOD_HI + sta DTV_BLITTER_SRCB_LIN_LO + lda #>$100 + sta DTV_BLITTER_SRCB_LIN_HI + lda #0 + sta DTV_BLITTER_SRCB_STEP + // Step 0.0 + lda #SCREEN+$28+5 + sta DTV_BLITTER_DEST_MI + lda #0 + sta DTV_BLITTER_DEST_HI + lda #<$15 + sta DTV_BLITTER_DEST_MOD_LO + lda #0 + sta DTV_BLITTER_DEST_MOD_HI + lda #<$13 + sta DTV_BLITTER_DEST_LIN_LO + lda #0 + sta DTV_BLITTER_DEST_LIN_HI + lda #$10 + sta DTV_BLITTER_DEST_STEP + // Step 1.0 + lda #<$14*$a + sta DTV_BLITTER_LEN_LO + lda #0 + sta DTV_BLITTER_LEN_HI + lda #DTV_BLIT_ADD + sta DTV_BLITTER_ALU + lda #DTV_BLIT_TRANSPARANCY_NONE + sta DTV_BLITTER_TRANSPARANCY + // Start blitter + lda #DTV_BLIT_FORCE_START|DTV_BLIT_SRCA_FWD|DTV_BLIT_SRCB_FWD|DTV_BLIT_DEST_FWD + sta DTV_BLITTER_CONTROL + // Instruct blitter to continue at DEST and restart SRC A/B + lda #DTV_BLIT_DEST_CONT + sta DTV_BLITTER_CONTROL2 + // wait til blitter is ready + b1: + lda #DTV_BLIT_STATUS_BUSY + and DTV_BLITTER_CONTROL2 + cmp #0 + bne b1 + rts +} + SRCA: .text "camelot rules!@" + SRCB: .byte $80 diff --git a/src/test/ref/c64dtv-blittermin.asm b/src/test/ref/c64dtv-blittermin.asm index b74c1966c..0628deace 100644 --- a/src/test/ref/c64dtv-blittermin.asm +++ b/src/test/ref/c64dtv-blittermin.asm @@ -85,7 +85,6 @@ main: { sta DTV_BLITTER_SRCA_HI sta DTV_BLITTER_SRCA_MOD_LO sta DTV_BLITTER_SRCA_MOD_HI - lda #<$100 sta DTV_BLITTER_SRCA_LIN_LO lda #>$100 sta DTV_BLITTER_SRCA_LIN_HI @@ -100,14 +99,12 @@ main: { sta DTV_BLITTER_SRCB_HI sta DTV_BLITTER_SRCB_MOD_LO sta DTV_BLITTER_SRCB_MOD_HI - lda #<$100 sta DTV_BLITTER_SRCB_LIN_LO lda #>$100 sta DTV_BLITTER_SRCB_LIN_HI lda #0 sta DTV_BLITTER_SRCB_STEP // Step 0.0 - lda #SCREEN sta DTV_BLITTER_DEST_MI @@ -115,7 +112,6 @@ main: { sta DTV_BLITTER_DEST_HI sta DTV_BLITTER_DEST_MOD_LO sta DTV_BLITTER_DEST_MOD_HI - lda #<$100 sta DTV_BLITTER_DEST_LIN_LO lda #>$100 sta DTV_BLITTER_DEST_LIN_HI diff --git a/src/test/ref/c64dtv-gfxexplorer.asm b/src/test/ref/c64dtv-gfxexplorer.asm index a1a01b569..18ca5b0bb 100644 --- a/src/test/ref/c64dtv-gfxexplorer.asm +++ b/src/test/ref/c64dtv-gfxexplorer.asm @@ -130,41 +130,6 @@ .const FORM_CURSOR_BLINK = $28 // Any shift is pressed .const KEY_MODIFIER_SHIFT = KEY_MODIFIER_LSHIFT|KEY_MODIFIER_RSHIFT - .label form_ctrl_bmm = form_fields_val+1 - .label form_ctrl_mcm = form_fields_val+2 - .label form_ctrl_ecm = form_fields_val+3 - .label form_ctrl_hicol = form_fields_val+4 - .label form_ctrl_line = form_fields_val+5 - .label form_ctrl_colof = form_fields_val+6 - .label form_ctrl_chunk = form_fields_val+7 - .label form_ctrl_borof = form_fields_val+8 - .label form_ctrl_overs = form_fields_val+9 - .label form_a_pattern = form_fields_val+$a - .label form_a_start_hi = form_fields_val+$b - .label form_a_start_lo = form_fields_val+$c - .label form_a_step_hi = form_fields_val+$d - .label form_a_step_lo = form_fields_val+$e - .label form_a_mod_hi = form_fields_val+$f - .label form_a_mod_lo = form_fields_val+$10 - .label form_b_pattern = form_fields_val+$11 - .label form_b_start_hi = form_fields_val+$12 - .label form_b_start_lo = form_fields_val+$13 - .label form_b_step_hi = form_fields_val+$14 - .label form_b_step_lo = form_fields_val+$15 - .label form_b_mod_hi = form_fields_val+$16 - .label form_b_mod_lo = form_fields_val+$17 - .label form_vic_screen = form_fields_val+$18 - .label form_vic_gfx = form_fields_val+$19 - .label form_vic_cols = form_fields_val+$1a - .label form_dtv_palet = form_fields_val+$1b - .label form_vic_bg0_hi = form_fields_val+$1c - .label form_vic_bg0_lo = form_fields_val+$1d - .label form_vic_bg1_hi = form_fields_val+$1e - .label form_vic_bg1_lo = form_fields_val+$1f - .label form_vic_bg2_hi = form_fields_val+$20 - .label form_vic_bg2_lo = form_fields_val+$21 - .label form_vic_bg3_hi = form_fields_val+$22 - .label form_vic_bg3_lo = form_fields_val+$23 .label print_char_cursor = 5 .label print_line_cursor = $10 .label keyboard_events_size = 8 @@ -196,61 +161,61 @@ main: { // Change graphics mode to show the selected graphics mode gfx_mode: { .label _22 = 9 - .label _24 = 3 .label _26 = 3 .label _28 = 3 .label _36 = 9 - .label _38 = 3 .label _40 = 3 .label _42 = 3 .label _52 = 3 + .label _53 = 3 .label _54 = 3 .label _55 = 3 .label _56 = 2 .label _57 = 3 + .label _58 = 3 .label _59 = 3 .label plane_a = 9 .label plane_b = 9 .label vic_colors = 3 .label col = 5 .label cy = 2 - lda form_ctrl_line + lda form_fields_val+5 cmp #0 beq b10 - ldx #0|DTV_LINEAR + ldx #DTV_LINEAR jmp b1 b10: ldx #0 b1: - lda form_ctrl_borof + lda form_fields_val+8 cmp #0 beq b2 txa ora #DTV_BORDER_OFF tax b2: - lda form_ctrl_hicol + lda form_fields_val+4 cmp #0 beq b3 txa ora #DTV_HIGHCOLOR tax b3: - lda form_ctrl_overs + lda form_fields_val+9 cmp #0 beq b4 txa ora #DTV_OVERSCAN tax b4: - lda form_ctrl_colof + lda form_fields_val+6 cmp #0 beq b5 txa ora #DTV_COLORRAM_OFF tax b5: - lda form_ctrl_chunk + lda form_fields_val+7 cmp #0 beq b6 txa @@ -258,7 +223,7 @@ gfx_mode: { tax b6: stx DTV_CONTROL - lda form_ctrl_ecm + lda form_fields_val+3 cmp #0 beq b11 ldx #VIC_DEN|VIC_RSEL|3|VIC_ECM @@ -266,7 +231,7 @@ gfx_mode: { b11: ldx #VIC_DEN|VIC_RSEL|3 b7: - lda form_ctrl_bmm + lda form_fields_val+1 cmp #0 beq b8 txa @@ -274,7 +239,7 @@ gfx_mode: { tax b8: stx VIC_CONTROL - lda form_ctrl_mcm + lda form_fields_val+2 cmp #0 beq b12 lda #VIC_CSEL|VIC_MCM @@ -283,14 +248,14 @@ gfx_mode: { lda #VIC_CSEL b9: sta VIC_CONTROL2 - lda form_a_start_hi + lda form_fields_val+$b asl asl asl asl - ora form_a_start_lo + ora form_fields_val+$c tax - lda form_a_pattern + lda form_fields_val+$a jsr get_plane txa clc @@ -306,15 +271,12 @@ gfx_mode: { adc #0 sta plane_a+3 lda plane_a - sta _24 - lda plane_a+1 - sta _24+1 - lda _24 - sta DTV_PLANEA_START_LO - lda plane_a sta _26 lda plane_a+1 sta _26+1 + lda _26 + sta DTV_PLANEA_START_LO + lda _26+1 sta DTV_PLANEA_START_MI lda plane_a+2 sta _28 @@ -322,30 +284,30 @@ gfx_mode: { sta _28+1 lda _28 sta DTV_PLANEA_START_HI - lda form_a_step_hi + lda form_fields_val+$d asl asl asl asl - ora form_a_step_lo + ora form_fields_val+$e sta DTV_PLANEA_STEP - lda form_a_mod_hi + lda form_fields_val+$f asl asl asl asl - ora form_a_mod_lo + ora form_fields_val+$10 sta DTV_PLANEA_MODULO_LO lda #0 sta DTV_PLANEA_MODULO_HI - lda form_b_start_hi + lda form_fields_val+$12 asl asl asl asl - ora form_b_start_lo + ora form_fields_val+$13 tax - lda form_b_pattern + lda form_fields_val+$11 jsr get_plane txa clc @@ -361,15 +323,12 @@ gfx_mode: { adc #0 sta plane_b+3 lda plane_b - sta _38 - lda plane_b+1 - sta _38+1 - lda _38 - sta DTV_PLANEB_START_LO - lda plane_b sta _40 lda plane_b+1 sta _40+1 + lda _40 + sta DTV_PLANEB_START_LO + lda _40+1 sta DTV_PLANEB_START_MI lda plane_b+2 sta _42 @@ -377,19 +336,19 @@ gfx_mode: { sta _42+1 lda _42 sta DTV_PLANEB_START_HI - lda form_b_step_hi + lda form_fields_val+$14 asl asl asl asl - ora form_b_step_lo + ora form_fields_val+$15 sta DTV_PLANEB_STEP - lda form_b_mod_hi + lda form_fields_val+$16 asl asl asl asl - ora form_b_mod_lo + ora form_fields_val+$17 sta DTV_PLANEB_MODULO_LO lda #0 sta DTV_PLANEB_MODULO_HI @@ -399,7 +358,7 @@ gfx_mode: { // Set VIC Bank bits to output - all others to input lda #3^VIC_SCREEN0/$4000 sta CIA2_PORT_A - lda form_vic_screen + lda form_fields_val+$18 jsr get_vic_screen lda _54 and #<$3fff @@ -415,7 +374,7 @@ gfx_mode: { bne !- lda _55 sta _56 - lda form_vic_gfx + lda form_fields_val+$19 jsr get_vic_charset lda _59 and #<$3fff @@ -429,7 +388,7 @@ gfx_mode: { // Set VIC Bank // VIC memory sta VIC_MEMORY - lda form_vic_cols + lda form_fields_val+$1a jsr get_vic_screen lda #0 sta cy @@ -461,36 +420,36 @@ gfx_mode: { // Background colors lda #0 sta BORDERCOL - lda form_vic_bg0_hi + lda form_fields_val+$1c asl asl asl asl - ora form_vic_bg0_lo + ora form_fields_val+$1d sta BGCOL1 - lda form_vic_bg1_hi + lda form_fields_val+$1e asl asl asl asl - ora form_vic_bg1_lo + ora form_fields_val+$1f sta BGCOL2 - lda form_vic_bg2_hi + lda form_fields_val+$20 asl asl asl asl - ora form_vic_bg2_lo + ora form_fields_val+$21 sta BGCOL3 - lda form_vic_bg3_hi + lda form_fields_val+$22 asl asl asl asl - ora form_vic_bg3_lo + ora form_fields_val+$23 sta BGCOL4 // DTV Palette - lda form_dtv_palet + lda form_fields_val+$1b cmp #0 beq b13 ldx #0 @@ -508,7 +467,9 @@ gfx_mode: { jsr keyboard_event_scan jsr keyboard_event_get cmp #KEY_SPACE - bne b25 + beq breturn + jmp b25 + breturn: rts // DTV Palette - default b13: @@ -567,7 +528,7 @@ keyboard_event_scan: { jsr keyboard_event_pressed cmp #0 beq b4 - ldx #0|KEY_MODIFIER_LSHIFT + ldx #KEY_MODIFIER_LSHIFT jmp b1 b4: ldx #0 @@ -679,39 +640,39 @@ keyboard_matrix_read: { get_vic_screen: { .label return = 3 cmp #0 - beq b2 + beq b1 cmp #1 - beq b3 + beq b2 cmp #2 - beq b4 + beq b3 cmp #3 - beq b5 + beq b4 cmp #4 - bne b2 + bne b1 lda #VIC_SCREEN4 sta return+1 rts - b2: + b1: lda #VIC_SCREEN0 sta return+1 rts - b3: + b2: lda #VIC_SCREEN1 sta return+1 rts - b4: + b3: lda #VIC_SCREEN2 sta return+1 rts - b5: + b4: lda #VIC_SCREEN3 @@ -723,15 +684,15 @@ get_vic_screen: { get_vic_charset: { .label return = 3 cmp #0 - beq b2 + beq b1 cmp #1 - bne b2 + bne b1 lda #VIC_BITMAP sta return+1 rts - b2: + b1: lda #VIC_CHARSET_ROM @@ -785,7 +746,7 @@ get_plane: { cmp #$c beq b6 cmp #$d - bne b2 + bne b1 lda #PLANE_FULL @@ -795,14 +756,24 @@ get_plane: { lda #>PLANE_FULL>>$10 sta return+3 rts - b2: - lda #<$ffffffff&VIC_SCREEN0 + b1: + lda #$ffffffff&VIC_SCREEN0 + lda #>VIC_SCREEN0 sta return+1 - lda #<$ffffffff&VIC_SCREEN0>>$10 + lda #>$10 sta return+2 - lda #>$ffffffff&VIC_SCREEN0>>$10 + lda #>VIC_SCREEN0>>$10 + sta return+3 + rts + b2: + lda #VIC_SCREEN0 + sta return+1 + lda #>$10 + sta return+2 + lda #>VIC_SCREEN0>>$10 sta return+3 rts b3: @@ -846,53 +817,53 @@ get_plane: { sta return+3 rts b7: - lda #<$ffffffff&VIC_SCREEN1 + lda #$ffffffff&VIC_SCREEN1 + lda #>VIC_SCREEN1 sta return+1 - lda #<$ffffffff&VIC_SCREEN1>>$10 + lda #>$10 sta return+2 - lda #>$ffffffff&VIC_SCREEN1>>$10 + lda #>VIC_SCREEN1>>$10 sta return+3 rts b8: - lda #<$ffffffff&VIC_SCREEN2 + lda #$ffffffff&VIC_SCREEN2 + lda #>VIC_SCREEN2 sta return+1 - lda #<$ffffffff&VIC_SCREEN2>>$10 + lda #>$10 sta return+2 - lda #>$ffffffff&VIC_SCREEN2>>$10 + lda #>VIC_SCREEN2>>$10 sta return+3 rts b9: - lda #<$ffffffff&VIC_SCREEN3 + lda #$ffffffff&VIC_SCREEN3 + lda #>VIC_SCREEN3 sta return+1 - lda #<$ffffffff&VIC_SCREEN3>>$10 + lda #>$10 sta return+2 - lda #>$ffffffff&VIC_SCREEN3>>$10 + lda #>VIC_SCREEN3>>$10 sta return+3 rts b10: - lda #<$ffffffff&VIC_BITMAP + lda #$ffffffff&VIC_BITMAP + lda #>VIC_BITMAP sta return+1 - lda #<$ffffffff&VIC_BITMAP>>$10 + lda #>$10 sta return+2 - lda #>$ffffffff&VIC_BITMAP>>$10 + lda #>VIC_BITMAP>>$10 sta return+3 rts b11: - lda #<$ffffffff&VIC_CHARSET_ROM + lda #$ffffffff&VIC_CHARSET_ROM + lda #>VIC_CHARSET_ROM sta return+1 - lda #<$ffffffff&VIC_CHARSET_ROM>>$10 + lda #>$10 sta return+2 - lda #>$ffffffff&VIC_CHARSET_ROM>>$10 + lda #>VIC_CHARSET_ROM>>$10 sta return+3 rts b12: @@ -956,10 +927,10 @@ form_mode: { lda form_fields_val jsr render_preset_name // DTV Graphics Bank - lda #($ffffffff&FORM_CHARSET)/$10000 + lda #0 sta DTV_GRAPHICS_VIC_BANK // DTV Color Bank - lda #DTV_COLOR_BANK_DEFAULT/$400 + lda #FORM_SCREEN sta DTV_PLANEA_START_MI @@ -1030,93 +1000,93 @@ form_mode: { render_preset_name: { .label name = 3 cmp #0 - beq b12 - cmp #1 - beq b4 - cmp #2 - beq b5 - cmp #3 - beq b6 - cmp #4 - beq b7 - cmp #5 - beq b8 - cmp #6 - beq b9 - cmp #7 - beq b10 - cmp #8 - beq b11 - cmp #9 - beq b2 - cmp #$a beq b3 - b12: + cmp #1 + beq b6 + cmp #2 + beq b7 + cmp #3 + beq b8 + cmp #4 + beq b9 + cmp #5 + beq b10 + cmp #6 + beq b11 + cmp #7 + beq b12 + cmp #8 + beq b4 + cmp #9 + beq b5 + cmp #$a + beq b1 + b3: lda #name_1 sta name+1 - jmp b1 - b2: - lda #name_10 - sta name+1 - jmp b1 - b3: + jmp b2 + b1: lda #name_11 sta name+1 - jmp b1 + jmp b2 b4: - lda #name_2 - sta name+1 - jmp b1 - b5: - lda #name_3 - sta name+1 - jmp b1 - b6: - lda #name_4 - sta name+1 - jmp b1 - b7: - lda #name_5 - sta name+1 - jmp b1 - b8: - lda #name_6 - sta name+1 - jmp b1 - b9: - lda #name_7 - sta name+1 - jmp b1 - b10: - lda #name_8 - sta name+1 - jmp b1 - b11: lda #name_9 sta name+1 - b1: + jmp b2 + b5: + lda #name_10 + sta name+1 + jmp b2 + b6: + lda #name_2 + sta name+1 + jmp b2 + b7: + lda #name_3 + sta name+1 + jmp b2 + b8: + lda #name_4 + sta name+1 + jmp b2 + b9: + lda #name_5 + sta name+1 + jmp b2 + b10: + lda #name_6 + sta name+1 + jmp b2 + b11: + lda #name_7 + sta name+1 + jmp b2 + b12: + lda #name_8 + sta name+1 + b2: jsr print_str_at rts name_1: .text "Standard Charset @" @@ -1168,7 +1138,7 @@ form_render_values: { ldy form_fields_val,x lda print_hextab,y ldy form_field_ptr.x - sta (form_field_ptr._2),y + sta (form_field_ptr.line),y inx cpx #form_fields_cnt bcc b1 @@ -1178,6 +1148,7 @@ form_render_values: { // field_idx is the index of the field to get the screen address for // form_field_ptr(byte register(X) field_idx) form_field_ptr: { + .label line = 3 .label x = $13 .label _2 = 3 lda form_fields_y,x @@ -1196,93 +1167,93 @@ form_field_ptr: { apply_preset: { .label preset = 3 cmp #0 - beq b12 - cmp #1 - beq b4 - cmp #2 - beq b5 - cmp #3 - beq b6 - cmp #4 - beq b7 - cmp #5 - beq b8 - cmp #6 - beq b9 - cmp #7 - beq b10 - cmp #8 - beq b11 - cmp #9 - beq b2 - cmp #$a beq b3 - b12: + cmp #1 + beq b6 + cmp #2 + beq b7 + cmp #3 + beq b8 + cmp #4 + beq b9 + cmp #5 + beq b10 + cmp #6 + beq b11 + cmp #7 + beq b12 + cmp #8 + beq b4 + cmp #9 + beq b5 + cmp #$a + beq b1 + b3: lda #preset_stdchar sta preset+1 - jmp b1 - b2: - lda #preset_sixsfred2 - sta preset+1 - jmp b1 - b3: + jmp b2 + b1: lda #preset_8bpppixelcell sta preset+1 - jmp b1 + jmp b2 b4: - lda #preset_ecmchar - sta preset+1 - jmp b1 - b5: - lda #preset_stdbm - sta preset+1 - jmp b1 - b6: - lda #preset_mcbm - sta preset+1 - jmp b1 - b7: - lda #preset_hi_stdchar - sta preset+1 - jmp b1 - b8: - lda #preset_hi_ecmchar - sta preset+1 - jmp b1 - b9: - lda #preset_twoplane - sta preset+1 - jmp b1 - b10: - lda #preset_chunky - sta preset+1 - jmp b1 - b11: lda #preset_sixsfred sta preset+1 - b1: + jmp b2 + b5: + lda #preset_sixsfred2 + sta preset+1 + jmp b2 + b6: + lda #preset_ecmchar + sta preset+1 + jmp b2 + b7: + lda #preset_stdbm + sta preset+1 + jmp b2 + b8: + lda #preset_mcbm + sta preset+1 + jmp b2 + b9: + lda #preset_hi_stdchar + sta preset+1 + jmp b2 + b10: + lda #preset_hi_ecmchar + sta preset+1 + jmp b2 + b11: + lda #preset_twoplane + sta preset+1 + jmp b2 + b12: + lda #preset_chunky + sta preset+1 + b2: ldy #0 // Copy preset values into the fields b13: @@ -1316,8 +1287,8 @@ form_control: { !b2: lda #$7f ldy form_field_ptr.x - and (form_field_ptr._2),y - sta (form_field_ptr._2),y + and (form_field_ptr.line),y + sta (form_field_ptr.line),y b3: jsr keyboard_event_scan jsr keyboard_event_get @@ -1325,78 +1296,78 @@ form_control: { bne b4 lda #$7f ldy form_field_ptr.x - and (form_field_ptr._2),y + and (form_field_ptr.line),y // Unblink the cursor - sta (form_field_ptr._2),y + sta (form_field_ptr.line),y txa and #KEY_MODIFIER_SHIFT cmp #0 - beq b12 + beq b13 dec form_field_idx lda #$ff cmp form_field_idx - bne b13 + bne b14 lda #form_fields_cnt-1 sta form_field_idx - b13: + b14: lda #FORM_CURSOR_BLINK/2 sta form_cursor_count ldx #0 rts - b12: + b13: inc form_field_idx lda #form_fields_cnt cmp form_field_idx - bne b13 + bne b14 lda #0 sta form_field_idx - jmp b13 + jmp b14 b4: cmp #KEY_CRSR_RIGHT bne b5 txa and #KEY_MODIFIER_SHIFT cmp #0 - beq b14 + beq b15 ldx form_field_idx dec form_fields_val,x lda #$ff ldy form_field_idx cmp form_fields_val,y - bne b15 + bne b16 lda form_fields_max,y sta form_fields_val,y - b15: + b16: // Render field value ldx form_field_idx ldy form_fields_val,x lda print_hextab,y ldy form_field_ptr.x - sta (form_field_ptr._2),y - b6: + sta (form_field_ptr.line),y + b7: ldx #0 rts - b14: + b15: ldx form_field_idx inc form_fields_val,x ldy form_field_idx lda form_fields_val,y cmp form_fields_max,y - bcc b15 - beq b15 + bcc b16 + beq b16 lda #0 sta form_fields_val,y - jmp b15 + jmp b16 b5: cmp #KEY_SPACE - bne b6 + bne b7 ldx #$ff rts b2: lda #$80 ldy form_field_ptr.x - ora (form_field_ptr._2),y - sta (form_field_ptr._2),y + ora (form_field_ptr.line),y + sta (form_field_ptr.line),y jmp b3 } // Set the screen to use for the form. @@ -1680,9 +1651,9 @@ gfx_init_plane_horisontal2: { .label ay = 2 lda #gfxbCpuBank jsr dtvSetCpuBankSegment1 - lda #<$4000+(PLANE_HORISONTAL2&$3fff) + lda #<$4000 sta gfxa - lda #>$4000+(PLANE_HORISONTAL2&$3fff) + lda #>$4000 sta gfxa+1 lda #0 sta ay @@ -1753,9 +1724,9 @@ gfx_init_plane_horisontal: { .label ay = 2 lda #gfxbCpuBank jsr dtvSetCpuBankSegment1 - lda #<$4000+(PLANE_HORISONTAL&$3fff) + lda #<$4000 sta gfxa - lda #>$4000+(PLANE_HORISONTAL&$3fff) + lda #>$4000 sta gfxa+1 lda #0 sta ay @@ -1810,9 +1781,9 @@ gfx_init_plane_charset8: { lda #0 sta ch sta col - lda #<$4000+(PLANE_CHARSET8&$3fff) + lda #<$4000 sta gfxa - lda #>$4000+(PLANE_CHARSET8&$3fff) + lda #>$4000 sta gfxa+1 lda #>$10 + lda #>$10 sta DTV_PLANEB_START_HI lda #8 sta DTV_PLANEB_STEP @@ -525,7 +524,7 @@ mode_8bpppixelcell: { lda #VIC_MCM|VIC_CSEL sta VIC_CONTROL2 // Linear Graphics Plane A Counter - lda #PLANEA sta DTV_PLANEA_START_MI @@ -537,7 +536,6 @@ mode_8bpppixelcell: { sta DTV_PLANEA_MODULO_LO sta DTV_PLANEA_MODULO_HI // Linear Graphics Plane B Counter - lda #PLANEB sta DTV_PLANEB_START_MI @@ -674,7 +672,7 @@ mode_sixsfred: { lda #VIC_MCM|VIC_CSEL sta VIC_CONTROL2 // Linear Graphics Plane A Counter - lda #PLANEA sta DTV_PLANEA_START_MI @@ -686,7 +684,6 @@ mode_sixsfred: { sta DTV_PLANEA_MODULO_LO sta DTV_PLANEA_MODULO_HI // Linear Graphics Plane B Counter - lda #PLANEB sta DTV_PLANEB_START_MI @@ -700,9 +697,9 @@ mode_sixsfred: { // DTV Color Bank lda #COLORS/$400 + lda #0 sta DTV_COLOR_BANK_HI - ldx #0 + tax // DTV Palette - Grey Tones b1: txa @@ -823,7 +820,7 @@ mode_twoplanebitmap: { lda #VIC_CSEL sta VIC_CONTROL2 // Linear Graphics Plane A Counter - lda #PLANEA sta DTV_PLANEA_START_MI @@ -835,7 +832,6 @@ mode_twoplanebitmap: { sta DTV_PLANEA_MODULO_LO sta DTV_PLANEA_MODULO_HI // Linear Graphics Plane B Counter - lda #PLANEB sta DTV_PLANEB_START_MI @@ -849,9 +845,9 @@ mode_twoplanebitmap: { // DTV Color Bank lda #COLORS/$400 + lda #0 sta DTV_COLOR_BANK_HI - ldx #0 + tax // DTV Palette - Grey Tones b1: txa @@ -989,7 +985,7 @@ mode_sixsfred2: { lda #VIC_MCM|VIC_CSEL sta VIC_CONTROL2 // Linear Graphics Plane A Counter - lda #PLANEA sta DTV_PLANEA_START_MI @@ -1001,7 +997,6 @@ mode_sixsfred2: { sta DTV_PLANEA_MODULO_LO sta DTV_PLANEA_MODULO_HI // Linear Graphics Plane B Counter - lda #PLANEB sta DTV_PLANEB_START_MI @@ -1015,9 +1010,9 @@ mode_sixsfred2: { // DTV Color Bank lda #COLORS/$400 + lda #0 sta DTV_COLOR_BANK_HI - ldx #0 + tax // DTV Palette - Grey Tones b1: txa @@ -1138,10 +1133,10 @@ mode_hicolmcchar: { .label ch = 5 .label cy = 4 // DTV Graphics Bank - lda #($ffffffff&CHARSET)/$10000 + lda #0 sta DTV_GRAPHICS_VIC_BANK // DTV Color Bank - lda #COLORS/$400 + lda #>1)+1 .const midw = (sumw>>1)+1 lda #midw diff --git a/src/test/ref/complex-conditional-problem.asm b/src/test/ref/complex-conditional-problem.asm index ec0d49551..12fdbcac5 100644 --- a/src/test/ref/complex-conditional-problem.asm +++ b/src/test/ref/complex-conditional-problem.asm @@ -10,11 +10,10 @@ main: { cmp #$20+1 bcs b3 cmp #$40 - bcc b3 + bcs b2 + b3: + lda #0 b2: sta SCREEN jmp b1 - b3: - lda #0 - jmp b2 } diff --git a/src/test/ref/complex/tetris/test-sprites.asm b/src/test/ref/complex/tetris/test-sprites.asm index a35164dc2..61571e8bb 100644 --- a/src/test/ref/complex/tetris/test-sprites.asm +++ b/src/test/ref/complex/tetris/test-sprites.asm @@ -84,7 +84,7 @@ bbegin: rts main: { .const toSpritePtr2_return = SIN_SPRITE/$40 - .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_SCREEN_1)/$40 + .const vicSelectGfxBank1_toDd001_return = 3 .const toD0181_return = (>(PLAYFIELD_SCREEN_1&$3fff)*4)|(>PLAYFIELD_CHARSET)/4&$f .label xpos = 2 .label ypos = 3 diff --git a/src/test/ref/complex/tetris/tetris.asm b/src/test/ref/complex/tetris/tetris.asm index 889a3b29e..ce2a47921 100644 --- a/src/test/ref/complex/tetris/tetris.asm +++ b/src/test/ref/complex/tetris/tetris.asm @@ -145,18 +145,18 @@ .label current_xpos_59 = $a .label current_piece_gfx_64 = 5 .label current_piece_char_68 = $b - .label render_screen_render_69 = 9 - .label current_xpos_130 = $a - .label current_xpos_131 = $a - .label current_piece_gfx_120 = 5 - .label current_piece_gfx_121 = 5 - .label current_piece_char_108 = $b - .label current_piece_char_109 = $b + .label render_screen_render_65 = 9 + .label current_xpos_119 = $a + .label current_xpos_120 = $a + .label current_piece_gfx_112 = 5 + .label current_piece_gfx_113 = 5 + .label current_piece_char_100 = $b + .label current_piece_char_101 = $b + .label current_piece_96 = 5 + .label current_piece_97 = 5 + .label current_piece_98 = 5 + .label current_piece_99 = 5 .label current_piece_100 = 5 - .label current_piece_101 = 5 - .label current_piece_102 = 5 - .label current_piece_103 = 5 - .label current_piece_104 = 5 bbegin: // The screen currently being showed to the user. $00 for screen 1 / $20 for screen 2. lda #0 @@ -192,23 +192,22 @@ main: { jsr render_playfield ldx current_ypos lda current_xpos - sta current_xpos_130 + sta current_xpos_119 lda current_piece_gfx - sta current_piece_gfx_120 + sta current_piece_gfx_112 lda current_piece_gfx+1 - sta current_piece_gfx_120+1 + sta current_piece_gfx_112+1 lda current_piece_char - sta current_piece_char_108 + sta current_piece_char_100 lda #$20 sta render_screen_render_33 jsr render_moving ldx play_spawn_current.piece_idx lda #$20 jsr render_next - ldy play_spawn_current._7 - lda PIECES,y + lda current_piece_gfx sta current_piece - lda PIECES+1,y + lda current_piece_gfx+1 sta current_piece+1 lda #0 sta level_bcd @@ -251,15 +250,15 @@ main: { jsr render_playfield ldx current_ypos lda render_screen_render - sta render_screen_render_69 + sta render_screen_render_65 lda current_xpos - sta current_xpos_131 + sta current_xpos_120 lda current_piece_gfx - sta current_piece_gfx_121 + sta current_piece_gfx_113 lda current_piece_gfx+1 - sta current_piece_gfx_121+1 + sta current_piece_gfx_113+1 lda current_piece_char - sta current_piece_char_109 + sta current_piece_char_101 jsr render_moving lda render_screen_render ldx next_piece_idx @@ -287,18 +286,18 @@ render_score: { .label screen = 5 lda render_screen_render cmp #0 - beq b2 + beq b1 lda #PLAYFIELD_SCREEN_2 sta screen+1 - jmp b1 - b2: + jmp b2 + b1: lda #PLAYFIELD_SCREEN_1 sta screen+1 - b1: + b2: ldx score_bytes+2 ldy #0 lda #score_offset+2 sta render_bcd.offset+1 jsr render_bcd ldx score_bytes ldy #0 - lda #score_offset+4 + lda #score_offset+4 sta render_bcd.offset+1 jsr render_bcd lda lines_bcd+1 @@ -331,9 +330,9 @@ render_score: { lda lines_bcd tax ldy #0 - lda #lines_offset+1 + lda #lines_offset+1 sta render_bcd.offset+1 jsr render_bcd ldx level_bcd @@ -389,33 +388,35 @@ render_bcd: { } // Render the next tetromino in the "next" area render_next: { + // Find the screen area .const next_area_offset = $28*$c+$18+4 - .label next_piece_char = $a .label next_piece_gfx = 5 + .label next_piece_char = $a .label screen_next_area = 7 .label l = 9 cmp #0 - beq b2 + beq b1 lda #PLAYFIELD_SCREEN_2+next_area_offset sta screen_next_area+1 - jmp b1 - b2: + jmp b2 + b1: lda #PLAYFIELD_SCREEN_1+next_area_offset sta screen_next_area+1 - b1: + b2: txa asl + // Render the next piece tay - lda PIECES_NEXT_CHARS,x - sta next_piece_char lda PIECES,y sta next_piece_gfx lda PIECES+1,y sta next_piece_gfx+1 + lda PIECES_NEXT_CHARS,x + sta next_piece_char lda #0 sta l b3: @@ -608,9 +609,9 @@ play_move_rotate: { sta play_collision.ypos ldx orientation lda current_piece - sta current_piece_103 + sta current_piece_99 lda current_piece+1 - sta current_piece_103+1 + sta current_piece_99+1 jsr play_collision cmp #COLLISION_NONE bne b4 @@ -645,8 +646,8 @@ play_collision: { .label l = $d .label i_2 = $e .label i_3 = $e - .label i_11 = $e - .label i_13 = $e + .label i_10 = $e + .label i_12 = $e txa clc adc piece_gfx @@ -715,11 +716,11 @@ play_collision: { rts b9: lda i - sta i_11 + sta i_10 jmp b1 b10: lda i - sta i_13 + sta i_12 jmp b2 } // Move left/right or rotate the current piece @@ -738,9 +739,9 @@ play_move_leftright: { sta play_collision.ypos ldx current_orientation lda current_piece - sta current_piece_102 + sta current_piece_98 lda current_piece+1 - sta current_piece_102+1 + sta current_piece_98+1 jsr play_collision cmp #COLLISION_NONE bne b3 @@ -759,9 +760,9 @@ play_move_leftright: { sta play_collision.ypos ldx current_orientation lda current_piece - sta current_piece_101 + sta current_piece_97 lda current_piece+1 - sta current_piece_101+1 + sta current_piece_97+1 jsr play_collision cmp #COLLISION_NONE bne b3 @@ -804,9 +805,9 @@ play_move_down: { sta play_collision.xpos ldx current_orientation lda current_piece - sta current_piece_100 + sta current_piece_96 lda current_piece+1 - sta current_piece_100+1 + sta current_piece_96+1 jsr play_collision cmp #COLLISION_NONE beq b10 @@ -816,10 +817,9 @@ play_move_down: { tax jsr play_update_score jsr play_spawn_current - ldy play_spawn_current._7 - lda PIECES,y + lda current_piece_gfx sta current_piece - lda PIECES+1,y + lda current_piece_gfx+1 sta current_piece+1 lda #0 sta current_orientation @@ -838,20 +838,18 @@ play_move_down: { // Spawn a new piece // Moves the next piece into the current and spawns a new next piece play_spawn_current: { - .label _7 = 4 .label piece_idx = $21 // Move next piece into current ldx next_piece_idx txa asl - sta _7 - lda PIECES_CHARS,x - sta current_piece_char - ldy _7 + tay lda PIECES,y sta current_piece_gfx lda PIECES+1,y sta current_piece_gfx+1 + lda PIECES_CHARS,x + sta current_piece_char lda PIECES_START_X,x sta current_xpos lda PIECES_START_Y,x @@ -860,10 +858,10 @@ play_spawn_current: { sta play_collision.xpos lda current_ypos sta play_collision.ypos - lda PIECES,y - sta current_piece_104 - lda PIECES+1,y - sta current_piece_104+1 + lda current_piece_gfx + sta current_piece_100 + lda current_piece_gfx+1 + sta current_piece_100+1 ldx #0 jsr play_collision cmp #COLLISION_PLAYFIELD @@ -1378,7 +1376,7 @@ sprites_init: { } // Initialize rendering render_init: { - .const vicSelectGfxBank1_toDd001_return = 3^(>PLAYFIELD_CHARSET)/$40 + .const vicSelectGfxBank1_toDd001_return = 3 .label li_1 = 5 .label li_2 = 7 lda #3 @@ -1415,22 +1413,19 @@ render_init: { sta li_1 lda #>PLAYFIELD_SCREEN_1+2*$28+$10 sta li_1+1 - ldx #0 + ldy #0 b1: - txa + tya asl - tay + tax lda li_1 - sta screen_lines_1,y + sta screen_lines_1,x lda li_1+1 - sta screen_lines_1+1,y - txa - asl - tay + sta screen_lines_1+1,x lda li_2 - sta screen_lines_2,y + sta screen_lines_2,x lda li_2+1 - sta screen_lines_2+1,y + sta screen_lines_2+1,x lda #$28 clc adc li_1 @@ -1445,8 +1440,8 @@ render_init: { bcc !+ inc li_2+1 !: - inx - cpx #PLAYFIELD_LINES-1+1 + iny + cpy #PLAYFIELD_LINES-1+1 bne b1 rts } diff --git a/src/test/ref/concat-char.cfg b/src/test/ref/concat-char.cfg deleted file mode 100644 index d85c7528b..000000000 --- a/src/test/ref/concat-char.cfg +++ /dev/null @@ -1,21 +0,0 @@ -@begin: scope:[] from - [0] phi() - to:@1 -@1: scope:[] from @begin - [1] phi() - [2] call main - to:@end -@end: scope:[] from @1 - [3] phi() -main: scope:[main] from @1 - [4] phi() - to:main::@1 -main::@1: scope:[main] from main main::@1 - [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) - [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) - [7] (byte) main::i#1 ← ++ (byte) main::i#2 - [8] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 - to:main::@return -main::@return: scope:[main] from main::@1 - [9] return - to:@return diff --git a/src/test/ref/concat-char.log b/src/test/ref/concat-char.log deleted file mode 100644 index 492facbb5..000000000 --- a/src/test/ref/concat-char.log +++ /dev/null @@ -1,338 +0,0 @@ -Identified constant variable (byte*) main::screen -Identified constant variable (byte) main::l - -CONTROL FLOW GRAPH SSA -@begin: scope:[] from - to:@1 -main: scope:[main] from @1 - (byte*) main::screen#0 ← ((byte*)) (word/signed word/dword/signed dword) $400 - (byte) main::l#0 ← (byte) 'l' - (string~) main::$0 ← (const string) main::$2 + (byte) main::l#0 - (byte[]) main::msg#0 ← (string~) main::$0 - (byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 - to:main::@1 -main::@1: scope:[main] from main main::@1 - (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) - *((byte*) main::screen#0 + (byte) main::i#2) ← *((byte[]) main::msg#0 + (byte) main::i#2) - (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,2) - (bool~) main::$1 ← (byte) main::i#1 != rangelast(0,2) - if((bool~) main::$1) goto main::@1 - to:main::@return -main::@return: scope:[main] from main::@1 - return - to:@return -@1: scope:[] from @begin - call main - to:@2 -@2: scope:[] from @1 - to:@end -@end: scope:[] from @2 - -SYMBOL TABLE SSA -(label) @1 -(label) @2 -(label) @begin -(label) @end -(void()) main() -(string~) main::$0 -(bool~) main::$1 -(const string) main::$2 = (string) "cm" -(label) main::@1 -(label) main::@return -(byte) main::i -(byte) main::i#0 -(byte) main::i#1 -(byte) main::i#2 -(byte) main::l -(byte) main::l#0 -(byte[]) main::msg -(byte[]) main::msg#0 -(byte*) main::screen -(byte*) main::screen#0 - -Culled Empty Block (label) @2 -Successful SSA optimization Pass2CullEmptyBlocks -Alias (byte[]) main::msg#0 = (string~) main::$0 -Successful SSA optimization Pass2AliasElimination -Simple Condition (bool~) main::$1 [9] if((byte) main::i#1!=rangelast(0,2)) goto main::@1 -Successful SSA optimization Pass2ConditionalJumpSimplification -Constant (const byte*) main::screen#0 = ((byte*))$400 -Constant (const byte) main::l#0 = 'l' -Constant (const byte) main::i#0 = 0 -Successful SSA optimization Pass2ConstantIdentification -Constant (const byte[]) main::msg#0 = "cm"+'l' -Successful SSA optimization Pass2ConstantIdentification -Eliminating unused constant (const string) main::$2 -Eliminating unused constant (const byte) main::l#0 -Successful SSA optimization PassNEliminateUnusedVars -Resolved ranged next value main::i#1 ← ++ main::i#2 to ++ -Resolved ranged comparison value if(main::i#1!=rangelast(0,2)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) 3 -Inlining constant with var siblings (const byte) main::i#0 -Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 -Successful SSA optimization Pass2ConstantInlining -Added new block during phi lifting main::@3(between main::@1 and main::@1) -Adding NOP phi() at start of @begin -Adding NOP phi() at start of @1 -Adding NOP phi() at start of @end -Adding NOP phi() at start of main -CALL GRAPH -Calls in [] to main:2 - -Created 1 initial phi equivalence classes -Coalesced [10] main::i#3 ← main::i#1 -Coalesced down to 1 phi equivalence classes -Culled Empty Block (label) main::@3 -Adding NOP phi() at start of @begin -Adding NOP phi() at start of @1 -Adding NOP phi() at start of @end -Adding NOP phi() at start of main - -FINAL CONTROL FLOW GRAPH -@begin: scope:[] from - [0] phi() - to:@1 -@1: scope:[] from @begin - [1] phi() - [2] call main - to:@end -@end: scope:[] from @1 - [3] phi() -main: scope:[main] from @1 - [4] phi() - to:main::@1 -main::@1: scope:[main] from main main::@1 - [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) - [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) - [7] (byte) main::i#1 ← ++ (byte) main::i#2 - [8] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 - to:main::@return -main::@return: scope:[main] from main::@1 - [9] return - to:@return - - -VARIABLE REGISTER WEIGHTS -(void()) main() -(byte) main::i -(byte) main::i#1 16.5 -(byte) main::i#2 22.0 -(byte) main::l -(byte[]) main::msg -(byte*) main::screen - -Initial phi equivalence classes -[ main::i#2 main::i#1 ] -Complete equivalence classes -[ main::i#2 main::i#1 ] -Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ] - -INITIAL ASM -//SEG0 File Comments -// Concatenate a char to a string -//SEG1 Basic Upstart -.pc = $801 "Basic" -:BasicUpstart(bbegin) -.pc = $80d "Program" -//SEG2 Global Constants & labels -//SEG3 @begin -bbegin: -//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] -b1_from_bbegin: - jmp b1 -//SEG5 @1 -b1: -//SEG6 [2] call main -//SEG7 [4] phi from @1 to main [phi:@1->main] -main_from_b1: - jsr main -//SEG8 [3] phi from @1 to @end [phi:@1->@end] -bend_from_b1: - jmp bend -//SEG9 @end -bend: -//SEG10 main -main: { - .label screen = $400 - .label i = 2 - //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] - b1_from_main: - //SEG12 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 - lda #0 - sta i - jmp b1 - //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] - b1_from_b1: - //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy - jmp b1 - //SEG15 main::@1 - b1: - //SEG16 [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz1 - ldy i - lda msg,y - sta screen,y - //SEG17 [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 - inc i - //SEG18 [8] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 - lda #3 - cmp i - bne b1_from_b1 - jmp breturn - //SEG19 main::@return - breturn: - //SEG20 [9] return - rts - msg: .text "cm"+'l' -} - -REGISTER UPLIFT POTENTIAL REGISTERS -Statement [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a -Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] -Statement [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a -Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , - -REGISTER UPLIFT SCOPES -Uplift Scope [main] 38.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] -Uplift Scope [] - -Uplifting [main] best 288 combination reg byte x [ main::i#2 main::i#1 ] -Uplifting [] best 288 combination - -ASSEMBLER BEFORE OPTIMIZATION -//SEG0 File Comments -// Concatenate a char to a string -//SEG1 Basic Upstart -.pc = $801 "Basic" -:BasicUpstart(bbegin) -.pc = $80d "Program" -//SEG2 Global Constants & labels -//SEG3 @begin -bbegin: -//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] -b1_from_bbegin: - jmp b1 -//SEG5 @1 -b1: -//SEG6 [2] call main -//SEG7 [4] phi from @1 to main [phi:@1->main] -main_from_b1: - jsr main -//SEG8 [3] phi from @1 to @end [phi:@1->@end] -bend_from_b1: - jmp bend -//SEG9 @end -bend: -//SEG10 main -main: { - .label screen = $400 - //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] - b1_from_main: - //SEG12 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 - ldx #0 - jmp b1 - //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] - b1_from_b1: - //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy - jmp b1 - //SEG15 main::@1 - b1: - //SEG16 [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx - lda msg,x - sta screen,x - //SEG17 [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx - inx - //SEG18 [8] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 - cpx #3 - bne b1_from_b1 - jmp breturn - //SEG19 main::@return - breturn: - //SEG20 [9] return - rts - msg: .text "cm"+'l' -} - -ASSEMBLER OPTIMIZATIONS -Removing instruction jmp b1 -Removing instruction jmp bend -Removing instruction jmp b1 -Removing instruction jmp breturn -Succesful ASM optimization Pass5NextJumpElimination -Replacing label b1_from_b1 with b1 -Removing instruction b1_from_bbegin: -Removing instruction b1: -Removing instruction main_from_b1: -Removing instruction bend_from_b1: -Removing instruction b1_from_b1: -Succesful ASM optimization Pass5RedundantLabelElimination -Removing instruction bend: -Removing instruction b1_from_main: -Removing instruction breturn: -Succesful ASM optimization Pass5UnusedLabelElimination -Updating BasicUpstart to call main directly -Removing instruction jsr main -Succesful ASM optimization Pass5SkipBegin -Removing instruction jmp b1 -Succesful ASM optimization Pass5NextJumpElimination -Removing instruction bbegin: -Succesful ASM optimization Pass5UnusedLabelElimination - -FINAL SYMBOL TABLE -(label) @1 -(label) @begin -(label) @end -(void()) main() -(label) main::@1 -(label) main::@return -(byte) main::i -(byte) main::i#1 reg byte x 16.5 -(byte) main::i#2 reg byte x 22.0 -(byte) main::l -(byte[]) main::msg -(const byte[]) main::msg#0 msg = (string) "cm"+(byte) 'l' -(byte*) main::screen -(const byte*) main::screen#0 screen = ((byte*))(word/signed word/dword/signed dword) $400 - -reg byte x [ main::i#2 main::i#1 ] - - -FINAL ASSEMBLER -Score: 186 - -//SEG0 File Comments -// Concatenate a char to a string -//SEG1 Basic Upstart -.pc = $801 "Basic" -:BasicUpstart(main) -.pc = $80d "Program" -//SEG2 Global Constants & labels -//SEG3 @begin -//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] -//SEG5 @1 -//SEG6 [2] call main -//SEG7 [4] phi from @1 to main [phi:@1->main] -//SEG8 [3] phi from @1 to @end [phi:@1->@end] -//SEG9 @end -//SEG10 main -main: { - .label screen = $400 - //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] - //SEG12 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 - ldx #0 - //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] - //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy - //SEG15 main::@1 - b1: - //SEG16 [6] *((const byte*) main::screen#0 + (byte) main::i#2) ← *((const byte[]) main::msg#0 + (byte) main::i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuxx - lda msg,x - sta screen,x - //SEG17 [7] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx - inx - //SEG18 [8] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 - cpx #3 - bne b1 - //SEG19 main::@return - //SEG20 [9] return - rts - msg: .text "cm"+'l' -} - diff --git a/src/test/ref/concat-char.sym b/src/test/ref/concat-char.sym deleted file mode 100644 index 118c86105..000000000 --- a/src/test/ref/concat-char.sym +++ /dev/null @@ -1,16 +0,0 @@ -(label) @1 -(label) @begin -(label) @end -(void()) main() -(label) main::@1 -(label) main::@return -(byte) main::i -(byte) main::i#1 reg byte x 16.5 -(byte) main::i#2 reg byte x 22.0 -(byte) main::l -(byte[]) main::msg -(const byte[]) main::msg#0 msg = (string) "cm"+(byte) 'l' -(byte*) main::screen -(const byte*) main::screen#0 screen = ((byte*))(word/signed word/dword/signed dword) $400 - -reg byte x [ main::i#2 main::i#1 ] diff --git a/src/test/ref/consolidate-constant-problem.asm b/src/test/ref/consolidate-constant-problem.asm index f8146c526..be6c8721f 100644 --- a/src/test/ref/consolidate-constant-problem.asm +++ b/src/test/ref/consolidate-constant-problem.asm @@ -6,7 +6,7 @@ main: { lda #0 sta screen+$27 sta screen+$26 - sta $28*1+screen+$27 - sta screen+$26+$28*1 + sta screen+$28*1+$27 + sta screen+$28*1+$26 rts } diff --git a/src/test/ref/const-int-cast-problem.asm b/src/test/ref/const-int-cast-problem.asm new file mode 100644 index 000000000..10377d0e9 --- /dev/null +++ b/src/test/ref/const-int-cast-problem.asm @@ -0,0 +1,19 @@ +// Test a problem with converting casted constant numbers to fixed type constant integers +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 +main: { + ldx #$79 + b1: + txa + lsr + lsr + lsr + lsr + sta SCREEN,x + inx + cpx #$7b + bne b1 + rts +} diff --git a/src/test/ref/const-signed-promotion.asm b/src/test/ref/const-signed-promotion.asm index 90042051c..fbe66dba9 100644 --- a/src/test/ref/const-signed-promotion.asm +++ b/src/test/ref/const-signed-promotion.asm @@ -2,7 +2,6 @@ .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" - .const SIZEOF_SIGNED_WORD = 2 main: { .label screen = $400 ldx #0 diff --git a/src/test/ref/constant-string-concat-0.asm b/src/test/ref/constant-string-concat-0.asm new file mode 100644 index 000000000..7fff00ab2 --- /dev/null +++ b/src/test/ref/constant-string-concat-0.asm @@ -0,0 +1,17 @@ +// Concatenates string constants in different ways +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + ldx #0 + b1: + lda msg,x + sta SCREEN,x + inx + lda msg,x + cmp #0 + bne b1 + rts + msg: .text "camelot@" +} diff --git a/src/test/ref/constant-string-concat.asm b/src/test/ref/constant-string-concat.asm index 4fa0ed741..c832a5567 100644 --- a/src/test/ref/constant-string-concat.asm +++ b/src/test/ref/constant-string-concat.asm @@ -6,14 +6,11 @@ main: { .label SCREEN = $400 ldx #0 b1: - lda s5,x + lda s,x sta SCREEN,x inx cpx #8 bne b1 rts - s: .text "e"+"l" - s4: .text ""+'t'+'!' - s3: .text "cam"+s+'o' - s5: .text s3+s4 + s: .text "camelot@" } diff --git a/src/test/ref/constantmin.asm b/src/test/ref/constantmin.asm index 4832ff399..5fc98d7cf 100644 --- a/src/test/ref/constantmin.asm +++ b/src/test/ref/constantmin.asm @@ -5,12 +5,11 @@ .const STAR = $51 .label VIC = $d000 .const RED = 2 - .label BGCOL = VIC+$10*2+1 main: { lda #STAR sta SCREEN lda #RED - sta BGCOL + sta VIC+$10*2+1 ldx #$28 b1: lda #STAR+1 diff --git a/src/test/ref/constants.asm b/src/test/ref/constants.asm index e49be31e1..7d603723c 100644 --- a/src/test/ref/constants.asm +++ b/src/test/ref/constants.asm @@ -18,8 +18,8 @@ main: { test_sbytes: { .const bb = 0 .const bc = bb+2 - .const bd = bc-4 .const bf = $ff&-$7f-$7f + .const bd = bc-4 .const be = -bd lda #0 sta assert_sbyte.c diff --git a/src/test/ref/derefidx-word-0.asm b/src/test/ref/derefidx-word-0.asm new file mode 100644 index 000000000..95ea7045b --- /dev/null +++ b/src/test/ref/derefidx-word-0.asm @@ -0,0 +1,39 @@ +// Tests that array-indexing by a word variable is turned into pointer addition +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label i = 2 + .label _1 = 4 + lda #0 + sta i + sta i+1 + b1: + lda i + clc + adc #screen + sta _1+1 + lda #'a' + ldy #0 + sta (_1),y + lda #$28 + clc + adc i + sta i + bcc !+ + inc i+1 + !: + lda i+1 + cmp #>$3e8 + bcc b1 + bne !+ + lda i + cmp #<$3e8 + bcc b1 + !: + rts +} diff --git a/src/test/ref/derefidx-word-1.asm b/src/test/ref/derefidx-word-1.asm new file mode 100644 index 000000000..631845860 --- /dev/null +++ b/src/test/ref/derefidx-word-1.asm @@ -0,0 +1,10 @@ +// Tests that array-indexing by a constant word is turned into a constant pointer +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + lda #'a' + sta screen+$28*$a + rts +} diff --git a/src/test/ref/derefidx-word-2.asm b/src/test/ref/derefidx-word-2.asm new file mode 100644 index 000000000..44af2978a --- /dev/null +++ b/src/test/ref/derefidx-word-2.asm @@ -0,0 +1,15 @@ +// Tests that array-indexing by a word variable that is a sum of a constant word and a byte is turned back into derefidx +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + ldx #0 + b1: + lda #'a' + sta screen+$28*$a,x + inx + cpx #$28 + bne b1 + rts +} diff --git a/src/test/ref/duplicate-loop-problem.asm b/src/test/ref/duplicate-loop-problem.asm index d2dc774fa..0a2aa7631 100644 --- a/src/test/ref/duplicate-loop-problem.asm +++ b/src/test/ref/duplicate-loop-problem.asm @@ -10,9 +10,7 @@ main: { txa and #$1f cpx #0 - beq b3 - jmp b1 - b3: + bne b1 cmp #$1f beq b1 jmp b1 diff --git a/src/test/ref/examples/3d/3d.asm b/src/test/ref/examples/3d/3d.asm index 0dcdcb236..c555981f4 100644 --- a/src/test/ref/examples/3d/3d.asm +++ b/src/test/ref/examples/3d/3d.asm @@ -129,13 +129,13 @@ anim: { tya asl tax - lda #$80 + lda xp clc - adc xp + adc #$80 sta SPRITES_XPOS,x - lda #$80 + lda yp clc - adc yp + adc #$80 sta SPRITES_YPOS,x inc i lda #8 @@ -149,10 +149,9 @@ anim: { // Increment angles inc sx inc sx - lda sy - sec - sbc #3 - sta sy + lax sy + axs #3 + stx sy jmp b2 } debug_print: { @@ -336,8 +335,7 @@ print_sbyte_at: { .label at = 6 cpx #0 bmi b1 - lda #' ' - sta print_char_at.ch + ldy #' ' jsr print_char_at b2: inc print_byte_at.at @@ -347,8 +345,7 @@ print_sbyte_at: { jsr print_byte_at rts b1: - lda #'-' - sta print_char_at.ch + ldy #'-' jsr print_char_at txa eor #$ff @@ -358,17 +355,16 @@ print_sbyte_at: { jmp b2 } // Print a single char -// print_char_at(byte zeropage(8) ch, byte* zeropage(6) at) +// print_char_at(byte register(Y) ch, byte* zeropage(6) at) print_char_at: { .label at = 6 - .label ch = 8 - lda ch + tya ldy #0 sta (at),y rts } // Print a byte as HEX at a specific position -// print_byte_at(byte* zeropage(6) at) +// print_byte_at(byte register(X) b, byte* zeropage(6) at) print_byte_at: { .label at = 6 txa @@ -378,7 +374,7 @@ print_byte_at: { lsr tay lda print_hextab,y - sta print_char_at.ch + tay jsr print_char_at lda #$f axs #0 @@ -386,8 +382,7 @@ print_byte_at: { bne !+ inc print_char_at.at+1 !: - lda print_hextab,x - sta print_char_at.ch + ldy print_hextab,x jsr print_char_at rts } @@ -395,10 +390,10 @@ print_byte_at: { // The rotation matrix is prepared by calling prepare_matrix() // The passed points must be in the interval [-$3f;$3f]. // Implemented in assembler to utilize seriously fast multiplication -// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage(8) z) +// rotate_matrix(signed byte register(X) x, signed byte zeropage(5) y, signed byte zeropage($a) z) rotate_matrix: { .label y = 5 - .label z = 8 + .label z = $a txa sta xr lda y @@ -543,7 +538,7 @@ calculate_matrix: { .label sy = 3 .label t1 = 4 .label t3 = 5 - .label t4 = 8 + .label t4 = $a .label t5 = $b .label t6 = $c .label t7 = $d @@ -959,9 +954,9 @@ debug_print_init: { str11: .text "yp@" } // Print a string at a specific screen position -// print_str_at(byte* zeropage(6) str, byte* zeropage(9) at) +// print_str_at(byte* zeropage(6) str, byte* zeropage(8) at) print_str_at: { - .label at = 9 + .label at = 8 .label str = 6 b1: ldy #0 @@ -1014,7 +1009,7 @@ sprites_init: { sta SPRITES_ENABLE ldx #0 b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta sprites_ptr,x lda #GREEN sta SPRITES_COLS,x @@ -1024,6 +1019,9 @@ sprites_init: { rts } print_hextab: .text "0123456789abcdef" + // Positions to rotate + xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34 + ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34 zs: .byte $34, $34, $34, $34, $34, $34, $34, $34 // Rotated positions xrs: .fill 8, 0 @@ -1036,9 +1034,6 @@ sprites_init: { yps: .fill 8, 0 // The rotation matrix rotation_matrix: .fill 9, 0 - // Positions to rotate - xs: .byte -$34, -$34, -$34, 0, 0, $34, $34, $34 - ys: .byte -$34, 0, $34, -$34, $34, -$34, 0, $34 .pc = mulf_sqr1 "mulf_sqr1" .for(var i=0;i<$200;i++) { .if(i<=159) { .byte round((i*i)/256) } diff --git a/src/test/ref/examples/3d/perspective.asm b/src/test/ref/examples/3d/perspective.asm index 7dea6c315..878c3f046 100644 --- a/src/test/ref/examples/3d/perspective.asm +++ b/src/test/ref/examples/3d/perspective.asm @@ -32,8 +32,8 @@ main: { rts } do_perspective: { - .label y = -$47 .label x = $39 + .label y = -$47 .label z = $36 lda #<$400 sta print_char_cursor @@ -244,42 +244,35 @@ mulf_init: { sta add lda #0 sta add+1 - tax + tay sta sqr sta sqr+1 b1: lda sqr+1 sta val + sta mulf_sqr1,y + sta mulf_sqr1+$100,y + tya + eor #$ff + tax + inx + lda val sta mulf_sqr1,x sta mulf_sqr1+$100,x - txa + sta mulf_sqr2+1,y + sta mulf_sqr2+$100+1,y + tya eor #$ff - tay - iny + tax + axs #1+1 lda val - sta mulf_sqr1,y - txa + sta mulf_sqr2,x + tya eor #$ff - tay - iny + tax + axs #1+1 lda val - sta mulf_sqr1+$100,y - sta mulf_sqr2+1,x - sta mulf_sqr2+$100+1,x - txa - eor #$ff - clc - adc #1+1 - tay - lda val - sta mulf_sqr2,y - txa - eor #$ff - clc - adc #1+1 - tay - lda val - sta mulf_sqr2+$100,y + sta mulf_sqr2+$100,x lda sqr clc adc add @@ -294,8 +287,8 @@ mulf_init: { bcc !+ inc add+1 !: - inx - cpx #$81 + iny + cpy #$81 bne b1 rts } diff --git a/src/test/ref/examples/bresenham/bitmap-bresenham.asm b/src/test/ref/examples/bresenham/bitmap-bresenham.asm index a5ee012ff..5c7a99cac 100644 --- a/src/test/ref/examples/bresenham/bitmap-bresenham.asm +++ b/src/test/ref/examples/bresenham/bitmap-bresenham.asm @@ -187,6 +187,7 @@ bitmap_plot: { .label _0 = 9 .label plotter_x = 9 .label plotter_y = $b + .label plotter = 9 lda bitmap_plot_xhi,x sta plotter_x+1 lda bitmap_plot_xlo,x @@ -204,8 +205,8 @@ bitmap_plot: { sta _0+1 lda bitmap_plot_bit,x ldy #0 - ora (_0),y - sta (_0),y + ora (plotter),y + sta (plotter),y rts } // bitmap_line_ydxi(byte zeropage(7) y, byte register(X) x, byte zeropage(6) y1, byte zeropage(3) yd, byte zeropage(4) xd) @@ -363,7 +364,7 @@ bitmap_clear: { } // Initialize the bitmap plotter tables for a specific bitmap bitmap_init: { - .label _6 = 2 + .label _10 = 2 .label yoffs = 9 ldy #$80 ldx #0 @@ -391,15 +392,14 @@ bitmap_init: { tax b3: lda #7 - sax _6 + sax _10 lda yoffs - ora _6 + ora _10 sta bitmap_plot_ylo,x lda yoffs+1 sta bitmap_plot_yhi,x - txa - and #7 - cmp #7 + lda #7 + cmp _10 bne b4 clc lda yoffs diff --git a/src/test/ref/examples/chargen/chargen-analysis.asm b/src/test/ref/examples/chargen/chargen-analysis.asm index 3acea7f3d..591a0f78e 100644 --- a/src/test/ref/examples/chargen/chargen-analysis.asm +++ b/src/test/ref/examples/chargen/chargen-analysis.asm @@ -174,39 +174,39 @@ main: { ldx #KEY_LSHIFT jsr keyboard_key_pressed cmp #0 - bne b2 + bne b9 lda #0 sta shift - jmp b9 - b2: + jmp b10 + b9: lda #1 sta shift - b9: + b10: lda #0 sta ch // Check for key presses - and plot char if found - b10: + b11: ldx ch jsr keyboard_get_keycode cmp #$3f - beq b13 + beq b2 tax jsr keyboard_key_pressed - jmp b11 - b13: + jmp b12 + b2: lda #0 - b11: + b12: cmp #0 - beq b12 + beq b13 ldy cur_pos lda ch ldx shift jsr plot_chargen - b12: + b13: inc ch lda #$40 cmp ch - bne b10 + bne b11 jmp b4 str: .text "f1@" str1: .text "f3@" diff --git a/src/test/ref/examples/fastmultiply/fastmultiply8.asm b/src/test/ref/examples/fastmultiply/fastmultiply8.asm index 1ca0be223..b01b2b3b8 100644 --- a/src/test/ref/examples/fastmultiply/fastmultiply8.asm +++ b/src/test/ref/examples/fastmultiply/fastmultiply8.asm @@ -145,10 +145,11 @@ print_char_at: { rts } // Print a byte as HEX at a specific position -// print_byte_at(byte* zeropage(8) at) +// print_byte_at(byte zeropage($a) b, byte* zeropage(8) at) print_byte_at: { + .label b = $a .label at = 8 - lda print_sbyte_at.b + lda b lsr lsr lsr @@ -158,7 +159,7 @@ print_byte_at: { sta print_char_at.ch jsr print_char_at lda #$f - and print_sbyte_at.b + and b tay inc print_char_at.at bne !+ diff --git a/src/test/ref/examples/fire/fire.asm b/src/test/ref/examples/fire/fire.asm index d14cf06e3..77c8919c1 100644 --- a/src/test/ref/examples/fire/fire.asm +++ b/src/test/ref/examples/fire/fire.asm @@ -182,7 +182,7 @@ makecharset: { .label ii = $a .label i = 9 .label c = 8 - .label _22 = 2 + .label _26 = 2 lda #CHARSET @@ -272,15 +272,15 @@ makecharset: { inc _19+1 !: clc - lda _22 + lda _26 adc #CHARSET+1*8 - sta _22+1 + sta _26+1 tya ldy #0 - sta (_22),y + sta (_26),y inc i lda i cmp #8 diff --git a/src/test/ref/examples/multiplexer/simple-multiplexer.asm b/src/test/ref/examples/multiplexer/simple-multiplexer.asm index 449776ef4..b0ac841db 100644 --- a/src/test/ref/examples/multiplexer/simple-multiplexer.asm +++ b/src/test/ref/examples/multiplexer/simple-multiplexer.asm @@ -23,10 +23,10 @@ .label SPRITE = $2000 .label YSIN = $2100 .label PLEX_SCREEN_PTR = SCREEN+$3f8 + .label plex_sprite_msb = 6 .label plex_free_next = 3 .label plex_sprite_idx = 4 .label plex_show_idx = 5 - .label plex_sprite_msb = 6 main: { sei jsr init @@ -120,17 +120,13 @@ plexShowSprite: { ldx plex_sprite_idx sta PLEX_SCREEN_PTR,x ldy plex_show_idx - ldx PLEX_SORTED_IDX,y - txa + lda PLEX_SORTED_IDX,y asl - tay - lda PLEX_XPOS,y + tax + lda PLEX_XPOS,x ldy plex_sprite_idx2 sta SPRITES_XPOS,y - txa - asl - tay - lda PLEX_XPOS+1,y + lda PLEX_XPOS+1,x cmp #0 bne b1 lda #$ff @@ -146,10 +142,11 @@ plexShowSprite: { asl plex_sprite_msb lda plex_sprite_msb cmp #0 - bne breturn + bne b5 lda #1 sta plex_sprite_msb - breturn: + rts + b5: rts b1: lda SPRITES_XMSB @@ -188,7 +185,11 @@ plexSort: { sta PLEX_SORTED_IDX+1,x dex cpx #$ff - bne b5 + beq b4 + lda nxt_y + ldy PLEX_SORTED_IDX,x + cmp PLEX_YPOS,y + bcc b3 b4: inx lda nxt_idx @@ -206,12 +207,6 @@ plexSort: { cpx #8 bne plexFreePrepare1_b1 rts - b5: - lda nxt_y - ldy PLEX_SORTED_IDX,x - cmp PLEX_YPOS,y - bcc b3 - jmp b4 } // Initialize the program init: { @@ -225,7 +220,7 @@ init: { sta xp+1 tax b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta PLEX_PTR,x txa asl diff --git a/src/test/ref/examples/rotate/rotate.asm b/src/test/ref/examples/rotate/rotate.asm index e96371907..21947b062 100644 --- a/src/test/ref/examples/rotate/rotate.asm +++ b/src/test/ref/examples/rotate/rotate.asm @@ -27,14 +27,16 @@ main: { rts } anim: { - .label _4 = 7 - .label _6 = 9 + .label _4 = 5 + .label _6 = 5 .label _9 = 5 .label _10 = 5 .label _11 = 5 .label _12 = 5 - .label x = $b - .label y = $c + .label cos_a = $b + .label sin_a = $c + .label x = $d + .label y = $e .label xr = 7 .label yr = 9 .label xpos = 5 @@ -48,6 +50,11 @@ anim: { cmp RASTER bne b2 inc BORDERCOL + ldy angle + lda COS,y + sta cos_a + lda SIN,y + sta sin_a lda #0 sta sprite_msb sta i @@ -58,27 +65,25 @@ anim: { // signed fixed[7.0] lda ys,y sta y - ldy angle - lda COS,y + lda cos_a jsr mulf8u_prepare ldy x jsr mulf8s_prepared - lda mulf8s_prepared.return - sta _4 - lda mulf8s_prepared.return+1 - sta _4+1 - asl xr - rol xr+1 + lda _4 + asl + sta xr + lda _4+1 + rol + sta xr+1 ldy y jsr mulf8s_prepared - lda mulf8s_prepared.return - sta _6 - lda mulf8s_prepared.return+1 - sta _6+1 - asl yr - rol yr+1 - ldy angle - lda SIN,y + lda _6 + asl + sta yr + lda _6+1 + rol + sta yr+1 + lda sin_a jsr mulf8u_prepare ldy y jsr mulf8s_prepared @@ -104,18 +109,16 @@ anim: { adc _12+1 sta yr+1 lda xr+1 + tax + clc + adc #<$18+$95 sta xpos + txa ora #$7f bmi !+ lda #0 !: - sta xpos+1 - lda xpos - clc - adc #$18+$95 - sta xpos - lda xpos+1 - adc #0 + adc #>$18+$95 sta xpos+1 lsr sprite_msb cmp #0 @@ -153,35 +156,44 @@ anim: { // mulf8s_prepared(signed byte register(Y) b) mulf8s_prepared: { .label memA = $fd + .label _8 = $f + .label _12 = $f .label m = 5 .label return = 5 + tya jsr mulf8u_prepared lda memA cmp #0 bpl b1 lda m+1 - sty $ff + sta _8 + tya + eor #$ff sec - sbc $ff + adc _8 sta m+1 b1: cpy #0 bpl b2 lda m+1 + sta _12 + lda memA + eor #$ff sec - sbc memA + adc _12 sta m+1 b2: rts } // Calculate fast multiply with a prepared unsigned byte to a word result // The prepared number is set by calling mulf8u_prepare(byte a) +// mulf8u_prepared(byte register(A) b) mulf8u_prepared: { .label resL = $fe .label memB = $ff .label return = 5 - sty memB - ldx memB + sta memB + tax sec sm1: lda mulf_sqr1_lo,x @@ -218,7 +230,7 @@ init: { sta SPRITES_ENABLE ldx #0 b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta sprites_ptr,x lda #GREEN sta SPRITES_COLS,x diff --git a/src/test/ref/examples/scrolllogo/scrolllogo.asm b/src/test/ref/examples/scrolllogo/scrolllogo.asm index 638b1528c..46983d01e 100644 --- a/src/test/ref/examples/scrolllogo/scrolllogo.asm +++ b/src/test/ref/examples/scrolllogo/scrolllogo.asm @@ -120,8 +120,8 @@ loop: { render_logo: { .label _3 = $f .label xpos = 9 - .label x_char = 4 .label logo_idx = 4 + .label logo_start = 4 lda xpos and #7 ora #VIC_MCM @@ -142,20 +142,21 @@ render_logo: { ror _3+1 ror _3 lda _3 - sta x_char + tax lda xpos+1 bmi b1 + stx logo_start ldy #0 - b2: - cpy x_char - bne b3 + b3: + cpy logo_start + bne b4 lda #0 sta logo_idx - b5: - cpy #$28 - bne b6 - rts b6: + cpy #$28 + bne b7 + rts + b7: lda logo_idx sta SCREEN,y lda #$28*1 @@ -180,8 +181,8 @@ render_logo: { sta SCREEN+$28*5,y iny inc logo_idx - jmp b5 - b3: + jmp b6 + b4: lda #0 sta SCREEN,y sta SCREEN+$28*1,y @@ -190,23 +191,23 @@ render_logo: { sta SCREEN+$28*4,y sta SCREEN+$28*5,y iny - jmp b2 + jmp b3 b1: - lda x_char + txa eor #$ff clc adc #1 sta logo_idx ldy #0 - b8: + b9: lda #$28 cmp logo_idx - bne b9 - b11: - cpy #$28 - bne b12 - rts + bne b10 b12: + cpy #$28 + bne b13 + rts + b13: lda #0 sta SCREEN,y sta SCREEN+$28*1,y @@ -215,8 +216,8 @@ render_logo: { sta SCREEN+$28*4,y sta SCREEN+$28*5,y iny - jmp b11 - b9: + jmp b12 + b10: lda logo_idx sta SCREEN,y lda #$28*1 @@ -241,7 +242,7 @@ render_logo: { sta SCREEN+$28*5,y iny inc logo_idx - jmp b8 + jmp b9 } // Generate signed word sinus table - with values in the range min-max. // sintab - the table to generate into @@ -254,7 +255,7 @@ sin16s_gen2: { .label _5 = $b .label _6 = $f .label _8 = $f - .label step = $1b + .label step = $19 .label sintab = 2 .label x = 5 .label i = 9 @@ -329,21 +330,25 @@ sin16s_gen2: { } // Multiply of two signed words to a signed double word // Fixes offsets introduced by using unsigned multiplication -// mul16s(signed word zeropage($17) a) +// mul16s(signed word zeropage($f) a) mul16s: { .label _9 = $f .label _16 = $f .label m = $b .label return = $b - .label a = $17 + .label a = $f lda a sta mul16u.a lda a+1 sta mul16u.a+1 lda #sin16s_gen2.ampl - sta mul16u.b+1 + sta mul16u.mb+1 + lda #>$10 + sta mul16u.mb+2 + lda #>sin16s_gen2.ampl>>$10 + sta mul16u.mb+3 jsr mul16u lda a+1 bpl b2 @@ -373,13 +378,7 @@ mul16u: { .label res = $b .label return = $b .label b = $f - lda b - sta mb - lda b+1 - sta mb+1 lda #0 - sta mb+2 - sta mb+3 sta res sta res+1 sta res+2 @@ -424,17 +423,18 @@ mul16u: { // sin16s(dword zeropage($b) x) sin16s: { .label _4 = $b + .label _20 = $f .label x = $b - .label return = $17 - .label x1 = $1f - .label x2 = $19 - .label x3 = $19 + .label return = $f + .label x1 = $1d + .label x2 = $17 + .label x3 = $17 .label x3_6 = $f - .label usinx = $17 - .label x4 = $19 + .label usinx = $1f + .label x4 = $17 .label x5 = $f .label x5_128 = $f - .label sinx = $17 + .label sinx = $f .label isUpper = 4 lda x+3 cmp #>PI_u4f28>>$10 @@ -580,9 +580,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff @@ -597,19 +605,26 @@ sin16s: { } // Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result. // The select parameter indicates how many of the highest bits of the 32-bit result to skip -// mulu16_sel(word zeropage($19) v1, word zeropage($f) v2, byte register(X) select) +// mulu16_sel(word zeropage($17) v1, word zeropage($f) v2, byte register(X) select) mulu16_sel: { .label _0 = $b .label _1 = $b - .label v1 = $19 + .label v1 = $17 .label v2 = $f .label return = $f - .label return_1 = $19 - .label return_10 = $19 + .label return_1 = $17 + .label return_10 = $17 lda v1 sta mul16u.a lda v1+1 sta mul16u.a+1 + lda mul16u.b + sta mul16u.mb + lda mul16u.b+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u cpx #0 beq !e+ @@ -632,7 +647,7 @@ mulu16_sel: { div32u16u: { .label quotient_hi = $11 .label quotient_lo = $f - .label return = $1b + .label return = $19 lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 diff --git a/src/test/ref/examples/sinplotter/sine-plotter.asm b/src/test/ref/examples/sinplotter/sine-plotter.asm index 76895de72..a7f77bdfb 100644 --- a/src/test/ref/examples/sinplotter/sine-plotter.asm +++ b/src/test/ref/examples/sinplotter/sine-plotter.asm @@ -36,7 +36,7 @@ .label sin2 = $1400 .label rem16u = 2 main: { - .const vicSelectGfxBank1_toDd001_return = 3^(>SCREEN)/$40 + .const vicSelectGfxBank1_toDd001_return = 3 .const toD0181_return = (>(SCREEN&$3fff)*4)|(>BITMAP)/4&$f sei // Disable normal interrupt @@ -176,6 +176,7 @@ render_sine: { bitmap_plot: { .label _1 = $10 .label plotter = 6 + .label plotter_1 = $10 .label x = 4 .label _3 = 6 lda bitmap_plot_yhi,x @@ -188,19 +189,19 @@ bitmap_plot: { lda x+1 and #>$fff8 sta _1+1 - lda plotter + lda plotter_1 clc - adc _1 - sta plotter - lda plotter+1 - adc _1+1 - sta plotter+1 + adc plotter + sta plotter_1 + lda plotter_1+1 + adc plotter+1 + sta plotter_1+1 lda x tay lda bitmap_plot_bit,y ldy #0 - ora (plotter),y - sta (plotter),y + ora (plotter_1),y + sta (plotter_1),y rts } // wrap_y(signed word zeropage(6) y) @@ -230,13 +231,13 @@ wrap_y: { sta y+1 jmp b3 b2: - sec lda y - sbc #$c8 + sec + sbc #<$c8 sta y - bcs !+ - dec y+1 - !: + lda y+1 + sbc #>$c8 + sta y+1 jmp b1 } // Generate signed word sinus table - with values in the range min-max. @@ -250,7 +251,7 @@ sin16s_gen2: { .label _5 = $c .label _6 = 6 .label _8 = 6 - .label step = $1b + .label step = $19 .label sintab = 2 .label x = 8 .label i = 4 @@ -325,21 +326,25 @@ sin16s_gen2: { } // Multiply of two signed words to a signed double word // Fixes offsets introduced by using unsigned multiplication -// mul16s(signed word zeropage($17) a) +// mul16s(signed word zeropage(6) a) mul16s: { .label _9 = 6 .label _16 = 6 .label m = $c .label return = $c - .label a = $17 + .label a = 6 lda a sta mul16u.a lda a+1 sta mul16u.a+1 lda #sin16s_gen2.ampl - sta mul16u.b+1 + sta mul16u.mb+1 + lda #>$10 + sta mul16u.mb+2 + lda #>sin16s_gen2.ampl>>$10 + sta mul16u.mb+3 jsr mul16u lda a+1 bpl b2 @@ -369,13 +374,7 @@ mul16u: { .label res = $c .label return = $c .label b = 6 - lda b - sta mb - lda b+1 - sta mb+1 lda #0 - sta mb+2 - sta mb+3 sta res sta res+1 sta res+2 @@ -420,17 +419,18 @@ mul16u: { // sin16s(dword zeropage($c) x) sin16s: { .label _4 = $c + .label _20 = 6 .label x = $c - .label return = $17 - .label x1 = $1f - .label x2 = $19 - .label x3 = $19 + .label return = 6 + .label x1 = $1d + .label x2 = $17 + .label x3 = $17 .label x3_6 = 6 - .label usinx = $17 - .label x4 = $19 + .label usinx = $1f + .label x4 = $17 .label x5 = 6 .label x5_128 = 6 - .label sinx = $17 + .label sinx = 6 .label isUpper = $16 lda x+3 cmp #>PI_u4f28>>$10 @@ -576,9 +576,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff @@ -593,19 +601,26 @@ sin16s: { } // Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result. // The select parameter indicates how many of the highest bits of the 32-bit result to skip -// mulu16_sel(word zeropage($19) v1, word zeropage(6) v2, byte register(X) select) +// mulu16_sel(word zeropage($17) v1, word zeropage(6) v2, byte register(X) select) mulu16_sel: { .label _0 = $c .label _1 = $c - .label v1 = $19 + .label v1 = $17 .label v2 = 6 .label return = 6 - .label return_1 = $19 - .label return_10 = $19 + .label return_1 = $17 + .label return_10 = $17 lda v1 sta mul16u.a lda v1+1 sta mul16u.a+1 + lda mul16u.b + sta mul16u.mb + lda mul16u.b+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u cpx #0 beq !e+ @@ -628,7 +643,7 @@ mulu16_sel: { div32u16u: { .label quotient_hi = $10 .label quotient_lo = 6 - .label return = $1b + .label return = $19 lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 @@ -742,7 +757,7 @@ bitmap_clear: { } // Initialize bitmap plotting tables bitmap_init: { - .label _3 = $16 + .label _7 = $16 .label yoffs = 2 ldx #0 lda #$80 @@ -763,15 +778,14 @@ bitmap_init: { ldx #0 b3: lda #7 - sax _3 + sax _7 lda yoffs - ora _3 + ora _7 sta bitmap_plot_ylo,x lda yoffs+1 sta bitmap_plot_yhi,x - txa - and #7 - cmp #7 + lda #7 + cmp _7 bne b4 clc lda yoffs diff --git a/src/test/ref/examples/sinsprites/sinus-sprites.asm b/src/test/ref/examples/sinsprites/sinus-sprites.asm index 6d699fc87..eddb6422e 100644 --- a/src/test/ref/examples/sinsprites/sinus-sprites.asm +++ b/src/test/ref/examples/sinsprites/sinus-sprites.asm @@ -596,7 +596,7 @@ place_sprites: { sta spr_x lda #0 sta j - lda #$ff&sprites/$40 + lda #sprites/$40 sta spr_id b1: lda spr_id diff --git a/src/test/ref/for-two-vars.asm b/src/test/ref/for-two-vars.asm new file mode 100644 index 000000000..cae2dddd5 --- /dev/null +++ b/src/test/ref/for-two-vars.asm @@ -0,0 +1,27 @@ +// Test a for-loop with two iterating variables +// Illustrates that for()-loops currently cannot contain two variable declarations. +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + .label sc = 2 + lda #SCREEN+$27 + sta sc+1 + ldx #0 + b1: + txa + ldy #0 + sta (sc),y + inx + lda sc + bne !+ + dec sc+1 + !: + dec sc + cpx #$28 + bcc b1 + rts +} diff --git a/src/test/ref/fragment-variations.asm b/src/test/ref/fragment-variations.asm new file mode 100644 index 000000000..4fea75dc1 --- /dev/null +++ b/src/test/ref/fragment-variations.asm @@ -0,0 +1,72 @@ +// Tests that ASM fragment variations works +// ASM fragment variations "cast" constants to different types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const SIZEOF_DWORD = 4 +main: { + .label screen = $400 + .label _0 = 2 + .label _1 = 2 + lda #$a + sta mul16u.a + lda #0 + sta mul16u.a+1 + lda #$a + sta mul16u.mb + lda #0 + sta mul16u.mb+1 + sta mul16u.mb+2 + sta mul16u.mb+3 + jsr mul16u + lda _0 + sta screen + lda _0+1 + sta screen+1 + lda _0+2 + sta screen+2 + lda _0+3 + sta screen+3 + lda #<$3e8 + sta mul16u.a + lda #>$3e8 + sta mul16u.a+1 + lda #<$3e8 + sta mul16u.mb + lda #>$3e8 + sta mul16u.mb+1 + lda #<$3e8>>$10 + sta mul16u.mb+2 + lda #>$3e8>>$10 + sta mul16u.mb+3 + jsr mul16u + lda _1 + sta screen+1*SIZEOF_DWORD + lda _1+1 + sta screen+1*SIZEOF_DWORD+1 + lda _1+2 + sta screen+1*SIZEOF_DWORD+2 + lda _1+3 + sta screen+1*SIZEOF_DWORD+3 + rts +} +// mul16u(word zeropage(6) a) +mul16u: { + .label return = 2 + .label mb = 2 + .label a = 6 + lda return + clc + adc a + sta return + lda return+1 + adc a+1 + sta return+1 + lda return+2 + adc #0 + sta return+2 + lda return+3 + adc #0 + sta return+3 + rts +} diff --git a/src/test/ref/function-pointer-noarg-3.asm b/src/test/ref/function-pointer-noarg-3.asm index a5efe51f9..6ef9b4501 100644 --- a/src/test/ref/function-pointer-noarg-3.asm +++ b/src/test/ref/function-pointer-noarg-3.asm @@ -13,18 +13,18 @@ main: { txa and #1 cmp #0 - beq b1 + beq b3 lda #fn2 sta f+1 - jmp b3 - b1: + jmp b4 + b3: lda #fn1 sta f+1 - b3: + b4: jsr ff jmp b2 diff --git a/src/test/ref/function-pointer-noarg-call-2.asm b/src/test/ref/function-pointer-noarg-call-2.asm index f751aa759..9d047951b 100644 --- a/src/test/ref/function-pointer-noarg-call-2.asm +++ b/src/test/ref/function-pointer-noarg-call-2.asm @@ -12,18 +12,18 @@ main: { lda #1 and i cmp #0 - beq b1 + beq b3 lda #fn2 sta f+1 - jmp b3 - b1: + jmp b4 + b3: lda #fn1 sta f+1 - b3: + b4: jsr bi_f jmp b2 bi_f: diff --git a/src/test/ref/function-pointer-noarg-call-8.asm b/src/test/ref/function-pointer-noarg-call-8.asm index 6ea60224a..c90b2daa7 100644 --- a/src/test/ref/function-pointer-noarg-call-8.asm +++ b/src/test/ref/function-pointer-noarg-call-8.asm @@ -3,8 +3,8 @@ :BasicUpstart(bbegin) .pc = $80d "Program" .label SCREEN = $400 - .label msg = 4 - .label idx = 3 + .label msg = 3 + .label idx = 5 bbegin: lda #<0 sta msg @@ -13,7 +13,6 @@ bbegin: jsr main rts main: { - .label f = hello lda #msg1 @@ -31,7 +30,7 @@ do10: { lda #0 sta i b1: - jsr main.f + jsr hello inc i lda #$a cmp i diff --git a/src/test/ref/function-pointer-return.asm b/src/test/ref/function-pointer-return.asm index 13febb158..c244eb54d 100644 --- a/src/test/ref/function-pointer-return.asm +++ b/src/test/ref/function-pointer-return.asm @@ -11,18 +11,18 @@ main: { txa and #1 cmp #0 - beq b1 + beq b3 lda #fn2 sta f+1 - jmp b3 - b1: + jmp b4 + b3: lda #fn1 sta f+1 - b3: + b4: lda f sta SCREEN jmp b2 diff --git a/src/test/ref/gfxbank.asm b/src/test/ref/gfxbank.asm new file mode 100644 index 000000000..54c84cffb --- /dev/null +++ b/src/test/ref/gfxbank.asm @@ -0,0 +1,16 @@ +// Test minimization of constants +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // CIA#2 Port A: Serial bus, RS-232, VIC memory bank + .label CIA2_PORT_A = $dd00 + // CIA #2 Port A data direction register. + .label CIA2_PORT_A_DDR = $dd02 +main: { + .const vicSelectGfxBank1_toDd001_return = 3 + lda #3 + sta CIA2_PORT_A_DDR + lda #vicSelectGfxBank1_toDd001_return + sta CIA2_PORT_A + rts +} diff --git a/src/test/ref/halfscii.asm b/src/test/ref/halfscii.asm index 179529db1..b452a7471 100644 --- a/src/test/ref/halfscii.asm +++ b/src/test/ref/halfscii.asm @@ -7,10 +7,11 @@ .label D018 = $d018 .label CHARSET4 = $2800 main: { - .label _1 = 6 - .label _11 = 6 - .label _21 = 6 - .label _30 = 6 + .label _1 = 8 + .label _11 = 8 + .label _21 = 8 + .label _30 = 8 + .label chargen1 = 6 .label charset4 = 4 .label chargen = 2 sei @@ -25,13 +26,19 @@ main: { lda #>CHARGEN sta chargen+1 b1: + lda chargen + clc + adc #1 + sta chargen1 + lda chargen+1 + adc #0 + sta chargen1+1 lda #$60 ldy #0 and (chargen),y sta _1 lda #$60 - ldy #1 - and (chargen),y + and (chargen1),y lsr lsr ora _1 @@ -54,8 +61,7 @@ main: { and (chargen),y sta _11 lda #$18 - ldy #1 - and (chargen),y + and (chargen1),y lsr lsr ora _11 @@ -75,8 +81,7 @@ main: { asl sta _21 lda #6 - ldy #1 - and (chargen),y + and (chargen1),y lsr ora _21 tay @@ -95,8 +100,7 @@ main: { asl sta _30 lda #1 - tay - and (chargen),y + and (chargen1),y ora _30 tay lda bits_count,y diff --git a/src/test/ref/concat-char.asm b/src/test/ref/helloworld0.asm similarity index 53% rename from src/test/ref/concat-char.asm rename to src/test/ref/helloworld0.asm index 921520657..4d3606742 100644 --- a/src/test/ref/concat-char.asm +++ b/src/test/ref/helloworld0.asm @@ -1,16 +1,16 @@ -// Concatenate a char to a string +// Tests minimal hello world .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" + .label SCREEN = $400 main: { - .label screen = $400 ldx #0 b1: lda msg,x - sta screen,x + sta SCREEN,x inx - cpx #3 + cpx #$c bne b1 rts - msg: .text "cm"+'l' } + msg: .text "hello world!@" diff --git a/src/test/ref/hex2dec-ptrptr.asm b/src/test/ref/hex2dec-ptrptr.asm new file mode 100644 index 000000000..af42a6775 --- /dev/null +++ b/src/test/ref/hex2dec-ptrptr.asm @@ -0,0 +1,127 @@ +// Testing binary to hex conversion using pointer to pointer +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + jsr cls + lda #<$400 + sta utoa16w.dst + lda #>$400 + sta utoa16w.dst+1 + lda #0 + sta utoa16w.value + sta utoa16w.value+1 + jsr utoa16w + lda #<$400+$28 + sta utoa16w.dst + lda #>$400+$28 + sta utoa16w.dst+1 + lda #<$4d2 + sta utoa16w.value + lda #>$4d2 + sta utoa16w.value+1 + jsr utoa16w + lda #<$400+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28 + sta utoa16w.dst+1 + lda #<$162e + sta utoa16w.value + lda #>$162e + sta utoa16w.value+1 + jsr utoa16w + lda #<$400+$28+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28+$28 + sta utoa16w.dst+1 + lda #<$270f + sta utoa16w.value + lda #>$270f + sta utoa16w.value+1 + jsr utoa16w + lda #<$400+$28+$28+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28+$28+$28 + sta utoa16w.dst+1 + lda #<$e608 + sta utoa16w.value + lda #>$e608 + sta utoa16w.value+1 + jsr utoa16w + rts +} +// Hexadecimal utoa() for an unsigned int (16bits) +// utoa16w(word zeropage(2) value, byte* zeropage(4) dst) +utoa16w: { + .label value = 2 + .label dst = 4 + lda value+1 + lsr + lsr + lsr + lsr + ldx #0 + jsr utoa16n + lda value+1 + and #$f + jsr utoa16n + lda value + lsr + lsr + lsr + lsr + jsr utoa16n + lda value + and #$f + ldx #1 + jsr utoa16n + lda #0 + tay + sta (dst),y + rts +} +// Hexadecimal utoa() for a single nybble +// utoa16n(byte register(A) nybble, byte register(X) started) +utoa16n: { + cmp #0 + beq b1 + ldx #1 + b1: + cpx #0 + beq breturn + tay + lda DIGITS,y + ldy #0 + sta (utoa16w.dst),y + inc utoa16w.dst + bne !+ + inc utoa16w.dst+1 + !: + breturn: + rts +} +cls: { + .label screen = $400 + .label sc = 2 + lda #screen + sta sc+1 + b1: + lda #' ' + ldy #0 + sta (sc),y + inc sc + bne !+ + inc sc+1 + !: + lda sc+1 + cmp #>screen+$3e7+1 + bne b1 + lda sc + cmp #$400 + sta utoa16w.dst+1 + lda #0 + sta utoa16w.value + sta utoa16w.value+1 + jsr utoa16w + inc bordercol + lda #<$400+$28 + sta utoa16w.dst + lda #>$400+$28 + sta utoa16w.dst+1 + lda #<$4d2 + sta utoa16w.value + lda #>$4d2 + sta utoa16w.value+1 + jsr utoa16w + inc bordercol + lda #<$400+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28 + sta utoa16w.dst+1 + lda #<$162e + sta utoa16w.value + lda #>$162e + sta utoa16w.value+1 + jsr utoa16w + inc bordercol + lda #<$400+$28+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28+$28 + sta utoa16w.dst+1 + lda #<$270f + sta utoa16w.value + lda #>$270f + sta utoa16w.value+1 + jsr utoa16w + inc bordercol + lda #<$400+$28+$28+$28+$28 + sta utoa16w.dst + lda #>$400+$28+$28+$28+$28 + sta utoa16w.dst+1 + lda #<$e608 + sta utoa16w.value + lda #>$e608 + sta utoa16w.value+1 + jsr utoa16w + ldx raster + lda #0 + sta bordercol + txa + sec + sbc time_start + sta utoa10w.value + lda #0 + sta utoa10w.value+1 + jsr utoa10w + ldx #0 + b3: + lda msg,x + sta $400+$28+$28+$28+$28+$50+3,x + inx + lda msg,x + cmp #0 + bne b3 + jmp b1 + msg: .text "raster lines@" +} +// Decimal utoa() without using multiply or divide +// utoa10w(word zeropage(2) value, byte* zeropage(6) dst) +utoa10w: { + .label value = 2 + .label digit = 4 + .label dst = 6 + .label bStarted = 5 + lda #<$400+$28+$28+$28+$28+$50 + sta dst + lda #>$400+$28+$28+$28+$28+$50 + sta dst+1 + lda #0 + sta bStarted + sta digit + tax + b1: + txa + asl + tay + lda UTOA10_SUB+1,y + cmp value+1 + bne !+ + lda UTOA10_SUB,y + cmp value + beq b2 + !: + bcc b2 + txa + and #1 + cmp #0 + beq b6 + lda bStarted + cmp #0 + beq b7 + ldy digit + lda DIGITS,y + ldy #0 + sta (dst),y + inc dst + bne !+ + inc dst+1 + !: + b7: + lda #0 + sta digit + b6: + inx + cpx #8 + bne b1 + lda value + tay + lda DIGITS,y + ldy #0 + sta (dst),y + inc dst + bne !+ + inc dst+1 + !: + lda #0 + tay + sta (dst),y + rts + b2: + lda UTOA10_VAL,x + clc + adc digit + sta digit + txa + asl + tay + sec + lda value + sbc UTOA10_SUB,y + sta value + lda value+1 + sbc UTOA10_SUB+1,y + sta value+1 + lda #1 + sta bStarted + jmp b1 +} +// Hexadecimal utoa() for an unsigned int (16bits) +// utoa16w(word zeropage(2) value, byte* zeropage(6) dst) +utoa16w: { + .label value = 2 + .label dst = 6 + lda value+1 + lsr + lsr + lsr + lsr + ldx #0 + jsr utoa16n + lda value+1 + and #$f + jsr utoa16n + lda value + lsr + lsr + lsr + lsr + jsr utoa16n + lda value + and #$f + ldx #1 + jsr utoa16n + lda #0 + tay + sta (dst),y + rts +} +// Hexadecimal utoa() for a single nybble +// utoa16n(byte register(A) nybble, byte register(X) started) +utoa16n: { + cmp #0 + beq b1 + ldx #1 + b1: + cpx #0 + beq breturn + tay + lda DIGITS,y + ldy #0 + sta (utoa16w.dst),y + inc utoa16w.dst + bne !+ + inc utoa16w.dst+1 + !: + breturn: + rts +} +cls: { + .label screen = $400 + .label sc = 2 + lda #screen + sta sc+1 + b1: + lda #' ' + ldy #0 + sta (sc),y + inc sc + bne !+ + inc sc+1 + !: + lda sc+1 + cmp #>screen+$3e7+1 + bne b1 + lda sc + cmp #msg_2 sta msg+1 - jmp b1 - b2: + jmp b2 + b1: lda #msg_1 sta msg+1 - b1: + b2: jsr print rts msg_1: .text "Hello @" diff --git a/src/test/ref/inline-string-3.asm b/src/test/ref/inline-string-3.asm index aaf848ee9..1881a03a3 100644 --- a/src/test/ref/inline-string-3.asm +++ b/src/test/ref/inline-string-3.asm @@ -7,6 +7,7 @@ main: { .label PTR = $9ffe .label SCREEN = $400 + .label ptr = 2 .label _6 = 2 lda #w + sta screen+1 + rts +} diff --git a/src/test/ref/inline-word-1.asm b/src/test/ref/inline-word-1.asm new file mode 100644 index 000000000..bb6135dcc --- /dev/null +++ b/src/test/ref/inline-word-1.asm @@ -0,0 +1,13 @@ +// Tests minimal inline word +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = 1*$100+2 + lda #w + sta screen+1 + rts +} diff --git a/src/test/ref/inline-word-2.asm b/src/test/ref/inline-word-2.asm new file mode 100644 index 000000000..bb6135dcc --- /dev/null +++ b/src/test/ref/inline-word-2.asm @@ -0,0 +1,13 @@ +// Tests minimal inline word +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = 1*$100+2 + lda #w + sta screen+1 + rts +} diff --git a/src/test/ref/inline-word.asm b/src/test/ref/inline-word.asm index 505c1ebc1..7b80c88b1 100644 --- a/src/test/ref/inline-word.asm +++ b/src/test/ref/inline-word.asm @@ -4,6 +4,7 @@ .label SCREEN = $400 main: { .label w = 3 + .label sc = 3 .label h = 2 lda #0 sta h @@ -17,7 +18,7 @@ main: { stx w lda #'*' ldy #0 - sta (w),y + sta (sc),y inx cpx #8 bne b2 diff --git a/src/test/ref/int-conversion.asm b/src/test/ref/int-conversion.asm new file mode 100644 index 000000000..9ad08351c --- /dev/null +++ b/src/test/ref/int-conversion.asm @@ -0,0 +1,242 @@ +// Tests different integer literal types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const TYPEID_BYTE = 1 + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_WORD = 3 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_DWORD = 5 + .const TYPEID_SIGNED_DWORD = 6 + .const RED = 2 + .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 +main: { + .label s = 2 + lda #SCREEN + sta s+1 + b1: + lda #' ' + ldy #0 + sta (s),y + inc s + bne !+ + inc s+1 + !: + lda s+1 + cmp #>SCREEN+$3e8 + bcc b1 + bne !+ + lda s + cmp #@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label s = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte*) main::s#2 = (const byte*) SCREEN#0 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #SCREEN + sta s+1 + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte*) main::s#2 = (byte*) main::s#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] *((byte*) main::s#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (s),y + //SEG17 [7] (byte*) main::s#1 ← ++ (byte*) main::s#2 -- pbuz1=_inc_pbuz1 + inc s + bne !+ + inc s+1 + !: + //SEG18 [8] if((byte*) main::s#1<(const byte*) SCREEN#0+(word) $3e8) goto main::@1 -- pbuz1_lt_pbuc1_then_la1 + lda s+1 + cmp #>SCREEN+$3e8 + bcc b1_from_b1 + bne !+ + lda s + cmp #main::@2] + b2_from_b1: + jmp b2 + //SEG20 main::@2 + b2: + //SEG21 [10] call testUnaryOperator + //SEG22 [94] phi from main::@2 to testUnaryOperator [phi:main::@2->testUnaryOperator] + testUnaryOperator_from_b2: + jsr testUnaryOperator + //SEG23 [11] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + b3_from_b2: + jmp b3 + //SEG24 main::@3 + b3: + //SEG25 [12] call testBinaryOperator + //SEG26 [14] phi from main::@3 to testBinaryOperator [phi:main::@3->testBinaryOperator] + testBinaryOperator_from_b3: + jsr testBinaryOperator + jmp breturn + //SEG27 main::@return + breturn: + //SEG28 [13] return + rts +} +//SEG29 testBinaryOperator +testBinaryOperator: { + //SEG30 [15] call assertType + //SEG31 [87] phi from testBinaryOperator to assertType [phi:testBinaryOperator->assertType] + assertType_from_testBinaryOperator: + //SEG32 [87] phi (byte) idx#105 = (byte) $28 [phi:testBinaryOperator->assertType#0] -- vbuz1=vbuc1 + lda #$28 + sta idx + //SEG33 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG34 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG35 [16] phi from testBinaryOperator to testBinaryOperator::@1 [phi:testBinaryOperator->testBinaryOperator::@1] + b1_from_testBinaryOperator: + jmp b1 + //SEG36 testBinaryOperator::@1 + b1: + //SEG37 [17] call assertType + //SEG38 [87] phi from testBinaryOperator::@1 to assertType [phi:testBinaryOperator::@1->assertType] + assertType_from_b1: + //SEG39 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@1->assertType#0] -- register_copy + //SEG40 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG41 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@1->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG42 [18] phi from testBinaryOperator::@1 to testBinaryOperator::@2 [phi:testBinaryOperator::@1->testBinaryOperator::@2] + b2_from_b1: + jmp b2 + //SEG43 testBinaryOperator::@2 + b2: + //SEG44 [19] call assertType + //SEG45 [87] phi from testBinaryOperator::@2 to assertType [phi:testBinaryOperator::@2->assertType] + assertType_from_b2: + //SEG46 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@2->assertType#0] -- register_copy + //SEG47 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG48 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@2->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG49 [20] phi from testBinaryOperator::@2 to testBinaryOperator::@3 [phi:testBinaryOperator::@2->testBinaryOperator::@3] + b3_from_b2: + jmp b3 + //SEG50 testBinaryOperator::@3 + b3: + //SEG51 [21] call assertType + //SEG52 [87] phi from testBinaryOperator::@3 to assertType [phi:testBinaryOperator::@3->assertType] + assertType_from_b3: + //SEG53 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@3->assertType#0] -- register_copy + //SEG54 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG55 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@3->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG56 [22] phi from testBinaryOperator::@3 to testBinaryOperator::@4 [phi:testBinaryOperator::@3->testBinaryOperator::@4] + b4_from_b3: + jmp b4 + //SEG57 testBinaryOperator::@4 + b4: + //SEG58 [23] call assertType + //SEG59 [87] phi from testBinaryOperator::@4 to assertType [phi:testBinaryOperator::@4->assertType] + assertType_from_b4: + //SEG60 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@4->assertType#0] -- register_copy + //SEG61 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG62 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@4->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG63 [24] phi from testBinaryOperator::@4 to testBinaryOperator::@5 [phi:testBinaryOperator::@4->testBinaryOperator::@5] + b5_from_b4: + jmp b5 + //SEG64 testBinaryOperator::@5 + b5: + //SEG65 [25] call assertType + //SEG66 [87] phi from testBinaryOperator::@5 to assertType [phi:testBinaryOperator::@5->assertType] + assertType_from_b5: + //SEG67 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@5->assertType#0] -- register_copy + //SEG68 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG69 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@5->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp b6 + //SEG70 testBinaryOperator::@6 + b6: + //SEG71 [26] (byte) idx#19 ← ++ (byte) idx#108 -- vbuz1=_inc_vbuz1 + inc idx + //SEG72 [27] call assertType + //SEG73 [87] phi from testBinaryOperator::@6 to assertType [phi:testBinaryOperator::@6->assertType] + assertType_from_b6: + //SEG74 [87] phi (byte) idx#105 = (byte) idx#19 [phi:testBinaryOperator::@6->assertType#0] -- register_copy + //SEG75 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG76 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@6->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG77 [28] phi from testBinaryOperator::@6 to testBinaryOperator::@7 [phi:testBinaryOperator::@6->testBinaryOperator::@7] + b7_from_b6: + jmp b7 + //SEG78 testBinaryOperator::@7 + b7: + //SEG79 [29] call assertType + //SEG80 [87] phi from testBinaryOperator::@7 to assertType [phi:testBinaryOperator::@7->assertType] + assertType_from_b7: + //SEG81 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@7->assertType#0] -- register_copy + //SEG82 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testBinaryOperator::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG83 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testBinaryOperator::@7->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t1 + jsr assertType + //SEG84 [30] phi from testBinaryOperator::@7 to testBinaryOperator::@8 [phi:testBinaryOperator::@7->testBinaryOperator::@8] + b8_from_b7: + jmp b8 + //SEG85 testBinaryOperator::@8 + b8: + //SEG86 [31] call assertType + //SEG87 [87] phi from testBinaryOperator::@8 to assertType [phi:testBinaryOperator::@8->assertType] + assertType_from_b8: + //SEG88 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@8->assertType#0] -- register_copy + //SEG89 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG90 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@8->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG91 [32] phi from testBinaryOperator::@8 to testBinaryOperator::@9 [phi:testBinaryOperator::@8->testBinaryOperator::@9] + b9_from_b8: + jmp b9 + //SEG92 testBinaryOperator::@9 + b9: + //SEG93 [33] call assertType + //SEG94 [87] phi from testBinaryOperator::@9 to assertType [phi:testBinaryOperator::@9->assertType] + assertType_from_b9: + //SEG95 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@9->assertType#0] -- register_copy + //SEG96 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG97 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@9->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG98 [34] phi from testBinaryOperator::@9 to testBinaryOperator::@10 [phi:testBinaryOperator::@9->testBinaryOperator::@10] + b10_from_b9: + jmp b10 + //SEG99 testBinaryOperator::@10 + b10: + //SEG100 [35] call assertType + //SEG101 [87] phi from testBinaryOperator::@10 to assertType [phi:testBinaryOperator::@10->assertType] + assertType_from_b10: + //SEG102 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@10->assertType#0] -- register_copy + //SEG103 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG104 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@10->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG105 [36] phi from testBinaryOperator::@10 to testBinaryOperator::@11 [phi:testBinaryOperator::@10->testBinaryOperator::@11] + b11_from_b10: + jmp b11 + //SEG106 testBinaryOperator::@11 + b11: + //SEG107 [37] call assertType + //SEG108 [87] phi from testBinaryOperator::@11 to assertType [phi:testBinaryOperator::@11->assertType] + assertType_from_b11: + //SEG109 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@11->assertType#0] -- register_copy + //SEG110 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG111 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@11->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp b12 + //SEG112 testBinaryOperator::@12 + b12: + //SEG113 [38] (byte) idx#26 ← ++ (byte) idx#108 -- vbuz1=_inc_vbuz1 + inc idx + //SEG114 [39] call assertType + //SEG115 [87] phi from testBinaryOperator::@12 to assertType [phi:testBinaryOperator::@12->assertType] + assertType_from_b12: + //SEG116 [87] phi (byte) idx#105 = (byte) idx#26 [phi:testBinaryOperator::@12->assertType#0] -- register_copy + //SEG117 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG118 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@12->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG119 [40] phi from testBinaryOperator::@12 to testBinaryOperator::@13 [phi:testBinaryOperator::@12->testBinaryOperator::@13] + b13_from_b12: + jmp b13 + //SEG120 testBinaryOperator::@13 + b13: + //SEG121 [41] call assertType + //SEG122 [87] phi from testBinaryOperator::@13 to assertType [phi:testBinaryOperator::@13->assertType] + assertType_from_b13: + //SEG123 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@13->assertType#0] -- register_copy + //SEG124 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG125 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@13->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG126 [42] phi from testBinaryOperator::@13 to testBinaryOperator::@14 [phi:testBinaryOperator::@13->testBinaryOperator::@14] + b14_from_b13: + jmp b14 + //SEG127 testBinaryOperator::@14 + b14: + //SEG128 [43] call assertType + //SEG129 [87] phi from testBinaryOperator::@14 to assertType [phi:testBinaryOperator::@14->assertType] + assertType_from_b14: + //SEG130 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@14->assertType#0] -- register_copy + //SEG131 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG132 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@14->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG133 [44] phi from testBinaryOperator::@14 to testBinaryOperator::@15 [phi:testBinaryOperator::@14->testBinaryOperator::@15] + b15_from_b14: + jmp b15 + //SEG134 testBinaryOperator::@15 + b15: + //SEG135 [45] call assertType + //SEG136 [87] phi from testBinaryOperator::@15 to assertType [phi:testBinaryOperator::@15->assertType] + assertType_from_b15: + //SEG137 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@15->assertType#0] -- register_copy + //SEG138 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@15->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG139 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@15->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG140 [46] phi from testBinaryOperator::@15 to testBinaryOperator::@16 [phi:testBinaryOperator::@15->testBinaryOperator::@16] + b16_from_b15: + jmp b16 + //SEG141 testBinaryOperator::@16 + b16: + //SEG142 [47] call assertType + //SEG143 [87] phi from testBinaryOperator::@16 to assertType [phi:testBinaryOperator::@16->assertType] + assertType_from_b16: + //SEG144 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@16->assertType#0] -- register_copy + //SEG145 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@16->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG146 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@16->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG147 [48] phi from testBinaryOperator::@16 to testBinaryOperator::@17 [phi:testBinaryOperator::@16->testBinaryOperator::@17] + b17_from_b16: + jmp b17 + //SEG148 testBinaryOperator::@17 + b17: + //SEG149 [49] call assertType + //SEG150 [87] phi from testBinaryOperator::@17 to assertType [phi:testBinaryOperator::@17->assertType] + assertType_from_b17: + //SEG151 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@17->assertType#0] -- register_copy + //SEG152 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@17->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG153 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@17->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG154 [50] phi from testBinaryOperator::@17 to testBinaryOperator::@18 [phi:testBinaryOperator::@17->testBinaryOperator::@18] + b18_from_b17: + jmp b18 + //SEG155 testBinaryOperator::@18 + b18: + //SEG156 [51] call assertType + //SEG157 [87] phi from testBinaryOperator::@18 to assertType [phi:testBinaryOperator::@18->assertType] + assertType_from_b18: + //SEG158 [87] phi (byte) idx#105 = (byte) $50 [phi:testBinaryOperator::@18->assertType#0] -- vbuz1=vbuc1 + lda #$50 + sta idx + //SEG159 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@18->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG160 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@18->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG161 [52] phi from testBinaryOperator::@18 to testBinaryOperator::@19 [phi:testBinaryOperator::@18->testBinaryOperator::@19] + b19_from_b18: + jmp b19 + //SEG162 testBinaryOperator::@19 + b19: + //SEG163 [53] call assertType + //SEG164 [87] phi from testBinaryOperator::@19 to assertType [phi:testBinaryOperator::@19->assertType] + assertType_from_b19: + //SEG165 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@19->assertType#0] -- register_copy + //SEG166 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@19->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG167 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@19->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG168 [54] phi from testBinaryOperator::@19 to testBinaryOperator::@20 [phi:testBinaryOperator::@19->testBinaryOperator::@20] + b20_from_b19: + jmp b20 + //SEG169 testBinaryOperator::@20 + b20: + //SEG170 [55] call assertType + //SEG171 [87] phi from testBinaryOperator::@20 to assertType [phi:testBinaryOperator::@20->assertType] + assertType_from_b20: + //SEG172 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@20->assertType#0] -- register_copy + //SEG173 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@20->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG174 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@20->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG175 [56] phi from testBinaryOperator::@20 to testBinaryOperator::@21 [phi:testBinaryOperator::@20->testBinaryOperator::@21] + b21_from_b20: + jmp b21 + //SEG176 testBinaryOperator::@21 + b21: + //SEG177 [57] call assertType + //SEG178 [87] phi from testBinaryOperator::@21 to assertType [phi:testBinaryOperator::@21->assertType] + assertType_from_b21: + //SEG179 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@21->assertType#0] -- register_copy + //SEG180 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@21->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG181 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@21->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG182 [58] phi from testBinaryOperator::@21 to testBinaryOperator::@22 [phi:testBinaryOperator::@21->testBinaryOperator::@22] + b22_from_b21: + jmp b22 + //SEG183 testBinaryOperator::@22 + b22: + //SEG184 [59] call assertType + //SEG185 [87] phi from testBinaryOperator::@22 to assertType [phi:testBinaryOperator::@22->assertType] + assertType_from_b22: + //SEG186 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@22->assertType#0] -- register_copy + //SEG187 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@22->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG188 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@22->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG189 [60] phi from testBinaryOperator::@22 to testBinaryOperator::@23 [phi:testBinaryOperator::@22->testBinaryOperator::@23] + b23_from_b22: + jmp b23 + //SEG190 testBinaryOperator::@23 + b23: + //SEG191 [61] call assertType + //SEG192 [87] phi from testBinaryOperator::@23 to assertType [phi:testBinaryOperator::@23->assertType] + assertType_from_b23: + //SEG193 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@23->assertType#0] -- register_copy + //SEG194 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@23->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG195 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@23->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp b24 + //SEG196 testBinaryOperator::@24 + b24: + //SEG197 [62] (byte) idx#40 ← ++ (byte) idx#108 -- vbuz1=_inc_vbuz1 + inc idx + //SEG198 [63] call assertType + //SEG199 [87] phi from testBinaryOperator::@24 to assertType [phi:testBinaryOperator::@24->assertType] + assertType_from_b24: + //SEG200 [87] phi (byte) idx#105 = (byte) idx#40 [phi:testBinaryOperator::@24->assertType#0] -- register_copy + //SEG201 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@24->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG202 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@24->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG203 [64] phi from testBinaryOperator::@24 to testBinaryOperator::@25 [phi:testBinaryOperator::@24->testBinaryOperator::@25] + b25_from_b24: + jmp b25 + //SEG204 testBinaryOperator::@25 + b25: + //SEG205 [65] call assertType + //SEG206 [87] phi from testBinaryOperator::@25 to assertType [phi:testBinaryOperator::@25->assertType] + assertType_from_b25: + //SEG207 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@25->assertType#0] -- register_copy + //SEG208 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@25->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG209 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@25->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG210 [66] phi from testBinaryOperator::@25 to testBinaryOperator::@26 [phi:testBinaryOperator::@25->testBinaryOperator::@26] + b26_from_b25: + jmp b26 + //SEG211 testBinaryOperator::@26 + b26: + //SEG212 [67] call assertType + //SEG213 [87] phi from testBinaryOperator::@26 to assertType [phi:testBinaryOperator::@26->assertType] + assertType_from_b26: + //SEG214 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@26->assertType#0] -- register_copy + //SEG215 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@26->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG216 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@26->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG217 [68] phi from testBinaryOperator::@26 to testBinaryOperator::@27 [phi:testBinaryOperator::@26->testBinaryOperator::@27] + b27_from_b26: + jmp b27 + //SEG218 testBinaryOperator::@27 + b27: + //SEG219 [69] call assertType + //SEG220 [87] phi from testBinaryOperator::@27 to assertType [phi:testBinaryOperator::@27->assertType] + assertType_from_b27: + //SEG221 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@27->assertType#0] -- register_copy + //SEG222 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@27->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG223 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@27->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG224 [70] phi from testBinaryOperator::@27 to testBinaryOperator::@28 [phi:testBinaryOperator::@27->testBinaryOperator::@28] + b28_from_b27: + jmp b28 + //SEG225 testBinaryOperator::@28 + b28: + //SEG226 [71] call assertType + //SEG227 [87] phi from testBinaryOperator::@28 to assertType [phi:testBinaryOperator::@28->assertType] + assertType_from_b28: + //SEG228 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@28->assertType#0] -- register_copy + //SEG229 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@28->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG230 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@28->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG231 [72] phi from testBinaryOperator::@28 to testBinaryOperator::@29 [phi:testBinaryOperator::@28->testBinaryOperator::@29] + b29_from_b28: + jmp b29 + //SEG232 testBinaryOperator::@29 + b29: + //SEG233 [73] call assertType + //SEG234 [87] phi from testBinaryOperator::@29 to assertType [phi:testBinaryOperator::@29->assertType] + assertType_from_b29: + //SEG235 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@29->assertType#0] -- register_copy + //SEG236 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@29->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG237 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@29->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + jmp b30 + //SEG238 testBinaryOperator::@30 + b30: + //SEG239 [74] (byte) idx#47 ← ++ (byte) idx#108 -- vbuz1=_inc_vbuz1 + inc idx + //SEG240 [75] call assertType + //SEG241 [87] phi from testBinaryOperator::@30 to assertType [phi:testBinaryOperator::@30->assertType] + assertType_from_b30: + //SEG242 [87] phi (byte) idx#105 = (byte) idx#47 [phi:testBinaryOperator::@30->assertType#0] -- register_copy + //SEG243 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@30->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG244 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@30->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG245 [76] phi from testBinaryOperator::@30 to testBinaryOperator::@31 [phi:testBinaryOperator::@30->testBinaryOperator::@31] + b31_from_b30: + jmp b31 + //SEG246 testBinaryOperator::@31 + b31: + //SEG247 [77] call assertType + //SEG248 [87] phi from testBinaryOperator::@31 to assertType [phi:testBinaryOperator::@31->assertType] + assertType_from_b31: + //SEG249 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@31->assertType#0] -- register_copy + //SEG250 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@31->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG251 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@31->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG252 [78] phi from testBinaryOperator::@31 to testBinaryOperator::@32 [phi:testBinaryOperator::@31->testBinaryOperator::@32] + b32_from_b31: + jmp b32 + //SEG253 testBinaryOperator::@32 + b32: + //SEG254 [79] call assertType + //SEG255 [87] phi from testBinaryOperator::@32 to assertType [phi:testBinaryOperator::@32->assertType] + assertType_from_b32: + //SEG256 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@32->assertType#0] -- register_copy + //SEG257 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@32->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG258 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@32->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG259 [80] phi from testBinaryOperator::@32 to testBinaryOperator::@33 [phi:testBinaryOperator::@32->testBinaryOperator::@33] + b33_from_b32: + jmp b33 + //SEG260 testBinaryOperator::@33 + b33: + //SEG261 [81] call assertType + //SEG262 [87] phi from testBinaryOperator::@33 to assertType [phi:testBinaryOperator::@33->assertType] + assertType_from_b33: + //SEG263 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@33->assertType#0] -- register_copy + //SEG264 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@33->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG265 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@33->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG266 [82] phi from testBinaryOperator::@33 to testBinaryOperator::@34 [phi:testBinaryOperator::@33->testBinaryOperator::@34] + b34_from_b33: + jmp b34 + //SEG267 testBinaryOperator::@34 + b34: + //SEG268 [83] call assertType + //SEG269 [87] phi from testBinaryOperator::@34 to assertType [phi:testBinaryOperator::@34->assertType] + assertType_from_b34: + //SEG270 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@34->assertType#0] -- register_copy + //SEG271 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@34->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG272 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@34->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG273 [84] phi from testBinaryOperator::@34 to testBinaryOperator::@35 [phi:testBinaryOperator::@34->testBinaryOperator::@35] + b35_from_b34: + jmp b35 + //SEG274 testBinaryOperator::@35 + b35: + //SEG275 [85] call assertType + //SEG276 [87] phi from testBinaryOperator::@35 to assertType [phi:testBinaryOperator::@35->assertType] + assertType_from_b35: + //SEG277 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@35->assertType#0] -- register_copy + //SEG278 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@35->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG279 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@35->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp breturn + //SEG280 testBinaryOperator::@return + breturn: + //SEG281 [86] return + rts +} +//SEG282 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte zeropage(4) t1, byte zeropage(5) t2) +assertType: { + .label t1 = 4 + .label t2 = 5 + //SEG283 [88] if((byte) assertType::t1#42==(byte) assertType::t2#42) goto assertType::@1 -- vbuz1_eq_vbuz2_then_la1 + lda t1 + cmp t2 + beq b1 + jmp b3 + //SEG284 assertType::@3 + b3: + //SEG285 [89] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) RED#0 -- pbuc1_derefidx_vbuz1=vbuc2 + lda #RED + ldy idx + sta COLS,y + jmp b2 + //SEG286 assertType::@2 + b2: + //SEG287 [90] *((const byte*) SCREEN#0 + (byte) idx#105) ← (byte) assertType::t1#42 -- pbuc1_derefidx_vbuz1=vbuz2 + lda t1 + ldy idx + sta SCREEN,y + //SEG288 [91] (byte) idx#108 ← ++ (byte) idx#105 -- vbuz1=_inc_vbuz1 + inc idx + jmp breturn + //SEG289 assertType::@return + breturn: + //SEG290 [92] return + rts + //SEG291 assertType::@1 + b1: + //SEG292 [93] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuz1=vbuc2 + lda #GREEN + ldy idx + sta COLS,y + jmp b2 +} +//SEG293 testUnaryOperator +testUnaryOperator: { + //SEG294 [95] call assertType + //SEG295 [87] phi from testUnaryOperator to assertType [phi:testUnaryOperator->assertType] + assertType_from_testUnaryOperator: + //SEG296 [87] phi (byte) idx#105 = (byte) 0 [phi:testUnaryOperator->assertType#0] -- vbuz1=vbuc1 + lda #0 + sta idx + //SEG297 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testUnaryOperator->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG298 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testUnaryOperator->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG299 [96] phi from testUnaryOperator to testUnaryOperator::@1 [phi:testUnaryOperator->testUnaryOperator::@1] + b1_from_testUnaryOperator: + jmp b1 + //SEG300 testUnaryOperator::@1 + b1: + //SEG301 [97] call assertType + //SEG302 [87] phi from testUnaryOperator::@1 to assertType [phi:testUnaryOperator::@1->assertType] + assertType_from_b1: + //SEG303 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@1->assertType#0] -- register_copy + //SEG304 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testUnaryOperator::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG305 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testUnaryOperator::@1->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t1 + jsr assertType + //SEG306 [98] phi from testUnaryOperator::@1 to testUnaryOperator::@2 [phi:testUnaryOperator::@1->testUnaryOperator::@2] + b2_from_b1: + jmp b2 + //SEG307 testUnaryOperator::@2 + b2: + //SEG308 [99] call assertType + //SEG309 [87] phi from testUnaryOperator::@2 to assertType [phi:testUnaryOperator::@2->assertType] + assertType_from_b2: + //SEG310 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@2->assertType#0] -- register_copy + //SEG311 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testUnaryOperator::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG312 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testUnaryOperator::@2->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG313 [100] phi from testUnaryOperator::@2 to testUnaryOperator::@3 [phi:testUnaryOperator::@2->testUnaryOperator::@3] + b3_from_b2: + jmp b3 + //SEG314 testUnaryOperator::@3 + b3: + //SEG315 [101] call assertType + //SEG316 [87] phi from testUnaryOperator::@3 to assertType [phi:testUnaryOperator::@3->assertType] + assertType_from_b3: + //SEG317 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@3->assertType#0] -- register_copy + //SEG318 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testUnaryOperator::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG319 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testUnaryOperator::@3->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG320 [102] phi from testUnaryOperator::@3 to testUnaryOperator::@4 [phi:testUnaryOperator::@3->testUnaryOperator::@4] + b4_from_b3: + jmp b4 + //SEG321 testUnaryOperator::@4 + b4: + //SEG322 [103] call assertType + //SEG323 [87] phi from testUnaryOperator::@4 to assertType [phi:testUnaryOperator::@4->assertType] + assertType_from_b4: + //SEG324 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@4->assertType#0] -- register_copy + //SEG325 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testUnaryOperator::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG326 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testUnaryOperator::@4->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG327 [104] phi from testUnaryOperator::@4 to testUnaryOperator::@5 [phi:testUnaryOperator::@4->testUnaryOperator::@5] + b5_from_b4: + jmp b5 + //SEG328 testUnaryOperator::@5 + b5: + //SEG329 [105] call assertType + //SEG330 [87] phi from testUnaryOperator::@5 to assertType [phi:testUnaryOperator::@5->assertType] + assertType_from_b5: + //SEG331 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@5->assertType#0] -- register_copy + //SEG332 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testUnaryOperator::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG333 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testUnaryOperator::@5->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp breturn + //SEG334 testUnaryOperator::@return + breturn: + //SEG335 [106] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [6] *((byte*) main::s#2) ← (byte) ' ' [ main::s#2 ] ( main:2 [ main::s#2 ] ) always clobbers reg byte a reg byte y +Statement [8] if((byte*) main::s#1<(const byte*) SCREEN#0+(word) $3e8) goto main::@1 [ main::s#1 ] ( main:2 [ main::s#1 ] ) always clobbers reg byte a +Statement [89] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) RED#0 [ assertType::t1#42 idx#105 ] ( main:2::testBinaryOperator:12::assertType:15 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:17 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:19 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:21 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:23 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:25 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:27 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:29 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:31 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:33 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:35 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:37 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:39 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:41 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:43 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:45 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:47 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:49 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:51 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:53 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:55 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:57 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:59 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:61 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:63 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:65 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:67 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:69 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:71 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:73 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:75 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:77 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:79 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:81 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:83 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:85 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:95 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:97 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:99 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:101 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:103 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:105 [ assertType::t1#42 idx#105 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ assertType::t1#42 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ idx#105 idx#108 idx#26 idx#40 idx#47 idx#19 ] +Statement [90] *((const byte*) SCREEN#0 + (byte) idx#105) ← (byte) assertType::t1#42 [ idx#105 ] ( main:2::testBinaryOperator:12::assertType:15 [ idx#105 ] main:2::testBinaryOperator:12::assertType:17 [ idx#105 ] main:2::testBinaryOperator:12::assertType:19 [ idx#105 ] main:2::testBinaryOperator:12::assertType:21 [ idx#105 ] main:2::testBinaryOperator:12::assertType:23 [ idx#105 ] main:2::testBinaryOperator:12::assertType:25 [ idx#105 ] main:2::testBinaryOperator:12::assertType:27 [ idx#105 ] main:2::testBinaryOperator:12::assertType:29 [ idx#105 ] main:2::testBinaryOperator:12::assertType:31 [ idx#105 ] main:2::testBinaryOperator:12::assertType:33 [ idx#105 ] main:2::testBinaryOperator:12::assertType:35 [ idx#105 ] main:2::testBinaryOperator:12::assertType:37 [ idx#105 ] main:2::testBinaryOperator:12::assertType:39 [ idx#105 ] main:2::testBinaryOperator:12::assertType:41 [ idx#105 ] main:2::testBinaryOperator:12::assertType:43 [ idx#105 ] main:2::testBinaryOperator:12::assertType:45 [ idx#105 ] main:2::testBinaryOperator:12::assertType:47 [ idx#105 ] main:2::testBinaryOperator:12::assertType:49 [ idx#105 ] main:2::testBinaryOperator:12::assertType:51 [ idx#105 ] main:2::testBinaryOperator:12::assertType:53 [ idx#105 ] main:2::testBinaryOperator:12::assertType:55 [ idx#105 ] main:2::testBinaryOperator:12::assertType:57 [ idx#105 ] main:2::testBinaryOperator:12::assertType:59 [ idx#105 ] main:2::testBinaryOperator:12::assertType:61 [ idx#105 ] main:2::testBinaryOperator:12::assertType:63 [ idx#105 ] main:2::testBinaryOperator:12::assertType:65 [ idx#105 ] main:2::testBinaryOperator:12::assertType:67 [ idx#105 ] main:2::testBinaryOperator:12::assertType:69 [ idx#105 ] main:2::testBinaryOperator:12::assertType:71 [ idx#105 ] main:2::testBinaryOperator:12::assertType:73 [ idx#105 ] main:2::testBinaryOperator:12::assertType:75 [ idx#105 ] main:2::testBinaryOperator:12::assertType:77 [ idx#105 ] main:2::testBinaryOperator:12::assertType:79 [ idx#105 ] main:2::testBinaryOperator:12::assertType:81 [ idx#105 ] main:2::testBinaryOperator:12::assertType:83 [ idx#105 ] main:2::testBinaryOperator:12::assertType:85 [ idx#105 ] main:2::testUnaryOperator:10::assertType:95 [ idx#105 ] main:2::testUnaryOperator:10::assertType:97 [ idx#105 ] main:2::testUnaryOperator:10::assertType:99 [ idx#105 ] main:2::testUnaryOperator:10::assertType:101 [ idx#105 ] main:2::testUnaryOperator:10::assertType:103 [ idx#105 ] main:2::testUnaryOperator:10::assertType:105 [ idx#105 ] ) always clobbers reg byte a +Statement [93] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) GREEN#0 [ assertType::t1#42 idx#105 ] ( main:2::testBinaryOperator:12::assertType:15 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:17 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:19 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:21 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:23 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:25 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:27 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:29 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:31 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:33 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:35 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:37 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:39 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:41 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:43 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:45 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:47 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:49 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:51 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:53 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:55 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:57 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:59 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:61 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:63 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:65 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:67 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:69 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:71 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:73 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:75 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:77 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:79 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:81 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:83 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:85 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:95 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:97 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:99 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:101 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:103 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:105 [ assertType::t1#42 idx#105 ] ) always clobbers reg byte a +Statement [6] *((byte*) main::s#2) ← (byte) ' ' [ main::s#2 ] ( main:2 [ main::s#2 ] ) always clobbers reg byte a reg byte y +Statement [8] if((byte*) main::s#1<(const byte*) SCREEN#0+(word) $3e8) goto main::@1 [ main::s#1 ] ( main:2 [ main::s#1 ] ) always clobbers reg byte a +Statement [89] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) RED#0 [ assertType::t1#42 idx#105 ] ( main:2::testBinaryOperator:12::assertType:15 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:17 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:19 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:21 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:23 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:25 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:27 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:29 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:31 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:33 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:35 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:37 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:39 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:41 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:43 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:45 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:47 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:49 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:51 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:53 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:55 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:57 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:59 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:61 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:63 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:65 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:67 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:69 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:71 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:73 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:75 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:77 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:79 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:81 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:83 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:85 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:95 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:97 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:99 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:101 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:103 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:105 [ assertType::t1#42 idx#105 ] ) always clobbers reg byte a +Statement [90] *((const byte*) SCREEN#0 + (byte) idx#105) ← (byte) assertType::t1#42 [ idx#105 ] ( main:2::testBinaryOperator:12::assertType:15 [ idx#105 ] main:2::testBinaryOperator:12::assertType:17 [ idx#105 ] main:2::testBinaryOperator:12::assertType:19 [ idx#105 ] main:2::testBinaryOperator:12::assertType:21 [ idx#105 ] main:2::testBinaryOperator:12::assertType:23 [ idx#105 ] main:2::testBinaryOperator:12::assertType:25 [ idx#105 ] main:2::testBinaryOperator:12::assertType:27 [ idx#105 ] main:2::testBinaryOperator:12::assertType:29 [ idx#105 ] main:2::testBinaryOperator:12::assertType:31 [ idx#105 ] main:2::testBinaryOperator:12::assertType:33 [ idx#105 ] main:2::testBinaryOperator:12::assertType:35 [ idx#105 ] main:2::testBinaryOperator:12::assertType:37 [ idx#105 ] main:2::testBinaryOperator:12::assertType:39 [ idx#105 ] main:2::testBinaryOperator:12::assertType:41 [ idx#105 ] main:2::testBinaryOperator:12::assertType:43 [ idx#105 ] main:2::testBinaryOperator:12::assertType:45 [ idx#105 ] main:2::testBinaryOperator:12::assertType:47 [ idx#105 ] main:2::testBinaryOperator:12::assertType:49 [ idx#105 ] main:2::testBinaryOperator:12::assertType:51 [ idx#105 ] main:2::testBinaryOperator:12::assertType:53 [ idx#105 ] main:2::testBinaryOperator:12::assertType:55 [ idx#105 ] main:2::testBinaryOperator:12::assertType:57 [ idx#105 ] main:2::testBinaryOperator:12::assertType:59 [ idx#105 ] main:2::testBinaryOperator:12::assertType:61 [ idx#105 ] main:2::testBinaryOperator:12::assertType:63 [ idx#105 ] main:2::testBinaryOperator:12::assertType:65 [ idx#105 ] main:2::testBinaryOperator:12::assertType:67 [ idx#105 ] main:2::testBinaryOperator:12::assertType:69 [ idx#105 ] main:2::testBinaryOperator:12::assertType:71 [ idx#105 ] main:2::testBinaryOperator:12::assertType:73 [ idx#105 ] main:2::testBinaryOperator:12::assertType:75 [ idx#105 ] main:2::testBinaryOperator:12::assertType:77 [ idx#105 ] main:2::testBinaryOperator:12::assertType:79 [ idx#105 ] main:2::testBinaryOperator:12::assertType:81 [ idx#105 ] main:2::testBinaryOperator:12::assertType:83 [ idx#105 ] main:2::testBinaryOperator:12::assertType:85 [ idx#105 ] main:2::testUnaryOperator:10::assertType:95 [ idx#105 ] main:2::testUnaryOperator:10::assertType:97 [ idx#105 ] main:2::testUnaryOperator:10::assertType:99 [ idx#105 ] main:2::testUnaryOperator:10::assertType:101 [ idx#105 ] main:2::testUnaryOperator:10::assertType:103 [ idx#105 ] main:2::testUnaryOperator:10::assertType:105 [ idx#105 ] ) always clobbers reg byte a +Statement [93] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) GREEN#0 [ assertType::t1#42 idx#105 ] ( main:2::testBinaryOperator:12::assertType:15 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:17 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:19 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:21 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:23 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:25 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:27 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:29 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:31 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:33 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:35 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:37 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:39 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:41 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:43 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:45 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:47 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:49 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:51 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:53 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:55 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:57 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:59 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:61 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:63 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:65 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:67 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:69 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:71 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:73 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:75 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:77 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:79 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:81 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:83 [ assertType::t1#42 idx#105 ] main:2::testBinaryOperator:12::assertType:85 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:95 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:97 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:99 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:101 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:103 [ assertType::t1#42 idx#105 ] main:2::testUnaryOperator:10::assertType:105 [ assertType::t1#42 idx#105 ] ) always clobbers reg byte a +Potential registers zp ZP_WORD:2 [ main::s#2 main::s#1 ] : zp ZP_WORD:2 , +Potential registers zp ZP_BYTE:4 [ assertType::t1#42 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ assertType::t2#42 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:6 [ idx#105 idx#108 idx#26 idx#40 idx#47 idx#19 ] : zp ZP_BYTE:6 , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [] 34.25: zp ZP_BYTE:6 [ idx#105 idx#108 idx#26 idx#40 idx#47 idx#19 ] +Uplift Scope [main] 33: zp ZP_WORD:2 [ main::s#2 main::s#1 ] +Uplift Scope [assertType] 2: zp ZP_BYTE:5 [ assertType::t2#42 ] 1: zp ZP_BYTE:4 [ assertType::t1#42 ] +Uplift Scope [testUnaryOperator] +Uplift Scope [testBinaryOperator] + +Uplifting [] best 1503 combination reg byte x [ idx#105 idx#108 idx#26 idx#40 idx#47 idx#19 ] +Uplifting [main] best 1503 combination zp ZP_WORD:2 [ main::s#2 main::s#1 ] +Uplifting [assertType] best 1375 combination zp ZP_BYTE:5 [ assertType::t2#42 ] reg byte y [ assertType::t1#42 ] +Uplifting [testUnaryOperator] best 1375 combination +Uplifting [testBinaryOperator] best 1375 combination +Attempting to uplift remaining variables inzp ZP_BYTE:5 [ assertType::t2#42 ] +Uplifting [assertType] best 1375 combination zp ZP_BYTE:5 [ assertType::t2#42 ] +Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:4 [ assertType::t2#42 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests different integer literal types +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_BYTE = 1 + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_WORD = 3 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_DWORD = 5 + .const TYPEID_SIGNED_DWORD = 6 + .const RED = 2 + .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label s = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte*) main::s#2 = (const byte*) SCREEN#0 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #SCREEN + sta s+1 + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte*) main::s#2 = (byte*) main::s#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] *((byte*) main::s#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (s),y + //SEG17 [7] (byte*) main::s#1 ← ++ (byte*) main::s#2 -- pbuz1=_inc_pbuz1 + inc s + bne !+ + inc s+1 + !: + //SEG18 [8] if((byte*) main::s#1<(const byte*) SCREEN#0+(word) $3e8) goto main::@1 -- pbuz1_lt_pbuc1_then_la1 + lda s+1 + cmp #>SCREEN+$3e8 + bcc b1_from_b1 + bne !+ + lda s + cmp #main::@2] + b2_from_b1: + jmp b2 + //SEG20 main::@2 + b2: + //SEG21 [10] call testUnaryOperator + //SEG22 [94] phi from main::@2 to testUnaryOperator [phi:main::@2->testUnaryOperator] + testUnaryOperator_from_b2: + jsr testUnaryOperator + //SEG23 [11] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + b3_from_b2: + jmp b3 + //SEG24 main::@3 + b3: + //SEG25 [12] call testBinaryOperator + //SEG26 [14] phi from main::@3 to testBinaryOperator [phi:main::@3->testBinaryOperator] + testBinaryOperator_from_b3: + jsr testBinaryOperator + jmp breturn + //SEG27 main::@return + breturn: + //SEG28 [13] return + rts +} +//SEG29 testBinaryOperator +testBinaryOperator: { + //SEG30 [15] call assertType + //SEG31 [87] phi from testBinaryOperator to assertType [phi:testBinaryOperator->assertType] + assertType_from_testBinaryOperator: + //SEG32 [87] phi (byte) idx#105 = (byte) $28 [phi:testBinaryOperator->assertType#0] -- vbuxx=vbuc1 + ldx #$28 + //SEG33 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG34 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG35 [16] phi from testBinaryOperator to testBinaryOperator::@1 [phi:testBinaryOperator->testBinaryOperator::@1] + b1_from_testBinaryOperator: + jmp b1 + //SEG36 testBinaryOperator::@1 + b1: + //SEG37 [17] call assertType + //SEG38 [87] phi from testBinaryOperator::@1 to assertType [phi:testBinaryOperator::@1->assertType] + assertType_from_b1: + //SEG39 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@1->assertType#0] -- register_copy + //SEG40 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG41 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@1->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG42 [18] phi from testBinaryOperator::@1 to testBinaryOperator::@2 [phi:testBinaryOperator::@1->testBinaryOperator::@2] + b2_from_b1: + jmp b2 + //SEG43 testBinaryOperator::@2 + b2: + //SEG44 [19] call assertType + //SEG45 [87] phi from testBinaryOperator::@2 to assertType [phi:testBinaryOperator::@2->assertType] + assertType_from_b2: + //SEG46 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@2->assertType#0] -- register_copy + //SEG47 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG48 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@2->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG49 [20] phi from testBinaryOperator::@2 to testBinaryOperator::@3 [phi:testBinaryOperator::@2->testBinaryOperator::@3] + b3_from_b2: + jmp b3 + //SEG50 testBinaryOperator::@3 + b3: + //SEG51 [21] call assertType + //SEG52 [87] phi from testBinaryOperator::@3 to assertType [phi:testBinaryOperator::@3->assertType] + assertType_from_b3: + //SEG53 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@3->assertType#0] -- register_copy + //SEG54 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG55 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@3->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG56 [22] phi from testBinaryOperator::@3 to testBinaryOperator::@4 [phi:testBinaryOperator::@3->testBinaryOperator::@4] + b4_from_b3: + jmp b4 + //SEG57 testBinaryOperator::@4 + b4: + //SEG58 [23] call assertType + //SEG59 [87] phi from testBinaryOperator::@4 to assertType [phi:testBinaryOperator::@4->assertType] + assertType_from_b4: + //SEG60 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@4->assertType#0] -- register_copy + //SEG61 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG62 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@4->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG63 [24] phi from testBinaryOperator::@4 to testBinaryOperator::@5 [phi:testBinaryOperator::@4->testBinaryOperator::@5] + b5_from_b4: + jmp b5 + //SEG64 testBinaryOperator::@5 + b5: + //SEG65 [25] call assertType + //SEG66 [87] phi from testBinaryOperator::@5 to assertType [phi:testBinaryOperator::@5->assertType] + assertType_from_b5: + //SEG67 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@5->assertType#0] -- register_copy + //SEG68 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG69 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@5->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp b6 + //SEG70 testBinaryOperator::@6 + b6: + //SEG71 [26] (byte) idx#19 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG72 [27] call assertType + //SEG73 [87] phi from testBinaryOperator::@6 to assertType [phi:testBinaryOperator::@6->assertType] + assertType_from_b6: + //SEG74 [87] phi (byte) idx#105 = (byte) idx#19 [phi:testBinaryOperator::@6->assertType#0] -- register_copy + //SEG75 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG76 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@6->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG77 [28] phi from testBinaryOperator::@6 to testBinaryOperator::@7 [phi:testBinaryOperator::@6->testBinaryOperator::@7] + b7_from_b6: + jmp b7 + //SEG78 testBinaryOperator::@7 + b7: + //SEG79 [29] call assertType + //SEG80 [87] phi from testBinaryOperator::@7 to assertType [phi:testBinaryOperator::@7->assertType] + assertType_from_b7: + //SEG81 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@7->assertType#0] -- register_copy + //SEG82 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testBinaryOperator::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG83 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testBinaryOperator::@7->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_BYTE + jsr assertType + //SEG84 [30] phi from testBinaryOperator::@7 to testBinaryOperator::@8 [phi:testBinaryOperator::@7->testBinaryOperator::@8] + b8_from_b7: + jmp b8 + //SEG85 testBinaryOperator::@8 + b8: + //SEG86 [31] call assertType + //SEG87 [87] phi from testBinaryOperator::@8 to assertType [phi:testBinaryOperator::@8->assertType] + assertType_from_b8: + //SEG88 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@8->assertType#0] -- register_copy + //SEG89 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG90 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@8->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG91 [32] phi from testBinaryOperator::@8 to testBinaryOperator::@9 [phi:testBinaryOperator::@8->testBinaryOperator::@9] + b9_from_b8: + jmp b9 + //SEG92 testBinaryOperator::@9 + b9: + //SEG93 [33] call assertType + //SEG94 [87] phi from testBinaryOperator::@9 to assertType [phi:testBinaryOperator::@9->assertType] + assertType_from_b9: + //SEG95 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@9->assertType#0] -- register_copy + //SEG96 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG97 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@9->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG98 [34] phi from testBinaryOperator::@9 to testBinaryOperator::@10 [phi:testBinaryOperator::@9->testBinaryOperator::@10] + b10_from_b9: + jmp b10 + //SEG99 testBinaryOperator::@10 + b10: + //SEG100 [35] call assertType + //SEG101 [87] phi from testBinaryOperator::@10 to assertType [phi:testBinaryOperator::@10->assertType] + assertType_from_b10: + //SEG102 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@10->assertType#0] -- register_copy + //SEG103 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG104 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@10->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG105 [36] phi from testBinaryOperator::@10 to testBinaryOperator::@11 [phi:testBinaryOperator::@10->testBinaryOperator::@11] + b11_from_b10: + jmp b11 + //SEG106 testBinaryOperator::@11 + b11: + //SEG107 [37] call assertType + //SEG108 [87] phi from testBinaryOperator::@11 to assertType [phi:testBinaryOperator::@11->assertType] + assertType_from_b11: + //SEG109 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@11->assertType#0] -- register_copy + //SEG110 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG111 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@11->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp b12 + //SEG112 testBinaryOperator::@12 + b12: + //SEG113 [38] (byte) idx#26 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG114 [39] call assertType + //SEG115 [87] phi from testBinaryOperator::@12 to assertType [phi:testBinaryOperator::@12->assertType] + assertType_from_b12: + //SEG116 [87] phi (byte) idx#105 = (byte) idx#26 [phi:testBinaryOperator::@12->assertType#0] -- register_copy + //SEG117 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG118 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@12->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG119 [40] phi from testBinaryOperator::@12 to testBinaryOperator::@13 [phi:testBinaryOperator::@12->testBinaryOperator::@13] + b13_from_b12: + jmp b13 + //SEG120 testBinaryOperator::@13 + b13: + //SEG121 [41] call assertType + //SEG122 [87] phi from testBinaryOperator::@13 to assertType [phi:testBinaryOperator::@13->assertType] + assertType_from_b13: + //SEG123 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@13->assertType#0] -- register_copy + //SEG124 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG125 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@13->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG126 [42] phi from testBinaryOperator::@13 to testBinaryOperator::@14 [phi:testBinaryOperator::@13->testBinaryOperator::@14] + b14_from_b13: + jmp b14 + //SEG127 testBinaryOperator::@14 + b14: + //SEG128 [43] call assertType + //SEG129 [87] phi from testBinaryOperator::@14 to assertType [phi:testBinaryOperator::@14->assertType] + assertType_from_b14: + //SEG130 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@14->assertType#0] -- register_copy + //SEG131 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG132 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@14->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG133 [44] phi from testBinaryOperator::@14 to testBinaryOperator::@15 [phi:testBinaryOperator::@14->testBinaryOperator::@15] + b15_from_b14: + jmp b15 + //SEG134 testBinaryOperator::@15 + b15: + //SEG135 [45] call assertType + //SEG136 [87] phi from testBinaryOperator::@15 to assertType [phi:testBinaryOperator::@15->assertType] + assertType_from_b15: + //SEG137 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@15->assertType#0] -- register_copy + //SEG138 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@15->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG139 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@15->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG140 [46] phi from testBinaryOperator::@15 to testBinaryOperator::@16 [phi:testBinaryOperator::@15->testBinaryOperator::@16] + b16_from_b15: + jmp b16 + //SEG141 testBinaryOperator::@16 + b16: + //SEG142 [47] call assertType + //SEG143 [87] phi from testBinaryOperator::@16 to assertType [phi:testBinaryOperator::@16->assertType] + assertType_from_b16: + //SEG144 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@16->assertType#0] -- register_copy + //SEG145 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@16->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG146 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@16->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG147 [48] phi from testBinaryOperator::@16 to testBinaryOperator::@17 [phi:testBinaryOperator::@16->testBinaryOperator::@17] + b17_from_b16: + jmp b17 + //SEG148 testBinaryOperator::@17 + b17: + //SEG149 [49] call assertType + //SEG150 [87] phi from testBinaryOperator::@17 to assertType [phi:testBinaryOperator::@17->assertType] + assertType_from_b17: + //SEG151 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@17->assertType#0] -- register_copy + //SEG152 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@17->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG153 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@17->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG154 [50] phi from testBinaryOperator::@17 to testBinaryOperator::@18 [phi:testBinaryOperator::@17->testBinaryOperator::@18] + b18_from_b17: + jmp b18 + //SEG155 testBinaryOperator::@18 + b18: + //SEG156 [51] call assertType + //SEG157 [87] phi from testBinaryOperator::@18 to assertType [phi:testBinaryOperator::@18->assertType] + assertType_from_b18: + //SEG158 [87] phi (byte) idx#105 = (byte) $50 [phi:testBinaryOperator::@18->assertType#0] -- vbuxx=vbuc1 + ldx #$50 + //SEG159 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@18->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG160 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@18->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG161 [52] phi from testBinaryOperator::@18 to testBinaryOperator::@19 [phi:testBinaryOperator::@18->testBinaryOperator::@19] + b19_from_b18: + jmp b19 + //SEG162 testBinaryOperator::@19 + b19: + //SEG163 [53] call assertType + //SEG164 [87] phi from testBinaryOperator::@19 to assertType [phi:testBinaryOperator::@19->assertType] + assertType_from_b19: + //SEG165 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@19->assertType#0] -- register_copy + //SEG166 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@19->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG167 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@19->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG168 [54] phi from testBinaryOperator::@19 to testBinaryOperator::@20 [phi:testBinaryOperator::@19->testBinaryOperator::@20] + b20_from_b19: + jmp b20 + //SEG169 testBinaryOperator::@20 + b20: + //SEG170 [55] call assertType + //SEG171 [87] phi from testBinaryOperator::@20 to assertType [phi:testBinaryOperator::@20->assertType] + assertType_from_b20: + //SEG172 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@20->assertType#0] -- register_copy + //SEG173 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@20->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG174 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@20->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG175 [56] phi from testBinaryOperator::@20 to testBinaryOperator::@21 [phi:testBinaryOperator::@20->testBinaryOperator::@21] + b21_from_b20: + jmp b21 + //SEG176 testBinaryOperator::@21 + b21: + //SEG177 [57] call assertType + //SEG178 [87] phi from testBinaryOperator::@21 to assertType [phi:testBinaryOperator::@21->assertType] + assertType_from_b21: + //SEG179 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@21->assertType#0] -- register_copy + //SEG180 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@21->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG181 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@21->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG182 [58] phi from testBinaryOperator::@21 to testBinaryOperator::@22 [phi:testBinaryOperator::@21->testBinaryOperator::@22] + b22_from_b21: + jmp b22 + //SEG183 testBinaryOperator::@22 + b22: + //SEG184 [59] call assertType + //SEG185 [87] phi from testBinaryOperator::@22 to assertType [phi:testBinaryOperator::@22->assertType] + assertType_from_b22: + //SEG186 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@22->assertType#0] -- register_copy + //SEG187 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@22->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG188 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@22->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG189 [60] phi from testBinaryOperator::@22 to testBinaryOperator::@23 [phi:testBinaryOperator::@22->testBinaryOperator::@23] + b23_from_b22: + jmp b23 + //SEG190 testBinaryOperator::@23 + b23: + //SEG191 [61] call assertType + //SEG192 [87] phi from testBinaryOperator::@23 to assertType [phi:testBinaryOperator::@23->assertType] + assertType_from_b23: + //SEG193 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@23->assertType#0] -- register_copy + //SEG194 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@23->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG195 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@23->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp b24 + //SEG196 testBinaryOperator::@24 + b24: + //SEG197 [62] (byte) idx#40 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG198 [63] call assertType + //SEG199 [87] phi from testBinaryOperator::@24 to assertType [phi:testBinaryOperator::@24->assertType] + assertType_from_b24: + //SEG200 [87] phi (byte) idx#105 = (byte) idx#40 [phi:testBinaryOperator::@24->assertType#0] -- register_copy + //SEG201 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@24->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG202 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@24->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG203 [64] phi from testBinaryOperator::@24 to testBinaryOperator::@25 [phi:testBinaryOperator::@24->testBinaryOperator::@25] + b25_from_b24: + jmp b25 + //SEG204 testBinaryOperator::@25 + b25: + //SEG205 [65] call assertType + //SEG206 [87] phi from testBinaryOperator::@25 to assertType [phi:testBinaryOperator::@25->assertType] + assertType_from_b25: + //SEG207 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@25->assertType#0] -- register_copy + //SEG208 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@25->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG209 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@25->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG210 [66] phi from testBinaryOperator::@25 to testBinaryOperator::@26 [phi:testBinaryOperator::@25->testBinaryOperator::@26] + b26_from_b25: + jmp b26 + //SEG211 testBinaryOperator::@26 + b26: + //SEG212 [67] call assertType + //SEG213 [87] phi from testBinaryOperator::@26 to assertType [phi:testBinaryOperator::@26->assertType] + assertType_from_b26: + //SEG214 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@26->assertType#0] -- register_copy + //SEG215 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@26->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG216 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@26->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG217 [68] phi from testBinaryOperator::@26 to testBinaryOperator::@27 [phi:testBinaryOperator::@26->testBinaryOperator::@27] + b27_from_b26: + jmp b27 + //SEG218 testBinaryOperator::@27 + b27: + //SEG219 [69] call assertType + //SEG220 [87] phi from testBinaryOperator::@27 to assertType [phi:testBinaryOperator::@27->assertType] + assertType_from_b27: + //SEG221 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@27->assertType#0] -- register_copy + //SEG222 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@27->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG223 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@27->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG224 [70] phi from testBinaryOperator::@27 to testBinaryOperator::@28 [phi:testBinaryOperator::@27->testBinaryOperator::@28] + b28_from_b27: + jmp b28 + //SEG225 testBinaryOperator::@28 + b28: + //SEG226 [71] call assertType + //SEG227 [87] phi from testBinaryOperator::@28 to assertType [phi:testBinaryOperator::@28->assertType] + assertType_from_b28: + //SEG228 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@28->assertType#0] -- register_copy + //SEG229 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@28->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG230 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@28->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG231 [72] phi from testBinaryOperator::@28 to testBinaryOperator::@29 [phi:testBinaryOperator::@28->testBinaryOperator::@29] + b29_from_b28: + jmp b29 + //SEG232 testBinaryOperator::@29 + b29: + //SEG233 [73] call assertType + //SEG234 [87] phi from testBinaryOperator::@29 to assertType [phi:testBinaryOperator::@29->assertType] + assertType_from_b29: + //SEG235 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@29->assertType#0] -- register_copy + //SEG236 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@29->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG237 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@29->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + jmp b30 + //SEG238 testBinaryOperator::@30 + b30: + //SEG239 [74] (byte) idx#47 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG240 [75] call assertType + //SEG241 [87] phi from testBinaryOperator::@30 to assertType [phi:testBinaryOperator::@30->assertType] + assertType_from_b30: + //SEG242 [87] phi (byte) idx#105 = (byte) idx#47 [phi:testBinaryOperator::@30->assertType#0] -- register_copy + //SEG243 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@30->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG244 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@30->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG245 [76] phi from testBinaryOperator::@30 to testBinaryOperator::@31 [phi:testBinaryOperator::@30->testBinaryOperator::@31] + b31_from_b30: + jmp b31 + //SEG246 testBinaryOperator::@31 + b31: + //SEG247 [77] call assertType + //SEG248 [87] phi from testBinaryOperator::@31 to assertType [phi:testBinaryOperator::@31->assertType] + assertType_from_b31: + //SEG249 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@31->assertType#0] -- register_copy + //SEG250 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@31->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG251 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@31->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG252 [78] phi from testBinaryOperator::@31 to testBinaryOperator::@32 [phi:testBinaryOperator::@31->testBinaryOperator::@32] + b32_from_b31: + jmp b32 + //SEG253 testBinaryOperator::@32 + b32: + //SEG254 [79] call assertType + //SEG255 [87] phi from testBinaryOperator::@32 to assertType [phi:testBinaryOperator::@32->assertType] + assertType_from_b32: + //SEG256 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@32->assertType#0] -- register_copy + //SEG257 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@32->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG258 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@32->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG259 [80] phi from testBinaryOperator::@32 to testBinaryOperator::@33 [phi:testBinaryOperator::@32->testBinaryOperator::@33] + b33_from_b32: + jmp b33 + //SEG260 testBinaryOperator::@33 + b33: + //SEG261 [81] call assertType + //SEG262 [87] phi from testBinaryOperator::@33 to assertType [phi:testBinaryOperator::@33->assertType] + assertType_from_b33: + //SEG263 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@33->assertType#0] -- register_copy + //SEG264 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@33->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG265 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@33->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG266 [82] phi from testBinaryOperator::@33 to testBinaryOperator::@34 [phi:testBinaryOperator::@33->testBinaryOperator::@34] + b34_from_b33: + jmp b34 + //SEG267 testBinaryOperator::@34 + b34: + //SEG268 [83] call assertType + //SEG269 [87] phi from testBinaryOperator::@34 to assertType [phi:testBinaryOperator::@34->assertType] + assertType_from_b34: + //SEG270 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@34->assertType#0] -- register_copy + //SEG271 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@34->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG272 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@34->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG273 [84] phi from testBinaryOperator::@34 to testBinaryOperator::@35 [phi:testBinaryOperator::@34->testBinaryOperator::@35] + b35_from_b34: + jmp b35 + //SEG274 testBinaryOperator::@35 + b35: + //SEG275 [85] call assertType + //SEG276 [87] phi from testBinaryOperator::@35 to assertType [phi:testBinaryOperator::@35->assertType] + assertType_from_b35: + //SEG277 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@35->assertType#0] -- register_copy + //SEG278 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@35->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG279 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@35->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp breturn + //SEG280 testBinaryOperator::@return + breturn: + //SEG281 [86] return + rts +} +//SEG282 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(4) t2) +assertType: { + .label t2 = 4 + //SEG283 [88] if((byte) assertType::t1#42==(byte) assertType::t2#42) goto assertType::@1 -- vbuyy_eq_vbuz1_then_la1 + tya + cmp t2 + beq b1 + jmp b3 + //SEG284 assertType::@3 + b3: + //SEG285 [89] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) RED#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #RED + sta COLS,x + jmp b2 + //SEG286 assertType::@2 + b2: + //SEG287 [90] *((const byte*) SCREEN#0 + (byte) idx#105) ← (byte) assertType::t1#42 -- pbuc1_derefidx_vbuxx=vbuyy + tya + sta SCREEN,x + //SEG288 [91] (byte) idx#108 ← ++ (byte) idx#105 -- vbuxx=_inc_vbuxx + inx + jmp breturn + //SEG289 assertType::@return + breturn: + //SEG290 [92] return + rts + //SEG291 assertType::@1 + b1: + //SEG292 [93] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #GREEN + sta COLS,x + jmp b2 +} +//SEG293 testUnaryOperator +testUnaryOperator: { + //SEG294 [95] call assertType + //SEG295 [87] phi from testUnaryOperator to assertType [phi:testUnaryOperator->assertType] + assertType_from_testUnaryOperator: + //SEG296 [87] phi (byte) idx#105 = (byte) 0 [phi:testUnaryOperator->assertType#0] -- vbuxx=vbuc1 + ldx #0 + //SEG297 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testUnaryOperator->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG298 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testUnaryOperator->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG299 [96] phi from testUnaryOperator to testUnaryOperator::@1 [phi:testUnaryOperator->testUnaryOperator::@1] + b1_from_testUnaryOperator: + jmp b1 + //SEG300 testUnaryOperator::@1 + b1: + //SEG301 [97] call assertType + //SEG302 [87] phi from testUnaryOperator::@1 to assertType [phi:testUnaryOperator::@1->assertType] + assertType_from_b1: + //SEG303 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@1->assertType#0] -- register_copy + //SEG304 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testUnaryOperator::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG305 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testUnaryOperator::@1->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_BYTE + jsr assertType + //SEG306 [98] phi from testUnaryOperator::@1 to testUnaryOperator::@2 [phi:testUnaryOperator::@1->testUnaryOperator::@2] + b2_from_b1: + jmp b2 + //SEG307 testUnaryOperator::@2 + b2: + //SEG308 [99] call assertType + //SEG309 [87] phi from testUnaryOperator::@2 to assertType [phi:testUnaryOperator::@2->assertType] + assertType_from_b2: + //SEG310 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@2->assertType#0] -- register_copy + //SEG311 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testUnaryOperator::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG312 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testUnaryOperator::@2->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG313 [100] phi from testUnaryOperator::@2 to testUnaryOperator::@3 [phi:testUnaryOperator::@2->testUnaryOperator::@3] + b3_from_b2: + jmp b3 + //SEG314 testUnaryOperator::@3 + b3: + //SEG315 [101] call assertType + //SEG316 [87] phi from testUnaryOperator::@3 to assertType [phi:testUnaryOperator::@3->assertType] + assertType_from_b3: + //SEG317 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@3->assertType#0] -- register_copy + //SEG318 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testUnaryOperator::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG319 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testUnaryOperator::@3->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG320 [102] phi from testUnaryOperator::@3 to testUnaryOperator::@4 [phi:testUnaryOperator::@3->testUnaryOperator::@4] + b4_from_b3: + jmp b4 + //SEG321 testUnaryOperator::@4 + b4: + //SEG322 [103] call assertType + //SEG323 [87] phi from testUnaryOperator::@4 to assertType [phi:testUnaryOperator::@4->assertType] + assertType_from_b4: + //SEG324 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@4->assertType#0] -- register_copy + //SEG325 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testUnaryOperator::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG326 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testUnaryOperator::@4->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG327 [104] phi from testUnaryOperator::@4 to testUnaryOperator::@5 [phi:testUnaryOperator::@4->testUnaryOperator::@5] + b5_from_b4: + jmp b5 + //SEG328 testUnaryOperator::@5 + b5: + //SEG329 [105] call assertType + //SEG330 [87] phi from testUnaryOperator::@5 to assertType [phi:testUnaryOperator::@5->assertType] + assertType_from_b5: + //SEG331 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@5->assertType#0] -- register_copy + //SEG332 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testUnaryOperator::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG333 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testUnaryOperator::@5->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp breturn + //SEG334 testUnaryOperator::@return + breturn: + //SEG335 [106] return + rts +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp b4 +Removing instruction jmp b5 +Removing instruction jmp b6 +Removing instruction jmp b7 +Removing instruction jmp b8 +Removing instruction jmp b9 +Removing instruction jmp b10 +Removing instruction jmp b11 +Removing instruction jmp b12 +Removing instruction jmp b13 +Removing instruction jmp b14 +Removing instruction jmp b15 +Removing instruction jmp b16 +Removing instruction jmp b17 +Removing instruction jmp b18 +Removing instruction jmp b19 +Removing instruction jmp b20 +Removing instruction jmp b21 +Removing instruction jmp b22 +Removing instruction jmp b23 +Removing instruction jmp b24 +Removing instruction jmp b25 +Removing instruction jmp b26 +Removing instruction jmp b27 +Removing instruction jmp b28 +Removing instruction jmp b29 +Removing instruction jmp b30 +Removing instruction jmp b31 +Removing instruction jmp b32 +Removing instruction jmp b33 +Removing instruction jmp b34 +Removing instruction jmp b35 +Removing instruction jmp breturn +Removing instruction jmp b3 +Removing instruction jmp b2 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp b4 +Removing instruction jmp b5 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_SIGNED_BYTE with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_SIGNED_BYTE with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b1 with b1 +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_b1: +Removing instruction b2_from_b1: +Removing instruction testUnaryOperator_from_b2: +Removing instruction b3_from_b2: +Removing instruction testBinaryOperator_from_b3: +Removing instruction b1_from_testBinaryOperator: +Removing instruction assertType_from_b1: +Removing instruction b2_from_b1: +Removing instruction assertType_from_b2: +Removing instruction b3_from_b2: +Removing instruction assertType_from_b3: +Removing instruction b4_from_b3: +Removing instruction assertType_from_b4: +Removing instruction b5_from_b4: +Removing instruction assertType_from_b5: +Removing instruction b7_from_b6: +Removing instruction assertType_from_b7: +Removing instruction b8_from_b7: +Removing instruction assertType_from_b8: +Removing instruction b9_from_b8: +Removing instruction assertType_from_b9: +Removing instruction b10_from_b9: +Removing instruction assertType_from_b10: +Removing instruction b11_from_b10: +Removing instruction assertType_from_b11: +Removing instruction b13_from_b12: +Removing instruction assertType_from_b13: +Removing instruction b14_from_b13: +Removing instruction assertType_from_b14: +Removing instruction b15_from_b14: +Removing instruction assertType_from_b15: +Removing instruction b16_from_b15: +Removing instruction assertType_from_b16: +Removing instruction b17_from_b16: +Removing instruction assertType_from_b17: +Removing instruction b18_from_b17: +Removing instruction assertType_from_b18: +Removing instruction b19_from_b18: +Removing instruction assertType_from_b19: +Removing instruction b20_from_b19: +Removing instruction assertType_from_b20: +Removing instruction b21_from_b20: +Removing instruction assertType_from_b21: +Removing instruction b22_from_b21: +Removing instruction assertType_from_b22: +Removing instruction b23_from_b22: +Removing instruction assertType_from_b23: +Removing instruction b25_from_b24: +Removing instruction assertType_from_b25: +Removing instruction b26_from_b25: +Removing instruction assertType_from_b26: +Removing instruction b27_from_b26: +Removing instruction assertType_from_b27: +Removing instruction b28_from_b27: +Removing instruction assertType_from_b28: +Removing instruction b29_from_b28: +Removing instruction assertType_from_b29: +Removing instruction b31_from_b30: +Removing instruction assertType_from_b31: +Removing instruction b32_from_b31: +Removing instruction assertType_from_b32: +Removing instruction b33_from_b32: +Removing instruction assertType_from_b33: +Removing instruction b34_from_b33: +Removing instruction assertType_from_b34: +Removing instruction b35_from_b34: +Removing instruction assertType_from_b35: +Removing instruction b1_from_testUnaryOperator: +Removing instruction assertType_from_b1: +Removing instruction b2_from_b1: +Removing instruction assertType_from_b2: +Removing instruction b3_from_b2: +Removing instruction assertType_from_b3: +Removing instruction b4_from_b3: +Removing instruction assertType_from_b4: +Removing instruction b5_from_b4: +Removing instruction assertType_from_b5: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction b1_from_main: +Removing instruction b2: +Removing instruction b3: +Removing instruction breturn: +Removing instruction assertType_from_testBinaryOperator: +Removing instruction b1: +Removing instruction b2: +Removing instruction b3: +Removing instruction b4: +Removing instruction b5: +Removing instruction b6: +Removing instruction assertType_from_b6: +Removing instruction b7: +Removing instruction b8: +Removing instruction b9: +Removing instruction b10: +Removing instruction b11: +Removing instruction b12: +Removing instruction assertType_from_b12: +Removing instruction b13: +Removing instruction b14: +Removing instruction b15: +Removing instruction b16: +Removing instruction b17: +Removing instruction b18: +Removing instruction b19: +Removing instruction b20: +Removing instruction b21: +Removing instruction b22: +Removing instruction b23: +Removing instruction b24: +Removing instruction assertType_from_b24: +Removing instruction b25: +Removing instruction b26: +Removing instruction b27: +Removing instruction b28: +Removing instruction b29: +Removing instruction b30: +Removing instruction assertType_from_b30: +Removing instruction b31: +Removing instruction b32: +Removing instruction b33: +Removing instruction b34: +Removing instruction b35: +Removing instruction breturn: +Removing instruction b3: +Removing instruction breturn: +Removing instruction assertType_from_testUnaryOperator: +Removing instruction b1: +Removing instruction b2: +Removing instruction b3: +Removing instruction b4: +Removing instruction b5: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction jmp b1 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) COLS +(const byte*) COLS#0 COLS = ((byte*))(word) $d800 +(byte) GREEN +(const byte) GREEN#0 GREEN = (byte) 5 +(byte) RED +(const byte) RED#0 RED = (byte) 2 +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = ((byte*))(word) $400 +(const byte) TYPEID_BYTE TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#42 reg byte y 1.0 +(byte) assertType::t2 +(byte) assertType::t2#42 t2 zp ZP_BYTE:4 2.0 +(byte) idx +(byte) idx#105 reg byte x 17.200000000000003 +(byte) idx#108 reg byte x 1.0526315789473677 +(byte) idx#19 reg byte x 4.0 +(byte) idx#26 reg byte x 4.0 +(byte) idx#40 reg byte x 4.0 +(byte) idx#47 reg byte x 4.0 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@return +(byte*) main::s +(byte*) main::s#1 s zp ZP_WORD:2 16.5 +(byte*) main::s#2 s zp ZP_WORD:2 16.5 +(void()) testBinaryOperator() +(label) testBinaryOperator::@1 +(label) testBinaryOperator::@10 +(label) testBinaryOperator::@11 +(label) testBinaryOperator::@12 +(label) testBinaryOperator::@13 +(label) testBinaryOperator::@14 +(label) testBinaryOperator::@15 +(label) testBinaryOperator::@16 +(label) testBinaryOperator::@17 +(label) testBinaryOperator::@18 +(label) testBinaryOperator::@19 +(label) testBinaryOperator::@2 +(label) testBinaryOperator::@20 +(label) testBinaryOperator::@21 +(label) testBinaryOperator::@22 +(label) testBinaryOperator::@23 +(label) testBinaryOperator::@24 +(label) testBinaryOperator::@25 +(label) testBinaryOperator::@26 +(label) testBinaryOperator::@27 +(label) testBinaryOperator::@28 +(label) testBinaryOperator::@29 +(label) testBinaryOperator::@3 +(label) testBinaryOperator::@30 +(label) testBinaryOperator::@31 +(label) testBinaryOperator::@32 +(label) testBinaryOperator::@33 +(label) testBinaryOperator::@34 +(label) testBinaryOperator::@35 +(label) testBinaryOperator::@4 +(label) testBinaryOperator::@5 +(label) testBinaryOperator::@6 +(label) testBinaryOperator::@7 +(label) testBinaryOperator::@8 +(label) testBinaryOperator::@9 +(label) testBinaryOperator::@return +(void()) testUnaryOperator() +(label) testUnaryOperator::@1 +(label) testUnaryOperator::@2 +(label) testUnaryOperator::@3 +(label) testUnaryOperator::@4 +(label) testUnaryOperator::@5 +(label) testUnaryOperator::@return + +zp ZP_WORD:2 [ main::s#2 main::s#1 ] +reg byte y [ assertType::t1#42 ] +zp ZP_BYTE:4 [ assertType::t2#42 ] +reg byte x [ idx#105 idx#108 idx#26 idx#40 idx#47 idx#19 ] + + +FINAL ASSEMBLER +Score: 1159 + +//SEG0 File Comments +// Tests different integer literal types +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_BYTE = 1 + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_WORD = 3 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_DWORD = 5 + .const TYPEID_SIGNED_DWORD = 6 + .const RED = 2 + .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .label s = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + //SEG12 [5] phi (byte*) main::s#2 = (const byte*) SCREEN#0 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #SCREEN + sta s+1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + //SEG14 [5] phi (byte*) main::s#2 = (byte*) main::s#1 [phi:main::@1->main::@1#0] -- register_copy + //SEG15 main::@1 + b1: + //SEG16 [6] *((byte*) main::s#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (s),y + //SEG17 [7] (byte*) main::s#1 ← ++ (byte*) main::s#2 -- pbuz1=_inc_pbuz1 + inc s + bne !+ + inc s+1 + !: + //SEG18 [8] if((byte*) main::s#1<(const byte*) SCREEN#0+(word) $3e8) goto main::@1 -- pbuz1_lt_pbuc1_then_la1 + lda s+1 + cmp #>SCREEN+$3e8 + bcc b1 + bne !+ + lda s + cmp #main::@2] + //SEG20 main::@2 + //SEG21 [10] call testUnaryOperator + //SEG22 [94] phi from main::@2 to testUnaryOperator [phi:main::@2->testUnaryOperator] + jsr testUnaryOperator + //SEG23 [11] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + //SEG24 main::@3 + //SEG25 [12] call testBinaryOperator + //SEG26 [14] phi from main::@3 to testBinaryOperator [phi:main::@3->testBinaryOperator] + jsr testBinaryOperator + //SEG27 main::@return + //SEG28 [13] return + rts +} +//SEG29 testBinaryOperator +testBinaryOperator: { + //SEG30 [15] call assertType + //SEG31 [87] phi from testBinaryOperator to assertType [phi:testBinaryOperator->assertType] + //SEG32 [87] phi (byte) idx#105 = (byte) $28 [phi:testBinaryOperator->assertType#0] -- vbuxx=vbuc1 + ldx #$28 + //SEG33 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG34 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG35 [16] phi from testBinaryOperator to testBinaryOperator::@1 [phi:testBinaryOperator->testBinaryOperator::@1] + //SEG36 testBinaryOperator::@1 + //SEG37 [17] call assertType + //SEG38 [87] phi from testBinaryOperator::@1 to assertType [phi:testBinaryOperator::@1->assertType] + //SEG39 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@1->assertType#0] -- register_copy + //SEG40 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG41 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@1->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG42 [18] phi from testBinaryOperator::@1 to testBinaryOperator::@2 [phi:testBinaryOperator::@1->testBinaryOperator::@2] + //SEG43 testBinaryOperator::@2 + //SEG44 [19] call assertType + //SEG45 [87] phi from testBinaryOperator::@2 to assertType [phi:testBinaryOperator::@2->assertType] + //SEG46 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@2->assertType#0] -- register_copy + //SEG47 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG48 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@2->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG49 [20] phi from testBinaryOperator::@2 to testBinaryOperator::@3 [phi:testBinaryOperator::@2->testBinaryOperator::@3] + //SEG50 testBinaryOperator::@3 + //SEG51 [21] call assertType + //SEG52 [87] phi from testBinaryOperator::@3 to assertType [phi:testBinaryOperator::@3->assertType] + //SEG53 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@3->assertType#0] -- register_copy + //SEG54 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG55 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@3->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG56 [22] phi from testBinaryOperator::@3 to testBinaryOperator::@4 [phi:testBinaryOperator::@3->testBinaryOperator::@4] + //SEG57 testBinaryOperator::@4 + //SEG58 [23] call assertType + //SEG59 [87] phi from testBinaryOperator::@4 to assertType [phi:testBinaryOperator::@4->assertType] + //SEG60 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@4->assertType#0] -- register_copy + //SEG61 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG62 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@4->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG63 [24] phi from testBinaryOperator::@4 to testBinaryOperator::@5 [phi:testBinaryOperator::@4->testBinaryOperator::@5] + //SEG64 testBinaryOperator::@5 + //SEG65 [25] call assertType + //SEG66 [87] phi from testBinaryOperator::@5 to assertType [phi:testBinaryOperator::@5->assertType] + //SEG67 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@5->assertType#0] -- register_copy + //SEG68 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG69 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@5->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG70 testBinaryOperator::@6 + //SEG71 [26] (byte) idx#19 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG72 [27] call assertType + //SEG73 [87] phi from testBinaryOperator::@6 to assertType [phi:testBinaryOperator::@6->assertType] + //SEG74 [87] phi (byte) idx#105 = (byte) idx#19 [phi:testBinaryOperator::@6->assertType#0] -- register_copy + //SEG75 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG76 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testBinaryOperator::@6->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG77 [28] phi from testBinaryOperator::@6 to testBinaryOperator::@7 [phi:testBinaryOperator::@6->testBinaryOperator::@7] + //SEG78 testBinaryOperator::@7 + //SEG79 [29] call assertType + //SEG80 [87] phi from testBinaryOperator::@7 to assertType [phi:testBinaryOperator::@7->assertType] + //SEG81 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@7->assertType#0] -- register_copy + //SEG82 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testBinaryOperator::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG83 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testBinaryOperator::@7->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG84 [30] phi from testBinaryOperator::@7 to testBinaryOperator::@8 [phi:testBinaryOperator::@7->testBinaryOperator::@8] + //SEG85 testBinaryOperator::@8 + //SEG86 [31] call assertType + //SEG87 [87] phi from testBinaryOperator::@8 to assertType [phi:testBinaryOperator::@8->assertType] + //SEG88 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@8->assertType#0] -- register_copy + //SEG89 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG90 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@8->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG91 [32] phi from testBinaryOperator::@8 to testBinaryOperator::@9 [phi:testBinaryOperator::@8->testBinaryOperator::@9] + //SEG92 testBinaryOperator::@9 + //SEG93 [33] call assertType + //SEG94 [87] phi from testBinaryOperator::@9 to assertType [phi:testBinaryOperator::@9->assertType] + //SEG95 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@9->assertType#0] -- register_copy + //SEG96 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG97 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@9->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG98 [34] phi from testBinaryOperator::@9 to testBinaryOperator::@10 [phi:testBinaryOperator::@9->testBinaryOperator::@10] + //SEG99 testBinaryOperator::@10 + //SEG100 [35] call assertType + //SEG101 [87] phi from testBinaryOperator::@10 to assertType [phi:testBinaryOperator::@10->assertType] + //SEG102 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@10->assertType#0] -- register_copy + //SEG103 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG104 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@10->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG105 [36] phi from testBinaryOperator::@10 to testBinaryOperator::@11 [phi:testBinaryOperator::@10->testBinaryOperator::@11] + //SEG106 testBinaryOperator::@11 + //SEG107 [37] call assertType + //SEG108 [87] phi from testBinaryOperator::@11 to assertType [phi:testBinaryOperator::@11->assertType] + //SEG109 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@11->assertType#0] -- register_copy + //SEG110 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG111 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@11->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG112 testBinaryOperator::@12 + //SEG113 [38] (byte) idx#26 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG114 [39] call assertType + //SEG115 [87] phi from testBinaryOperator::@12 to assertType [phi:testBinaryOperator::@12->assertType] + //SEG116 [87] phi (byte) idx#105 = (byte) idx#26 [phi:testBinaryOperator::@12->assertType#0] -- register_copy + //SEG117 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG118 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@12->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG119 [40] phi from testBinaryOperator::@12 to testBinaryOperator::@13 [phi:testBinaryOperator::@12->testBinaryOperator::@13] + //SEG120 testBinaryOperator::@13 + //SEG121 [41] call assertType + //SEG122 [87] phi from testBinaryOperator::@13 to assertType [phi:testBinaryOperator::@13->assertType] + //SEG123 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@13->assertType#0] -- register_copy + //SEG124 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG125 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@13->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG126 [42] phi from testBinaryOperator::@13 to testBinaryOperator::@14 [phi:testBinaryOperator::@13->testBinaryOperator::@14] + //SEG127 testBinaryOperator::@14 + //SEG128 [43] call assertType + //SEG129 [87] phi from testBinaryOperator::@14 to assertType [phi:testBinaryOperator::@14->assertType] + //SEG130 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@14->assertType#0] -- register_copy + //SEG131 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG132 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@14->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG133 [44] phi from testBinaryOperator::@14 to testBinaryOperator::@15 [phi:testBinaryOperator::@14->testBinaryOperator::@15] + //SEG134 testBinaryOperator::@15 + //SEG135 [45] call assertType + //SEG136 [87] phi from testBinaryOperator::@15 to assertType [phi:testBinaryOperator::@15->assertType] + //SEG137 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@15->assertType#0] -- register_copy + //SEG138 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@15->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG139 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@15->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG140 [46] phi from testBinaryOperator::@15 to testBinaryOperator::@16 [phi:testBinaryOperator::@15->testBinaryOperator::@16] + //SEG141 testBinaryOperator::@16 + //SEG142 [47] call assertType + //SEG143 [87] phi from testBinaryOperator::@16 to assertType [phi:testBinaryOperator::@16->assertType] + //SEG144 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@16->assertType#0] -- register_copy + //SEG145 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@16->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG146 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@16->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG147 [48] phi from testBinaryOperator::@16 to testBinaryOperator::@17 [phi:testBinaryOperator::@16->testBinaryOperator::@17] + //SEG148 testBinaryOperator::@17 + //SEG149 [49] call assertType + //SEG150 [87] phi from testBinaryOperator::@17 to assertType [phi:testBinaryOperator::@17->assertType] + //SEG151 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@17->assertType#0] -- register_copy + //SEG152 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@17->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG153 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@17->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG154 [50] phi from testBinaryOperator::@17 to testBinaryOperator::@18 [phi:testBinaryOperator::@17->testBinaryOperator::@18] + //SEG155 testBinaryOperator::@18 + //SEG156 [51] call assertType + //SEG157 [87] phi from testBinaryOperator::@18 to assertType [phi:testBinaryOperator::@18->assertType] + //SEG158 [87] phi (byte) idx#105 = (byte) $50 [phi:testBinaryOperator::@18->assertType#0] -- vbuxx=vbuc1 + ldx #$50 + //SEG159 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@18->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG160 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@18->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG161 [52] phi from testBinaryOperator::@18 to testBinaryOperator::@19 [phi:testBinaryOperator::@18->testBinaryOperator::@19] + //SEG162 testBinaryOperator::@19 + //SEG163 [53] call assertType + //SEG164 [87] phi from testBinaryOperator::@19 to assertType [phi:testBinaryOperator::@19->assertType] + //SEG165 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@19->assertType#0] -- register_copy + //SEG166 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@19->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG167 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@19->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG168 [54] phi from testBinaryOperator::@19 to testBinaryOperator::@20 [phi:testBinaryOperator::@19->testBinaryOperator::@20] + //SEG169 testBinaryOperator::@20 + //SEG170 [55] call assertType + //SEG171 [87] phi from testBinaryOperator::@20 to assertType [phi:testBinaryOperator::@20->assertType] + //SEG172 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@20->assertType#0] -- register_copy + //SEG173 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@20->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG174 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testBinaryOperator::@20->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG175 [56] phi from testBinaryOperator::@20 to testBinaryOperator::@21 [phi:testBinaryOperator::@20->testBinaryOperator::@21] + //SEG176 testBinaryOperator::@21 + //SEG177 [57] call assertType + //SEG178 [87] phi from testBinaryOperator::@21 to assertType [phi:testBinaryOperator::@21->assertType] + //SEG179 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@21->assertType#0] -- register_copy + //SEG180 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@21->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG181 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testBinaryOperator::@21->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG182 [58] phi from testBinaryOperator::@21 to testBinaryOperator::@22 [phi:testBinaryOperator::@21->testBinaryOperator::@22] + //SEG183 testBinaryOperator::@22 + //SEG184 [59] call assertType + //SEG185 [87] phi from testBinaryOperator::@22 to assertType [phi:testBinaryOperator::@22->assertType] + //SEG186 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@22->assertType#0] -- register_copy + //SEG187 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@22->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG188 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@22->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG189 [60] phi from testBinaryOperator::@22 to testBinaryOperator::@23 [phi:testBinaryOperator::@22->testBinaryOperator::@23] + //SEG190 testBinaryOperator::@23 + //SEG191 [61] call assertType + //SEG192 [87] phi from testBinaryOperator::@23 to assertType [phi:testBinaryOperator::@23->assertType] + //SEG193 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@23->assertType#0] -- register_copy + //SEG194 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@23->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG195 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@23->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG196 testBinaryOperator::@24 + //SEG197 [62] (byte) idx#40 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG198 [63] call assertType + //SEG199 [87] phi from testBinaryOperator::@24 to assertType [phi:testBinaryOperator::@24->assertType] + //SEG200 [87] phi (byte) idx#105 = (byte) idx#40 [phi:testBinaryOperator::@24->assertType#0] -- register_copy + //SEG201 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@24->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG202 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@24->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG203 [64] phi from testBinaryOperator::@24 to testBinaryOperator::@25 [phi:testBinaryOperator::@24->testBinaryOperator::@25] + //SEG204 testBinaryOperator::@25 + //SEG205 [65] call assertType + //SEG206 [87] phi from testBinaryOperator::@25 to assertType [phi:testBinaryOperator::@25->assertType] + //SEG207 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@25->assertType#0] -- register_copy + //SEG208 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@25->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG209 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@25->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG210 [66] phi from testBinaryOperator::@25 to testBinaryOperator::@26 [phi:testBinaryOperator::@25->testBinaryOperator::@26] + //SEG211 testBinaryOperator::@26 + //SEG212 [67] call assertType + //SEG213 [87] phi from testBinaryOperator::@26 to assertType [phi:testBinaryOperator::@26->assertType] + //SEG214 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@26->assertType#0] -- register_copy + //SEG215 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@26->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG216 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@26->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG217 [68] phi from testBinaryOperator::@26 to testBinaryOperator::@27 [phi:testBinaryOperator::@26->testBinaryOperator::@27] + //SEG218 testBinaryOperator::@27 + //SEG219 [69] call assertType + //SEG220 [87] phi from testBinaryOperator::@27 to assertType [phi:testBinaryOperator::@27->assertType] + //SEG221 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@27->assertType#0] -- register_copy + //SEG222 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@27->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG223 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@27->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG224 [70] phi from testBinaryOperator::@27 to testBinaryOperator::@28 [phi:testBinaryOperator::@27->testBinaryOperator::@28] + //SEG225 testBinaryOperator::@28 + //SEG226 [71] call assertType + //SEG227 [87] phi from testBinaryOperator::@28 to assertType [phi:testBinaryOperator::@28->assertType] + //SEG228 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@28->assertType#0] -- register_copy + //SEG229 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@28->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG230 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@28->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG231 [72] phi from testBinaryOperator::@28 to testBinaryOperator::@29 [phi:testBinaryOperator::@28->testBinaryOperator::@29] + //SEG232 testBinaryOperator::@29 + //SEG233 [73] call assertType + //SEG234 [87] phi from testBinaryOperator::@29 to assertType [phi:testBinaryOperator::@29->assertType] + //SEG235 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@29->assertType#0] -- register_copy + //SEG236 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@29->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG237 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@29->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG238 testBinaryOperator::@30 + //SEG239 [74] (byte) idx#47 ← ++ (byte) idx#108 -- vbuxx=_inc_vbuxx + inx + //SEG240 [75] call assertType + //SEG241 [87] phi from testBinaryOperator::@30 to assertType [phi:testBinaryOperator::@30->assertType] + //SEG242 [87] phi (byte) idx#105 = (byte) idx#47 [phi:testBinaryOperator::@30->assertType#0] -- register_copy + //SEG243 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@30->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG244 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@30->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG245 [76] phi from testBinaryOperator::@30 to testBinaryOperator::@31 [phi:testBinaryOperator::@30->testBinaryOperator::@31] + //SEG246 testBinaryOperator::@31 + //SEG247 [77] call assertType + //SEG248 [87] phi from testBinaryOperator::@31 to assertType [phi:testBinaryOperator::@31->assertType] + //SEG249 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@31->assertType#0] -- register_copy + //SEG250 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@31->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG251 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@31->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG252 [78] phi from testBinaryOperator::@31 to testBinaryOperator::@32 [phi:testBinaryOperator::@31->testBinaryOperator::@32] + //SEG253 testBinaryOperator::@32 + //SEG254 [79] call assertType + //SEG255 [87] phi from testBinaryOperator::@32 to assertType [phi:testBinaryOperator::@32->assertType] + //SEG256 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@32->assertType#0] -- register_copy + //SEG257 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@32->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG258 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@32->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG259 [80] phi from testBinaryOperator::@32 to testBinaryOperator::@33 [phi:testBinaryOperator::@32->testBinaryOperator::@33] + //SEG260 testBinaryOperator::@33 + //SEG261 [81] call assertType + //SEG262 [87] phi from testBinaryOperator::@33 to assertType [phi:testBinaryOperator::@33->assertType] + //SEG263 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@33->assertType#0] -- register_copy + //SEG264 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@33->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG265 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@33->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG266 [82] phi from testBinaryOperator::@33 to testBinaryOperator::@34 [phi:testBinaryOperator::@33->testBinaryOperator::@34] + //SEG267 testBinaryOperator::@34 + //SEG268 [83] call assertType + //SEG269 [87] phi from testBinaryOperator::@34 to assertType [phi:testBinaryOperator::@34->assertType] + //SEG270 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@34->assertType#0] -- register_copy + //SEG271 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@34->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG272 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testBinaryOperator::@34->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG273 [84] phi from testBinaryOperator::@34 to testBinaryOperator::@35 [phi:testBinaryOperator::@34->testBinaryOperator::@35] + //SEG274 testBinaryOperator::@35 + //SEG275 [85] call assertType + //SEG276 [87] phi from testBinaryOperator::@35 to assertType [phi:testBinaryOperator::@35->assertType] + //SEG277 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testBinaryOperator::@35->assertType#0] -- register_copy + //SEG278 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@35->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG279 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testBinaryOperator::@35->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG280 testBinaryOperator::@return + //SEG281 [86] return + rts +} +//SEG282 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(4) t2) +assertType: { + .label t2 = 4 + //SEG283 [88] if((byte) assertType::t1#42==(byte) assertType::t2#42) goto assertType::@1 -- vbuyy_eq_vbuz1_then_la1 + tya + cmp t2 + beq b1 + //SEG284 assertType::@3 + //SEG285 [89] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) RED#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #RED + sta COLS,x + //SEG286 assertType::@2 + b2: + //SEG287 [90] *((const byte*) SCREEN#0 + (byte) idx#105) ← (byte) assertType::t1#42 -- pbuc1_derefidx_vbuxx=vbuyy + tya + sta SCREEN,x + //SEG288 [91] (byte) idx#108 ← ++ (byte) idx#105 -- vbuxx=_inc_vbuxx + inx + //SEG289 assertType::@return + //SEG290 [92] return + rts + //SEG291 assertType::@1 + b1: + //SEG292 [93] *((const byte*) COLS#0 + (byte) idx#105) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #GREEN + sta COLS,x + jmp b2 +} +//SEG293 testUnaryOperator +testUnaryOperator: { + //SEG294 [95] call assertType + //SEG295 [87] phi from testUnaryOperator to assertType [phi:testUnaryOperator->assertType] + //SEG296 [87] phi (byte) idx#105 = (byte) 0 [phi:testUnaryOperator->assertType#0] -- vbuxx=vbuc1 + ldx #0 + //SEG297 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_BYTE [phi:testUnaryOperator->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG298 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_BYTE [phi:testUnaryOperator->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG299 [96] phi from testUnaryOperator to testUnaryOperator::@1 [phi:testUnaryOperator->testUnaryOperator::@1] + //SEG300 testUnaryOperator::@1 + //SEG301 [97] call assertType + //SEG302 [87] phi from testUnaryOperator::@1 to assertType [phi:testUnaryOperator::@1->assertType] + //SEG303 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@1->assertType#0] -- register_copy + //SEG304 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testUnaryOperator::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG305 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_BYTE [phi:testUnaryOperator::@1->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG306 [98] phi from testUnaryOperator::@1 to testUnaryOperator::@2 [phi:testUnaryOperator::@1->testUnaryOperator::@2] + //SEG307 testUnaryOperator::@2 + //SEG308 [99] call assertType + //SEG309 [87] phi from testUnaryOperator::@2 to assertType [phi:testUnaryOperator::@2->assertType] + //SEG310 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@2->assertType#0] -- register_copy + //SEG311 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_WORD [phi:testUnaryOperator::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG312 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_WORD [phi:testUnaryOperator::@2->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG313 [100] phi from testUnaryOperator::@2 to testUnaryOperator::@3 [phi:testUnaryOperator::@2->testUnaryOperator::@3] + //SEG314 testUnaryOperator::@3 + //SEG315 [101] call assertType + //SEG316 [87] phi from testUnaryOperator::@3 to assertType [phi:testUnaryOperator::@3->assertType] + //SEG317 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@3->assertType#0] -- register_copy + //SEG318 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_WORD [phi:testUnaryOperator::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG319 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_WORD [phi:testUnaryOperator::@3->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG320 [102] phi from testUnaryOperator::@3 to testUnaryOperator::@4 [phi:testUnaryOperator::@3->testUnaryOperator::@4] + //SEG321 testUnaryOperator::@4 + //SEG322 [103] call assertType + //SEG323 [87] phi from testUnaryOperator::@4 to assertType [phi:testUnaryOperator::@4->assertType] + //SEG324 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@4->assertType#0] -- register_copy + //SEG325 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_DWORD [phi:testUnaryOperator::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG326 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_DWORD [phi:testUnaryOperator::@4->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG327 [104] phi from testUnaryOperator::@4 to testUnaryOperator::@5 [phi:testUnaryOperator::@4->testUnaryOperator::@5] + //SEG328 testUnaryOperator::@5 + //SEG329 [105] call assertType + //SEG330 [87] phi from testUnaryOperator::@5 to assertType [phi:testUnaryOperator::@5->assertType] + //SEG331 [87] phi (byte) idx#105 = (byte) idx#108 [phi:testUnaryOperator::@5->assertType#0] -- register_copy + //SEG332 [87] phi (byte) assertType::t2#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testUnaryOperator::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG333 [87] phi (byte) assertType::t1#42 = (const byte) TYPEID_SIGNED_DWORD [phi:testUnaryOperator::@5->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG334 testUnaryOperator::@return + //SEG335 [106] return + rts +} + diff --git a/src/test/ref/int-conversion.sym b/src/test/ref/int-conversion.sym new file mode 100644 index 000000000..c17ed3db6 --- /dev/null +++ b/src/test/ref/int-conversion.sym @@ -0,0 +1,90 @@ +(label) @1 +(label) @begin +(label) @end +(byte*) COLS +(const byte*) COLS#0 COLS = ((byte*))(word) $d800 +(byte) GREEN +(const byte) GREEN#0 GREEN = (byte) 5 +(byte) RED +(const byte) RED#0 RED = (byte) 2 +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = ((byte*))(word) $400 +(const byte) TYPEID_BYTE TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#42 reg byte y 1.0 +(byte) assertType::t2 +(byte) assertType::t2#42 t2 zp ZP_BYTE:4 2.0 +(byte) idx +(byte) idx#105 reg byte x 17.200000000000003 +(byte) idx#108 reg byte x 1.0526315789473677 +(byte) idx#19 reg byte x 4.0 +(byte) idx#26 reg byte x 4.0 +(byte) idx#40 reg byte x 4.0 +(byte) idx#47 reg byte x 4.0 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@return +(byte*) main::s +(byte*) main::s#1 s zp ZP_WORD:2 16.5 +(byte*) main::s#2 s zp ZP_WORD:2 16.5 +(void()) testBinaryOperator() +(label) testBinaryOperator::@1 +(label) testBinaryOperator::@10 +(label) testBinaryOperator::@11 +(label) testBinaryOperator::@12 +(label) testBinaryOperator::@13 +(label) testBinaryOperator::@14 +(label) testBinaryOperator::@15 +(label) testBinaryOperator::@16 +(label) testBinaryOperator::@17 +(label) testBinaryOperator::@18 +(label) testBinaryOperator::@19 +(label) testBinaryOperator::@2 +(label) testBinaryOperator::@20 +(label) testBinaryOperator::@21 +(label) testBinaryOperator::@22 +(label) testBinaryOperator::@23 +(label) testBinaryOperator::@24 +(label) testBinaryOperator::@25 +(label) testBinaryOperator::@26 +(label) testBinaryOperator::@27 +(label) testBinaryOperator::@28 +(label) testBinaryOperator::@29 +(label) testBinaryOperator::@3 +(label) testBinaryOperator::@30 +(label) testBinaryOperator::@31 +(label) testBinaryOperator::@32 +(label) testBinaryOperator::@33 +(label) testBinaryOperator::@34 +(label) testBinaryOperator::@35 +(label) testBinaryOperator::@4 +(label) testBinaryOperator::@5 +(label) testBinaryOperator::@6 +(label) testBinaryOperator::@7 +(label) testBinaryOperator::@8 +(label) testBinaryOperator::@9 +(label) testBinaryOperator::@return +(void()) testUnaryOperator() +(label) testUnaryOperator::@1 +(label) testUnaryOperator::@2 +(label) testUnaryOperator::@3 +(label) testUnaryOperator::@4 +(label) testUnaryOperator::@5 +(label) testUnaryOperator::@return + +zp ZP_WORD:2 [ main::s#2 main::s#1 ] +reg byte y [ assertType::t1#42 ] +zp ZP_BYTE:4 [ assertType::t2#42 ] +reg byte x [ idx#105 idx#108 idx#26 idx#40 idx#47 idx#19 ] diff --git a/src/test/ref/int-literals.asm b/src/test/ref/int-literals.asm new file mode 100644 index 000000000..dc02bae1d --- /dev/null +++ b/src/test/ref/int-literals.asm @@ -0,0 +1,124 @@ +// Tests different integer literal types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const TYPEID_BYTE = 1 + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_WORD = 3 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_DWORD = 5 + .const TYPEID_SIGNED_DWORD = 6 + .const RED = 2 + .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 +main: { + .label s = 2 + lda #SCREEN + sta s+1 + b1: + lda #' ' + ldy #0 + sta (s),y + inc s + bne !+ + inc s+1 + !: + lda s+1 + cmp #>SCREEN+$3e8 + bcc b1 + bne !+ + lda s + cmp #@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label s = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte*) main::s#2 = (byte*)(word) $400 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta s + lda #>$400 + sta s+1 + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte*) main::s#2 = (byte*) main::s#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] *((byte*) main::s#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (s),y + //SEG17 [7] (byte*) main::s#1 ← ++ (byte*) main::s#2 -- pbuz1=_inc_pbuz1 + inc s + bne !+ + inc s+1 + !: + //SEG18 [8] if((byte*) main::s#1<(byte*)(word) $400+(word) $3e8) goto main::@1 -- pbuz1_lt_pbuc1_then_la1 + lda s+1 + cmp #>$400+$3e8 + bcc b1_from_b1 + bne !+ + lda s + cmp #<$400+$3e8 + bcc b1_from_b1 + !: + //SEG19 [9] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + jmp b2 + //SEG20 main::@2 + b2: + //SEG21 [10] call testSimpleTypes + //SEG22 [12] phi from main::@2 to testSimpleTypes [phi:main::@2->testSimpleTypes] + testSimpleTypes_from_b2: + jsr testSimpleTypes + jmp breturn + //SEG23 main::@return + breturn: + //SEG24 [11] return + rts +} +//SEG25 testSimpleTypes +testSimpleTypes: { + //SEG26 [13] call assertType + //SEG27 [43] phi from testSimpleTypes to assertType [phi:testSimpleTypes->assertType] + assertType_from_testSimpleTypes: + //SEG28 [43] phi (byte) idx#41 = (byte) 0 [phi:testSimpleTypes->assertType#0] -- vbuz1=vbuc1 + lda #0 + sta idx + //SEG29 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG30 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG31 [14] phi from testSimpleTypes to testSimpleTypes::@1 [phi:testSimpleTypes->testSimpleTypes::@1] + b1_from_testSimpleTypes: + jmp b1 + //SEG32 testSimpleTypes::@1 + b1: + //SEG33 [15] call assertType + //SEG34 [43] phi from testSimpleTypes::@1 to assertType [phi:testSimpleTypes::@1->assertType] + assertType_from_b1: + //SEG35 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@1->assertType#0] -- register_copy + //SEG36 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG37 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes::@1->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG38 [16] phi from testSimpleTypes::@1 to testSimpleTypes::@2 [phi:testSimpleTypes::@1->testSimpleTypes::@2] + b2_from_b1: + jmp b2 + //SEG39 testSimpleTypes::@2 + b2: + //SEG40 [17] call assertType + //SEG41 [43] phi from testSimpleTypes::@2 to assertType [phi:testSimpleTypes::@2->assertType] + assertType_from_b2: + //SEG42 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@2->assertType#0] -- register_copy + //SEG43 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG44 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@2->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t1 + jsr assertType + //SEG45 [18] phi from testSimpleTypes::@2 to testSimpleTypes::@3 [phi:testSimpleTypes::@2->testSimpleTypes::@3] + b3_from_b2: + jmp b3 + //SEG46 testSimpleTypes::@3 + b3: + //SEG47 [19] call assertType + //SEG48 [43] phi from testSimpleTypes::@3 to assertType [phi:testSimpleTypes::@3->assertType] + assertType_from_b3: + //SEG49 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@3->assertType#0] -- register_copy + //SEG50 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG51 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@3->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t1 + jsr assertType + //SEG52 [20] phi from testSimpleTypes::@3 to testSimpleTypes::@4 [phi:testSimpleTypes::@3->testSimpleTypes::@4] + b4_from_b3: + jmp b4 + //SEG53 testSimpleTypes::@4 + b4: + //SEG54 [21] call assertType + //SEG55 [43] phi from testSimpleTypes::@4 to assertType [phi:testSimpleTypes::@4->assertType] + assertType_from_b4: + //SEG56 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@4->assertType#0] -- register_copy + //SEG57 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG58 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@4->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG59 [22] phi from testSimpleTypes::@4 to testSimpleTypes::@5 [phi:testSimpleTypes::@4->testSimpleTypes::@5] + b5_from_b4: + jmp b5 + //SEG60 testSimpleTypes::@5 + b5: + //SEG61 [23] call assertType + //SEG62 [43] phi from testSimpleTypes::@5 to assertType [phi:testSimpleTypes::@5->assertType] + assertType_from_b5: + //SEG63 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@5->assertType#0] -- register_copy + //SEG64 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG65 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@5->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG66 [24] phi from testSimpleTypes::@5 to testSimpleTypes::@6 [phi:testSimpleTypes::@5->testSimpleTypes::@6] + b6_from_b5: + jmp b6 + //SEG67 testSimpleTypes::@6 + b6: + //SEG68 [25] call assertType + //SEG69 [43] phi from testSimpleTypes::@6 to assertType [phi:testSimpleTypes::@6->assertType] + assertType_from_b6: + //SEG70 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@6->assertType#0] -- register_copy + //SEG71 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG72 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@6->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG73 [26] phi from testSimpleTypes::@6 to testSimpleTypes::@7 [phi:testSimpleTypes::@6->testSimpleTypes::@7] + b7_from_b6: + jmp b7 + //SEG74 testSimpleTypes::@7 + b7: + //SEG75 [27] call assertType + //SEG76 [43] phi from testSimpleTypes::@7 to assertType [phi:testSimpleTypes::@7->assertType] + assertType_from_b7: + //SEG77 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@7->assertType#0] -- register_copy + //SEG78 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG79 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@7->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG80 [28] phi from testSimpleTypes::@7 to testSimpleTypes::@8 [phi:testSimpleTypes::@7->testSimpleTypes::@8] + b8_from_b7: + jmp b8 + //SEG81 testSimpleTypes::@8 + b8: + //SEG82 [29] call assertType + //SEG83 [43] phi from testSimpleTypes::@8 to assertType [phi:testSimpleTypes::@8->assertType] + assertType_from_b8: + //SEG84 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@8->assertType#0] -- register_copy + //SEG85 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG86 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@8->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG87 [30] phi from testSimpleTypes::@8 to testSimpleTypes::@9 [phi:testSimpleTypes::@8->testSimpleTypes::@9] + b9_from_b8: + jmp b9 + //SEG88 testSimpleTypes::@9 + b9: + //SEG89 [31] call assertType + //SEG90 [43] phi from testSimpleTypes::@9 to assertType [phi:testSimpleTypes::@9->assertType] + assertType_from_b9: + //SEG91 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@9->assertType#0] -- register_copy + //SEG92 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG93 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@9->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG94 [32] phi from testSimpleTypes::@9 to testSimpleTypes::@10 [phi:testSimpleTypes::@9->testSimpleTypes::@10] + b10_from_b9: + jmp b10 + //SEG95 testSimpleTypes::@10 + b10: + //SEG96 [33] call assertType + //SEG97 [43] phi from testSimpleTypes::@10 to assertType [phi:testSimpleTypes::@10->assertType] + assertType_from_b10: + //SEG98 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@10->assertType#0] -- register_copy + //SEG99 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG100 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@10->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG101 [34] phi from testSimpleTypes::@10 to testSimpleTypes::@11 [phi:testSimpleTypes::@10->testSimpleTypes::@11] + b11_from_b10: + jmp b11 + //SEG102 testSimpleTypes::@11 + b11: + //SEG103 [35] call assertType + //SEG104 [43] phi from testSimpleTypes::@11 to assertType [phi:testSimpleTypes::@11->assertType] + assertType_from_b11: + //SEG105 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@11->assertType#0] -- register_copy + //SEG106 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG107 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@11->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG108 [36] phi from testSimpleTypes::@11 to testSimpleTypes::@12 [phi:testSimpleTypes::@11->testSimpleTypes::@12] + b12_from_b11: + jmp b12 + //SEG109 testSimpleTypes::@12 + b12: + //SEG110 [37] call assertType + //SEG111 [43] phi from testSimpleTypes::@12 to assertType [phi:testSimpleTypes::@12->assertType] + assertType_from_b12: + //SEG112 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@12->assertType#0] -- register_copy + //SEG113 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG114 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@12->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG115 [38] phi from testSimpleTypes::@12 to testSimpleTypes::@13 [phi:testSimpleTypes::@12->testSimpleTypes::@13] + b13_from_b12: + jmp b13 + //SEG116 testSimpleTypes::@13 + b13: + //SEG117 [39] call assertType + //SEG118 [43] phi from testSimpleTypes::@13 to assertType [phi:testSimpleTypes::@13->assertType] + assertType_from_b13: + //SEG119 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@13->assertType#0] -- register_copy + //SEG120 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG121 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@13->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG122 [40] phi from testSimpleTypes::@13 to testSimpleTypes::@14 [phi:testSimpleTypes::@13->testSimpleTypes::@14] + b14_from_b13: + jmp b14 + //SEG123 testSimpleTypes::@14 + b14: + //SEG124 [41] call assertType + //SEG125 [43] phi from testSimpleTypes::@14 to assertType [phi:testSimpleTypes::@14->assertType] + assertType_from_b14: + //SEG126 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@14->assertType#0] -- register_copy + //SEG127 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG128 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@14->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp breturn + //SEG129 testSimpleTypes::@return + breturn: + //SEG130 [42] return + rts +} +//SEG131 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte zeropage(4) t1, byte zeropage(5) t2) +assertType: { + .label t1 = 4 + .label t2 = 5 + //SEG132 [44] if((byte) assertType::t1#15==(byte) assertType::t2#15) goto assertType::@1 -- vbuz1_eq_vbuz2_then_la1 + lda t1 + cmp t2 + beq b1 + jmp b3 + //SEG133 assertType::@3 + b3: + //SEG134 [45] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) RED#0 -- pbuc1_derefidx_vbuz1=vbuc2 + lda #RED + ldy idx + sta $d800,y + jmp b2 + //SEG135 assertType::@2 + b2: + //SEG136 [46] *((byte*)(word) $400 + (byte) idx#41) ← (byte) assertType::t1#15 -- pbuc1_derefidx_vbuz1=vbuz2 + lda t1 + ldy idx + sta $400,y + //SEG137 [47] (byte) idx#20 ← ++ (byte) idx#41 -- vbuz1=_inc_vbuz1 + inc idx + jmp breturn + //SEG138 assertType::@return + breturn: + //SEG139 [48] return + rts + //SEG140 assertType::@1 + b1: + //SEG141 [49] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuz1=vbuc2 + lda #GREEN + ldy idx + sta $d800,y + jmp b2 +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [6] *((byte*) main::s#2) ← (byte) ' ' [ main::s#2 ] ( main:2 [ main::s#2 ] ) always clobbers reg byte a reg byte y +Statement [8] if((byte*) main::s#1<(byte*)(word) $400+(word) $3e8) goto main::@1 [ main::s#1 ] ( main:2 [ main::s#1 ] ) always clobbers reg byte a +Statement [45] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) RED#0 [ assertType::t1#15 idx#41 ] ( main:2::testSimpleTypes:10::assertType:13 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:15 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:17 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:19 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:21 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:23 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:25 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:27 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:29 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:31 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:33 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:35 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:37 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:39 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:41 [ assertType::t1#15 idx#41 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ assertType::t1#15 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ idx#41 idx#20 ] +Statement [46] *((byte*)(word) $400 + (byte) idx#41) ← (byte) assertType::t1#15 [ idx#41 ] ( main:2::testSimpleTypes:10::assertType:13 [ idx#41 ] main:2::testSimpleTypes:10::assertType:15 [ idx#41 ] main:2::testSimpleTypes:10::assertType:17 [ idx#41 ] main:2::testSimpleTypes:10::assertType:19 [ idx#41 ] main:2::testSimpleTypes:10::assertType:21 [ idx#41 ] main:2::testSimpleTypes:10::assertType:23 [ idx#41 ] main:2::testSimpleTypes:10::assertType:25 [ idx#41 ] main:2::testSimpleTypes:10::assertType:27 [ idx#41 ] main:2::testSimpleTypes:10::assertType:29 [ idx#41 ] main:2::testSimpleTypes:10::assertType:31 [ idx#41 ] main:2::testSimpleTypes:10::assertType:33 [ idx#41 ] main:2::testSimpleTypes:10::assertType:35 [ idx#41 ] main:2::testSimpleTypes:10::assertType:37 [ idx#41 ] main:2::testSimpleTypes:10::assertType:39 [ idx#41 ] main:2::testSimpleTypes:10::assertType:41 [ idx#41 ] ) always clobbers reg byte a +Statement [49] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) GREEN#0 [ assertType::t1#15 idx#41 ] ( main:2::testSimpleTypes:10::assertType:13 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:15 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:17 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:19 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:21 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:23 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:25 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:27 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:29 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:31 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:33 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:35 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:37 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:39 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:41 [ assertType::t1#15 idx#41 ] ) always clobbers reg byte a +Statement [6] *((byte*) main::s#2) ← (byte) ' ' [ main::s#2 ] ( main:2 [ main::s#2 ] ) always clobbers reg byte a reg byte y +Statement [8] if((byte*) main::s#1<(byte*)(word) $400+(word) $3e8) goto main::@1 [ main::s#1 ] ( main:2 [ main::s#1 ] ) always clobbers reg byte a +Statement [45] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) RED#0 [ assertType::t1#15 idx#41 ] ( main:2::testSimpleTypes:10::assertType:13 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:15 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:17 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:19 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:21 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:23 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:25 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:27 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:29 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:31 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:33 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:35 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:37 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:39 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:41 [ assertType::t1#15 idx#41 ] ) always clobbers reg byte a +Statement [46] *((byte*)(word) $400 + (byte) idx#41) ← (byte) assertType::t1#15 [ idx#41 ] ( main:2::testSimpleTypes:10::assertType:13 [ idx#41 ] main:2::testSimpleTypes:10::assertType:15 [ idx#41 ] main:2::testSimpleTypes:10::assertType:17 [ idx#41 ] main:2::testSimpleTypes:10::assertType:19 [ idx#41 ] main:2::testSimpleTypes:10::assertType:21 [ idx#41 ] main:2::testSimpleTypes:10::assertType:23 [ idx#41 ] main:2::testSimpleTypes:10::assertType:25 [ idx#41 ] main:2::testSimpleTypes:10::assertType:27 [ idx#41 ] main:2::testSimpleTypes:10::assertType:29 [ idx#41 ] main:2::testSimpleTypes:10::assertType:31 [ idx#41 ] main:2::testSimpleTypes:10::assertType:33 [ idx#41 ] main:2::testSimpleTypes:10::assertType:35 [ idx#41 ] main:2::testSimpleTypes:10::assertType:37 [ idx#41 ] main:2::testSimpleTypes:10::assertType:39 [ idx#41 ] main:2::testSimpleTypes:10::assertType:41 [ idx#41 ] ) always clobbers reg byte a +Statement [49] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) GREEN#0 [ assertType::t1#15 idx#41 ] ( main:2::testSimpleTypes:10::assertType:13 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:15 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:17 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:19 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:21 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:23 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:25 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:27 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:29 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:31 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:33 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:35 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:37 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:39 [ assertType::t1#15 idx#41 ] main:2::testSimpleTypes:10::assertType:41 [ assertType::t1#15 idx#41 ] ) always clobbers reg byte a +Potential registers zp ZP_WORD:2 [ main::s#2 main::s#1 ] : zp ZP_WORD:2 , +Potential registers zp ZP_BYTE:4 [ assertType::t1#15 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ assertType::t2#15 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:6 [ idx#41 idx#20 ] : zp ZP_BYTE:6 , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 33: zp ZP_WORD:2 [ main::s#2 main::s#1 ] +Uplift Scope [] 8.2: zp ZP_BYTE:6 [ idx#41 idx#20 ] +Uplift Scope [assertType] 2: zp ZP_BYTE:5 [ assertType::t2#15 ] 1: zp ZP_BYTE:4 [ assertType::t1#15 ] +Uplift Scope [testSimpleTypes] + +Uplifting [main] best 978 combination zp ZP_WORD:2 [ main::s#2 main::s#1 ] +Uplifting [] best 963 combination reg byte x [ idx#41 idx#20 ] +Uplifting [assertType] best 916 combination zp ZP_BYTE:5 [ assertType::t2#15 ] reg byte y [ assertType::t1#15 ] +Uplifting [testSimpleTypes] best 916 combination +Attempting to uplift remaining variables inzp ZP_BYTE:5 [ assertType::t2#15 ] +Uplifting [assertType] best 916 combination zp ZP_BYTE:5 [ assertType::t2#15 ] +Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:4 [ assertType::t2#15 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests different integer literal types +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_BYTE = 1 + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_WORD = 3 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_DWORD = 5 + .const TYPEID_SIGNED_DWORD = 6 + .const RED = 2 + .const GREEN = 5 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + .label s = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG12 [5] phi (byte*) main::s#2 = (byte*)(word) $400 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta s + lda #>$400 + sta s+1 + jmp b1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + b1_from_b1: + //SEG14 [5] phi (byte*) main::s#2 = (byte*) main::s#1 [phi:main::@1->main::@1#0] -- register_copy + jmp b1 + //SEG15 main::@1 + b1: + //SEG16 [6] *((byte*) main::s#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (s),y + //SEG17 [7] (byte*) main::s#1 ← ++ (byte*) main::s#2 -- pbuz1=_inc_pbuz1 + inc s + bne !+ + inc s+1 + !: + //SEG18 [8] if((byte*) main::s#1<(byte*)(word) $400+(word) $3e8) goto main::@1 -- pbuz1_lt_pbuc1_then_la1 + lda s+1 + cmp #>$400+$3e8 + bcc b1_from_b1 + bne !+ + lda s + cmp #<$400+$3e8 + bcc b1_from_b1 + !: + //SEG19 [9] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + jmp b2 + //SEG20 main::@2 + b2: + //SEG21 [10] call testSimpleTypes + //SEG22 [12] phi from main::@2 to testSimpleTypes [phi:main::@2->testSimpleTypes] + testSimpleTypes_from_b2: + jsr testSimpleTypes + jmp breturn + //SEG23 main::@return + breturn: + //SEG24 [11] return + rts +} +//SEG25 testSimpleTypes +testSimpleTypes: { + //SEG26 [13] call assertType + //SEG27 [43] phi from testSimpleTypes to assertType [phi:testSimpleTypes->assertType] + assertType_from_testSimpleTypes: + //SEG28 [43] phi (byte) idx#41 = (byte) 0 [phi:testSimpleTypes->assertType#0] -- vbuxx=vbuc1 + ldx #0 + //SEG29 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG30 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG31 [14] phi from testSimpleTypes to testSimpleTypes::@1 [phi:testSimpleTypes->testSimpleTypes::@1] + b1_from_testSimpleTypes: + jmp b1 + //SEG32 testSimpleTypes::@1 + b1: + //SEG33 [15] call assertType + //SEG34 [43] phi from testSimpleTypes::@1 to assertType [phi:testSimpleTypes::@1->assertType] + assertType_from_b1: + //SEG35 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@1->assertType#0] -- register_copy + //SEG36 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG37 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes::@1->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG38 [16] phi from testSimpleTypes::@1 to testSimpleTypes::@2 [phi:testSimpleTypes::@1->testSimpleTypes::@2] + b2_from_b1: + jmp b2 + //SEG39 testSimpleTypes::@2 + b2: + //SEG40 [17] call assertType + //SEG41 [43] phi from testSimpleTypes::@2 to assertType [phi:testSimpleTypes::@2->assertType] + assertType_from_b2: + //SEG42 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@2->assertType#0] -- register_copy + //SEG43 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG44 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@2->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_BYTE + jsr assertType + //SEG45 [18] phi from testSimpleTypes::@2 to testSimpleTypes::@3 [phi:testSimpleTypes::@2->testSimpleTypes::@3] + b3_from_b2: + jmp b3 + //SEG46 testSimpleTypes::@3 + b3: + //SEG47 [19] call assertType + //SEG48 [43] phi from testSimpleTypes::@3 to assertType [phi:testSimpleTypes::@3->assertType] + assertType_from_b3: + //SEG49 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@3->assertType#0] -- register_copy + //SEG50 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG51 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@3->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_BYTE + jsr assertType + //SEG52 [20] phi from testSimpleTypes::@3 to testSimpleTypes::@4 [phi:testSimpleTypes::@3->testSimpleTypes::@4] + b4_from_b3: + jmp b4 + //SEG53 testSimpleTypes::@4 + b4: + //SEG54 [21] call assertType + //SEG55 [43] phi from testSimpleTypes::@4 to assertType [phi:testSimpleTypes::@4->assertType] + assertType_from_b4: + //SEG56 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@4->assertType#0] -- register_copy + //SEG57 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG58 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@4->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG59 [22] phi from testSimpleTypes::@4 to testSimpleTypes::@5 [phi:testSimpleTypes::@4->testSimpleTypes::@5] + b5_from_b4: + jmp b5 + //SEG60 testSimpleTypes::@5 + b5: + //SEG61 [23] call assertType + //SEG62 [43] phi from testSimpleTypes::@5 to assertType [phi:testSimpleTypes::@5->assertType] + assertType_from_b5: + //SEG63 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@5->assertType#0] -- register_copy + //SEG64 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG65 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@5->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG66 [24] phi from testSimpleTypes::@5 to testSimpleTypes::@6 [phi:testSimpleTypes::@5->testSimpleTypes::@6] + b6_from_b5: + jmp b6 + //SEG67 testSimpleTypes::@6 + b6: + //SEG68 [25] call assertType + //SEG69 [43] phi from testSimpleTypes::@6 to assertType [phi:testSimpleTypes::@6->assertType] + assertType_from_b6: + //SEG70 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@6->assertType#0] -- register_copy + //SEG71 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG72 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@6->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG73 [26] phi from testSimpleTypes::@6 to testSimpleTypes::@7 [phi:testSimpleTypes::@6->testSimpleTypes::@7] + b7_from_b6: + jmp b7 + //SEG74 testSimpleTypes::@7 + b7: + //SEG75 [27] call assertType + //SEG76 [43] phi from testSimpleTypes::@7 to assertType [phi:testSimpleTypes::@7->assertType] + assertType_from_b7: + //SEG77 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@7->assertType#0] -- register_copy + //SEG78 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG79 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@7->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG80 [28] phi from testSimpleTypes::@7 to testSimpleTypes::@8 [phi:testSimpleTypes::@7->testSimpleTypes::@8] + b8_from_b7: + jmp b8 + //SEG81 testSimpleTypes::@8 + b8: + //SEG82 [29] call assertType + //SEG83 [43] phi from testSimpleTypes::@8 to assertType [phi:testSimpleTypes::@8->assertType] + assertType_from_b8: + //SEG84 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@8->assertType#0] -- register_copy + //SEG85 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG86 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@8->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG87 [30] phi from testSimpleTypes::@8 to testSimpleTypes::@9 [phi:testSimpleTypes::@8->testSimpleTypes::@9] + b9_from_b8: + jmp b9 + //SEG88 testSimpleTypes::@9 + b9: + //SEG89 [31] call assertType + //SEG90 [43] phi from testSimpleTypes::@9 to assertType [phi:testSimpleTypes::@9->assertType] + assertType_from_b9: + //SEG91 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@9->assertType#0] -- register_copy + //SEG92 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG93 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@9->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG94 [32] phi from testSimpleTypes::@9 to testSimpleTypes::@10 [phi:testSimpleTypes::@9->testSimpleTypes::@10] + b10_from_b9: + jmp b10 + //SEG95 testSimpleTypes::@10 + b10: + //SEG96 [33] call assertType + //SEG97 [43] phi from testSimpleTypes::@10 to assertType [phi:testSimpleTypes::@10->assertType] + assertType_from_b10: + //SEG98 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@10->assertType#0] -- register_copy + //SEG99 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG100 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@10->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG101 [34] phi from testSimpleTypes::@10 to testSimpleTypes::@11 [phi:testSimpleTypes::@10->testSimpleTypes::@11] + b11_from_b10: + jmp b11 + //SEG102 testSimpleTypes::@11 + b11: + //SEG103 [35] call assertType + //SEG104 [43] phi from testSimpleTypes::@11 to assertType [phi:testSimpleTypes::@11->assertType] + assertType_from_b11: + //SEG105 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@11->assertType#0] -- register_copy + //SEG106 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG107 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@11->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG108 [36] phi from testSimpleTypes::@11 to testSimpleTypes::@12 [phi:testSimpleTypes::@11->testSimpleTypes::@12] + b12_from_b11: + jmp b12 + //SEG109 testSimpleTypes::@12 + b12: + //SEG110 [37] call assertType + //SEG111 [43] phi from testSimpleTypes::@12 to assertType [phi:testSimpleTypes::@12->assertType] + assertType_from_b12: + //SEG112 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@12->assertType#0] -- register_copy + //SEG113 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG114 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@12->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG115 [38] phi from testSimpleTypes::@12 to testSimpleTypes::@13 [phi:testSimpleTypes::@12->testSimpleTypes::@13] + b13_from_b12: + jmp b13 + //SEG116 testSimpleTypes::@13 + b13: + //SEG117 [39] call assertType + //SEG118 [43] phi from testSimpleTypes::@13 to assertType [phi:testSimpleTypes::@13->assertType] + assertType_from_b13: + //SEG119 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@13->assertType#0] -- register_copy + //SEG120 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG121 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@13->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG122 [40] phi from testSimpleTypes::@13 to testSimpleTypes::@14 [phi:testSimpleTypes::@13->testSimpleTypes::@14] + b14_from_b13: + jmp b14 + //SEG123 testSimpleTypes::@14 + b14: + //SEG124 [41] call assertType + //SEG125 [43] phi from testSimpleTypes::@14 to assertType [phi:testSimpleTypes::@14->assertType] + assertType_from_b14: + //SEG126 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@14->assertType#0] -- register_copy + //SEG127 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG128 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@14->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp breturn + //SEG129 testSimpleTypes::@return + breturn: + //SEG130 [42] return + rts +} +//SEG131 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(4) t2) +assertType: { + .label t2 = 4 + //SEG132 [44] if((byte) assertType::t1#15==(byte) assertType::t2#15) goto assertType::@1 -- vbuyy_eq_vbuz1_then_la1 + tya + cmp t2 + beq b1 + jmp b3 + //SEG133 assertType::@3 + b3: + //SEG134 [45] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) RED#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #RED + sta $d800,x + jmp b2 + //SEG135 assertType::@2 + b2: + //SEG136 [46] *((byte*)(word) $400 + (byte) idx#41) ← (byte) assertType::t1#15 -- pbuc1_derefidx_vbuxx=vbuyy + tya + sta $400,x + //SEG137 [47] (byte) idx#20 ← ++ (byte) idx#41 -- vbuxx=_inc_vbuxx + inx + jmp breturn + //SEG138 assertType::@return + breturn: + //SEG139 [48] return + rts + //SEG140 assertType::@1 + b1: + //SEG141 [49] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #GREEN + sta $d800,x + jmp b2 +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp b4 +Removing instruction jmp b5 +Removing instruction jmp b6 +Removing instruction jmp b7 +Removing instruction jmp b8 +Removing instruction jmp b9 +Removing instruction jmp b10 +Removing instruction jmp b11 +Removing instruction jmp b12 +Removing instruction jmp b13 +Removing instruction jmp b14 +Removing instruction jmp breturn +Removing instruction jmp b3 +Removing instruction jmp b2 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_SIGNED_BYTE with TAY +Replacing instruction ldy #TYPEID_SIGNED_BYTE with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing label b1_from_b1 with b1 +Replacing label b1_from_b1 with b1 +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_b1: +Removing instruction b2_from_b1: +Removing instruction testSimpleTypes_from_b2: +Removing instruction b1_from_testSimpleTypes: +Removing instruction assertType_from_b1: +Removing instruction b2_from_b1: +Removing instruction assertType_from_b2: +Removing instruction b3_from_b2: +Removing instruction assertType_from_b3: +Removing instruction b4_from_b3: +Removing instruction assertType_from_b4: +Removing instruction b5_from_b4: +Removing instruction assertType_from_b5: +Removing instruction b6_from_b5: +Removing instruction assertType_from_b6: +Removing instruction b7_from_b6: +Removing instruction assertType_from_b7: +Removing instruction b8_from_b7: +Removing instruction assertType_from_b8: +Removing instruction b9_from_b8: +Removing instruction assertType_from_b9: +Removing instruction b10_from_b9: +Removing instruction assertType_from_b10: +Removing instruction b11_from_b10: +Removing instruction assertType_from_b11: +Removing instruction b12_from_b11: +Removing instruction assertType_from_b12: +Removing instruction b13_from_b12: +Removing instruction assertType_from_b13: +Removing instruction b14_from_b13: +Removing instruction assertType_from_b14: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction b1_from_main: +Removing instruction b2: +Removing instruction breturn: +Removing instruction assertType_from_testSimpleTypes: +Removing instruction b1: +Removing instruction b2: +Removing instruction b3: +Removing instruction b4: +Removing instruction b5: +Removing instruction b6: +Removing instruction b7: +Removing instruction b8: +Removing instruction b9: +Removing instruction b10: +Removing instruction b11: +Removing instruction b12: +Removing instruction b13: +Removing instruction b14: +Removing instruction breturn: +Removing instruction b3: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction jmp b1 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) COLS +(byte) GREEN +(const byte) GREEN#0 GREEN = (byte) 5 +(byte) RED +(const byte) RED#0 RED = (byte) 2 +(byte*) SCREEN +(const byte) TYPEID_BYTE TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#15 reg byte y 1.0 +(byte) assertType::t2 +(byte) assertType::t2#15 t2 zp ZP_BYTE:4 2.0 +(byte) idx +(byte) idx#20 reg byte x 0.9999999999999999 +(byte) idx#41 reg byte x 7.200000000000002 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte*) main::s +(byte*) main::s#1 s zp ZP_WORD:2 16.5 +(byte*) main::s#2 s zp ZP_WORD:2 16.5 +(void()) testSimpleTypes() +(label) testSimpleTypes::@1 +(label) testSimpleTypes::@10 +(label) testSimpleTypes::@11 +(label) testSimpleTypes::@12 +(label) testSimpleTypes::@13 +(label) testSimpleTypes::@14 +(label) testSimpleTypes::@2 +(label) testSimpleTypes::@3 +(label) testSimpleTypes::@4 +(label) testSimpleTypes::@5 +(label) testSimpleTypes::@6 +(label) testSimpleTypes::@7 +(label) testSimpleTypes::@8 +(label) testSimpleTypes::@9 +(label) testSimpleTypes::@return + +zp ZP_WORD:2 [ main::s#2 main::s#1 ] +reg byte y [ assertType::t1#15 ] +zp ZP_BYTE:4 [ assertType::t2#15 ] +reg byte x [ idx#41 idx#20 ] + + +FINAL ASSEMBLER +Score: 784 + +//SEG0 File Comments +// Tests different integer literal types +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_BYTE = 1 + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_WORD = 3 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_DWORD = 5 + .const TYPEID_SIGNED_DWORD = 6 + .const RED = 2 + .const GREEN = 5 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + .label s = 2 + //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] + //SEG12 [5] phi (byte*) main::s#2 = (byte*)(word) $400 [phi:main->main::@1#0] -- pbuz1=pbuc1 + lda #<$400 + sta s + lda #>$400 + sta s+1 + //SEG13 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + //SEG14 [5] phi (byte*) main::s#2 = (byte*) main::s#1 [phi:main::@1->main::@1#0] -- register_copy + //SEG15 main::@1 + b1: + //SEG16 [6] *((byte*) main::s#2) ← (byte) ' ' -- _deref_pbuz1=vbuc1 + lda #' ' + ldy #0 + sta (s),y + //SEG17 [7] (byte*) main::s#1 ← ++ (byte*) main::s#2 -- pbuz1=_inc_pbuz1 + inc s + bne !+ + inc s+1 + !: + //SEG18 [8] if((byte*) main::s#1<(byte*)(word) $400+(word) $3e8) goto main::@1 -- pbuz1_lt_pbuc1_then_la1 + lda s+1 + cmp #>$400+$3e8 + bcc b1 + bne !+ + lda s + cmp #<$400+$3e8 + bcc b1 + !: + //SEG19 [9] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG20 main::@2 + //SEG21 [10] call testSimpleTypes + //SEG22 [12] phi from main::@2 to testSimpleTypes [phi:main::@2->testSimpleTypes] + jsr testSimpleTypes + //SEG23 main::@return + //SEG24 [11] return + rts +} +//SEG25 testSimpleTypes +testSimpleTypes: { + //SEG26 [13] call assertType + //SEG27 [43] phi from testSimpleTypes to assertType [phi:testSimpleTypes->assertType] + //SEG28 [43] phi (byte) idx#41 = (byte) 0 [phi:testSimpleTypes->assertType#0] -- vbuxx=vbuc1 + ldx #0 + //SEG29 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG30 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG31 [14] phi from testSimpleTypes to testSimpleTypes::@1 [phi:testSimpleTypes->testSimpleTypes::@1] + //SEG32 testSimpleTypes::@1 + //SEG33 [15] call assertType + //SEG34 [43] phi from testSimpleTypes::@1 to assertType [phi:testSimpleTypes::@1->assertType] + //SEG35 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@1->assertType#0] -- register_copy + //SEG36 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG37 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_BYTE [phi:testSimpleTypes::@1->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG38 [16] phi from testSimpleTypes::@1 to testSimpleTypes::@2 [phi:testSimpleTypes::@1->testSimpleTypes::@2] + //SEG39 testSimpleTypes::@2 + //SEG40 [17] call assertType + //SEG41 [43] phi from testSimpleTypes::@2 to assertType [phi:testSimpleTypes::@2->assertType] + //SEG42 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@2->assertType#0] -- register_copy + //SEG43 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG44 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@2->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG45 [18] phi from testSimpleTypes::@2 to testSimpleTypes::@3 [phi:testSimpleTypes::@2->testSimpleTypes::@3] + //SEG46 testSimpleTypes::@3 + //SEG47 [19] call assertType + //SEG48 [43] phi from testSimpleTypes::@3 to assertType [phi:testSimpleTypes::@3->assertType] + //SEG49 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@3->assertType#0] -- register_copy + //SEG50 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG51 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_BYTE [phi:testSimpleTypes::@3->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG52 [20] phi from testSimpleTypes::@3 to testSimpleTypes::@4 [phi:testSimpleTypes::@3->testSimpleTypes::@4] + //SEG53 testSimpleTypes::@4 + //SEG54 [21] call assertType + //SEG55 [43] phi from testSimpleTypes::@4 to assertType [phi:testSimpleTypes::@4->assertType] + //SEG56 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@4->assertType#0] -- register_copy + //SEG57 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG58 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@4->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG59 [22] phi from testSimpleTypes::@4 to testSimpleTypes::@5 [phi:testSimpleTypes::@4->testSimpleTypes::@5] + //SEG60 testSimpleTypes::@5 + //SEG61 [23] call assertType + //SEG62 [43] phi from testSimpleTypes::@5 to assertType [phi:testSimpleTypes::@5->assertType] + //SEG63 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@5->assertType#0] -- register_copy + //SEG64 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG65 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@5->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG66 [24] phi from testSimpleTypes::@5 to testSimpleTypes::@6 [phi:testSimpleTypes::@5->testSimpleTypes::@6] + //SEG67 testSimpleTypes::@6 + //SEG68 [25] call assertType + //SEG69 [43] phi from testSimpleTypes::@6 to assertType [phi:testSimpleTypes::@6->assertType] + //SEG70 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@6->assertType#0] -- register_copy + //SEG71 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG72 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_WORD [phi:testSimpleTypes::@6->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG73 [26] phi from testSimpleTypes::@6 to testSimpleTypes::@7 [phi:testSimpleTypes::@6->testSimpleTypes::@7] + //SEG74 testSimpleTypes::@7 + //SEG75 [27] call assertType + //SEG76 [43] phi from testSimpleTypes::@7 to assertType [phi:testSimpleTypes::@7->assertType] + //SEG77 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@7->assertType#0] -- register_copy + //SEG78 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG79 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@7->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG80 [28] phi from testSimpleTypes::@7 to testSimpleTypes::@8 [phi:testSimpleTypes::@7->testSimpleTypes::@8] + //SEG81 testSimpleTypes::@8 + //SEG82 [29] call assertType + //SEG83 [43] phi from testSimpleTypes::@8 to assertType [phi:testSimpleTypes::@8->assertType] + //SEG84 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@8->assertType#0] -- register_copy + //SEG85 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG86 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@8->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG87 [30] phi from testSimpleTypes::@8 to testSimpleTypes::@9 [phi:testSimpleTypes::@8->testSimpleTypes::@9] + //SEG88 testSimpleTypes::@9 + //SEG89 [31] call assertType + //SEG90 [43] phi from testSimpleTypes::@9 to assertType [phi:testSimpleTypes::@9->assertType] + //SEG91 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@9->assertType#0] -- register_copy + //SEG92 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG93 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_WORD [phi:testSimpleTypes::@9->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG94 [32] phi from testSimpleTypes::@9 to testSimpleTypes::@10 [phi:testSimpleTypes::@9->testSimpleTypes::@10] + //SEG95 testSimpleTypes::@10 + //SEG96 [33] call assertType + //SEG97 [43] phi from testSimpleTypes::@10 to assertType [phi:testSimpleTypes::@10->assertType] + //SEG98 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@10->assertType#0] -- register_copy + //SEG99 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG100 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@10->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG101 [34] phi from testSimpleTypes::@10 to testSimpleTypes::@11 [phi:testSimpleTypes::@10->testSimpleTypes::@11] + //SEG102 testSimpleTypes::@11 + //SEG103 [35] call assertType + //SEG104 [43] phi from testSimpleTypes::@11 to assertType [phi:testSimpleTypes::@11->assertType] + //SEG105 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@11->assertType#0] -- register_copy + //SEG106 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG107 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_DWORD [phi:testSimpleTypes::@11->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG108 [36] phi from testSimpleTypes::@11 to testSimpleTypes::@12 [phi:testSimpleTypes::@11->testSimpleTypes::@12] + //SEG109 testSimpleTypes::@12 + //SEG110 [37] call assertType + //SEG111 [43] phi from testSimpleTypes::@12 to assertType [phi:testSimpleTypes::@12->assertType] + //SEG112 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@12->assertType#0] -- register_copy + //SEG113 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG114 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@12->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG115 [38] phi from testSimpleTypes::@12 to testSimpleTypes::@13 [phi:testSimpleTypes::@12->testSimpleTypes::@13] + //SEG116 testSimpleTypes::@13 + //SEG117 [39] call assertType + //SEG118 [43] phi from testSimpleTypes::@13 to assertType [phi:testSimpleTypes::@13->assertType] + //SEG119 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@13->assertType#0] -- register_copy + //SEG120 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG121 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@13->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG122 [40] phi from testSimpleTypes::@13 to testSimpleTypes::@14 [phi:testSimpleTypes::@13->testSimpleTypes::@14] + //SEG123 testSimpleTypes::@14 + //SEG124 [41] call assertType + //SEG125 [43] phi from testSimpleTypes::@14 to assertType [phi:testSimpleTypes::@14->assertType] + //SEG126 [43] phi (byte) idx#41 = (byte) idx#20 [phi:testSimpleTypes::@14->assertType#0] -- register_copy + //SEG127 [43] phi (byte) assertType::t2#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG128 [43] phi (byte) assertType::t1#15 = (const byte) TYPEID_SIGNED_DWORD [phi:testSimpleTypes::@14->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG129 testSimpleTypes::@return + //SEG130 [42] return + rts +} +//SEG131 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(4) t2) +assertType: { + .label t2 = 4 + //SEG132 [44] if((byte) assertType::t1#15==(byte) assertType::t2#15) goto assertType::@1 -- vbuyy_eq_vbuz1_then_la1 + tya + cmp t2 + beq b1 + //SEG133 assertType::@3 + //SEG134 [45] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) RED#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #RED + sta $d800,x + //SEG135 assertType::@2 + b2: + //SEG136 [46] *((byte*)(word) $400 + (byte) idx#41) ← (byte) assertType::t1#15 -- pbuc1_derefidx_vbuxx=vbuyy + tya + sta $400,x + //SEG137 [47] (byte) idx#20 ← ++ (byte) idx#41 -- vbuxx=_inc_vbuxx + inx + //SEG138 assertType::@return + //SEG139 [48] return + rts + //SEG140 assertType::@1 + b1: + //SEG141 [49] *((byte*)(word) $d800 + (byte) idx#41) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #GREEN + sta $d800,x + jmp b2 +} + diff --git a/src/test/ref/int-literals.sym b/src/test/ref/int-literals.sym new file mode 100644 index 000000000..ea8cfda80 --- /dev/null +++ b/src/test/ref/int-literals.sym @@ -0,0 +1,55 @@ +(label) @1 +(label) @begin +(label) @end +(byte*) COLS +(byte) GREEN +(const byte) GREEN#0 GREEN = (byte) 5 +(byte) RED +(const byte) RED#0 RED = (byte) 2 +(byte*) SCREEN +(const byte) TYPEID_BYTE TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#15 reg byte y 1.0 +(byte) assertType::t2 +(byte) assertType::t2#15 t2 zp ZP_BYTE:4 2.0 +(byte) idx +(byte) idx#20 reg byte x 0.9999999999999999 +(byte) idx#41 reg byte x 7.200000000000002 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte*) main::s +(byte*) main::s#1 s zp ZP_WORD:2 16.5 +(byte*) main::s#2 s zp ZP_WORD:2 16.5 +(void()) testSimpleTypes() +(label) testSimpleTypes::@1 +(label) testSimpleTypes::@10 +(label) testSimpleTypes::@11 +(label) testSimpleTypes::@12 +(label) testSimpleTypes::@13 +(label) testSimpleTypes::@14 +(label) testSimpleTypes::@2 +(label) testSimpleTypes::@3 +(label) testSimpleTypes::@4 +(label) testSimpleTypes::@5 +(label) testSimpleTypes::@6 +(label) testSimpleTypes::@7 +(label) testSimpleTypes::@8 +(label) testSimpleTypes::@9 +(label) testSimpleTypes::@return + +zp ZP_WORD:2 [ main::s#2 main::s#1 ] +reg byte y [ assertType::t1#15 ] +zp ZP_BYTE:4 [ assertType::t2#15 ] +reg byte x [ idx#41 idx#20 ] diff --git a/src/test/ref/keyboard-glitch.asm b/src/test/ref/keyboard-glitch.asm index e557715bc..e9466358d 100644 --- a/src/test/ref/keyboard-glitch.asm +++ b/src/test/ref/keyboard-glitch.asm @@ -95,7 +95,9 @@ pressed: { ldx #KEY_SPACE jsr keyboard_key_pressed cmp #0 - beq b1 + bne breturn + jmp b1 + breturn: rts } // Keyboard row bitmask as expected by CIA#1 Port A when reading a specific keyboard matrix row (rows are numbered 0-7) diff --git a/src/test/ref/line-anim.asm b/src/test/ref/line-anim.asm index 7f9b1338f..862d9a41b 100644 --- a/src/test/ref/line-anim.asm +++ b/src/test/ref/line-anim.asm @@ -80,6 +80,7 @@ bitmap_plot: { .label _1 = 7 .label x = 3 .label plotter = 5 + .label plotter_1 = 7 .label _3 = 5 lda bitmap_plot_yhi,x sta _3+1 @@ -91,24 +92,26 @@ bitmap_plot: { lda x+1 and #>$fff8 sta _1+1 - lda plotter + lda plotter_1 clc - adc _1 - sta plotter - lda plotter+1 - adc _1+1 - sta plotter+1 + adc plotter + sta plotter_1 + lda plotter_1+1 + adc plotter+1 + sta plotter_1+1 lda x tay lda bitmap_plot_bit,y ldy #0 - ora (plotter),y - sta (plotter),y + ora (plotter_1),y + sta (plotter_1),y rts } // Initialize the points to be animated // point_init(byte zeropage(2) point_idx) point_init: { + .label _0 = 9 + .label _1 = 3 .label _3 = 7 .label _4 = 3 .label _9 = 3 @@ -120,20 +123,25 @@ point_init: { .label abs16s1_return = 3 .label abs16s2__2 = 5 .label abs16s2_return = 5 - .label x_stepf = 5 + .label x_stepf = 3 .label x_diff = 9 lda point_idx asl tax - lda point_idx - asl - tay - sec lda x_end,x - sbc x_start,y - sta x_diff + sta _0 lda x_end+1,x - sbc x_start+1,y + sta _0+1 + lda x_start,x + sta _1 + lda x_start+1,x + sta _1+1 + lda x_diff + sec + sbc _1 + sta x_diff + lda x_diff+1 + sbc _1+1 sta x_diff+1 ldy point_idx lda y_end,y @@ -180,10 +188,10 @@ point_init: { b2: lda point_idx asl - tay - lda x_start,y + tax + lda x_start,x sta _9 - lda x_start+1,y + lda x_start+1,x sta _9+1 asl _9 rol _9+1 @@ -193,13 +201,10 @@ point_init: { rol _9+1 asl _9 rol _9+1 - lda point_idx - asl - tay lda _9 - sta x_cur,y + sta x_cur,x lda _9+1 - sta x_cur+1,y + sta x_cur+1,x ldy point_idx lda y_start,y sta _10 @@ -213,15 +218,11 @@ point_init: { rol _11+1 asl _11 rol _11+1 - tya - asl - tay lda _11 - sta y_cur,y + sta y_cur,x lda _11+1 - sta y_cur+1,y + sta y_cur+1,x lda #DELAY - ldy point_idx sta delay,y rts b1: @@ -229,8 +230,8 @@ point_init: { lda x_diff+1 bmi b4 // x add = 1.0 - ldy point_idx lda #$10 + ldy point_idx sta x_add,y b5: jsr divr16s @@ -278,23 +279,18 @@ point_init: { // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 // divr16s(signed word zeropage(9) divisor, signed word zeropage(7) rem) divr16s: { - .const dividend = 0 .label _10 = 7 .label _13 = 9 - .label resultu = 5 - .label return = 5 + .label _18 = 3 + .label remu = 7 + .label divisoru = 9 + .label resultu = 3 + .label return = 3 .label divisor = 9 .label rem = 7 - .label dividendu = 3 - .label divisoru = 9 - .label remu = 7 lda rem+1 bmi b1 - lda #dividend - sta dividendu - lda #0 - sta dividendu+1 - tay + ldy #0 b2: lda divisor+1 bmi b3 @@ -337,10 +333,6 @@ divr16s: { eor #$ff adc #0 sta _10+1 - lda #-dividend - sta dividendu - lda #0 - sta dividendu+1 ldy #1 jmp b2 } @@ -348,17 +340,19 @@ divr16s: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zeropage(3) dividend, word zeropage(9) divisor, word zeropage(7) rem) +// divr16u(word zeropage(5) dividend, word zeropage(9) divisor, word zeropage(7) rem) divr16u: { .label rem = 7 - .label dividend = 3 - .label quotient = 5 - .label return = 5 + .label dividend = 5 + .label quotient = 3 + .label return = 3 .label divisor = 9 ldx #0 txa sta quotient sta quotient+1 + sta dividend + sta dividend+1 b1: asl rem rol rem+1 @@ -461,7 +455,7 @@ bitmap_clear: { rts } bitmap_init: { - .label _3 = 2 + .label _7 = 2 .label yoffs = 3 ldx #0 lda #$80 @@ -482,15 +476,14 @@ bitmap_init: { ldx #0 b3: lda #7 - sax _3 + sax _7 lda yoffs - ora _3 + ora _7 sta bitmap_plot_ylo,x lda yoffs+1 sta bitmap_plot_yhi,x - txa - and #7 - cmp #7 + lda #7 + cmp _7 bne b4 clc lda yoffs diff --git a/src/test/ref/literals.asm b/src/test/ref/literals.asm index 3ad59a6a7..31f1584a0 100644 --- a/src/test/ref/literals.asm +++ b/src/test/ref/literals.asm @@ -20,5 +20,5 @@ main: { bne b1 rts } + str: .text "bcde@" nums: .byte 2, 3, 4, 5 - str: .text "bc"+"d"+'e' diff --git a/src/test/ref/loop-break-continue.asm b/src/test/ref/loop-break-continue.asm index 1ff20050e..66faad93f 100644 --- a/src/test/ref/loop-break-continue.asm +++ b/src/test/ref/loop-break-continue.asm @@ -14,17 +14,12 @@ main: { lda str,x cmp #'@' bne b2 + breturn: rts b2: lda str,x cmp #' ' - bne b3 - b4: - inx - cpx #0 - bne b1 - rts - b3: + beq b4 lda str,x ldy #0 sta (screen),y @@ -32,6 +27,10 @@ main: { bne !+ inc screen+1 !: - jmp b4 + b4: + inx + cpx #0 + beq breturn + jmp b1 str: .text "hello brave new world@" } diff --git a/src/test/ref/loop-break-nested.asm b/src/test/ref/loop-break-nested.asm index 86284b28d..9de10c039 100644 --- a/src/test/ref/loop-break-nested.asm +++ b/src/test/ref/loop-break-nested.asm @@ -12,14 +12,20 @@ main: { ldy #0 lda (line),y cmp #'a' - bne b5 + bne b3 + breturn: rts - b5: + b3: ldy #0 b2: lda (line),y cmp #'a' - bne b3 + beq b4 + lda #'a' + sta (line),y + iny + cpy #$28 + bne b2 b4: lda #$28 clc @@ -30,18 +36,11 @@ main: { !: lda line+1 cmp #>$400+$28*$19 - bcc b1 - bne !+ + bcc !+ + bne breturn lda line cmp #<$400+$28*$19 - bcc b1 + bcs breturn !: - rts - b3: - lda #'a' - sta (line),y - iny - cpy #$28 - bne b2 - jmp b4 + jmp b1 } diff --git a/src/test/ref/loop-break.asm b/src/test/ref/loop-break.asm index e1e305c19..9be966560 100644 --- a/src/test/ref/loop-break.asm +++ b/src/test/ref/loop-break.asm @@ -8,13 +8,12 @@ main: { b1: lda SCREEN,x cmp #'a' - bne b2 - rts - b2: + beq breturn lda #'a' sta SCREEN,x inx cpx #$28*6+1 bne b1 + breturn: rts } diff --git a/src/test/ref/loop-continue.asm b/src/test/ref/loop-continue.asm index c5abdab71..bd86c60aa 100644 --- a/src/test/ref/loop-continue.asm +++ b/src/test/ref/loop-continue.asm @@ -8,13 +8,11 @@ main: { b1: lda SCREEN,x cmp #' ' - bne b2 + beq b3 + inc SCREEN,x b3: inx cpx #$28*6+1 bne b1 rts - b2: - inc SCREEN,x - jmp b3 } diff --git a/src/test/ref/loop-while-continue.asm b/src/test/ref/loop-while-continue.asm index 1424862f5..8529f855a 100644 --- a/src/test/ref/loop-while-continue.asm +++ b/src/test/ref/loop-while-continue.asm @@ -13,9 +13,7 @@ main: { b2: lda SCREEN,x cmp #' ' - bne b3 - jmp b1 - b3: + beq b1 inc SCREEN,x jmp b1 } diff --git a/src/test/ref/memory-heap.asm b/src/test/ref/memory-heap.asm new file mode 100644 index 000000000..c07e8c978 --- /dev/null +++ b/src/test/ref/memory-heap.asm @@ -0,0 +1,65 @@ +// Experiments with malloc() +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Start of the heap used by malloc() + .label HEAP_START = $c000 + .label heap_head = 2 +main: { + .label screen = $400 + .label buf1 = 4 + .label buf2 = 6 + lda #HEAP_START + sta heap_head+1 + jsr malloc + lda malloc.return + sta malloc.return_2 + lda malloc.return+1 + sta malloc.return_2+1 + jsr malloc + ldy #0 + b1: + tya + sta (buf1),y + tya + eor #$ff + clc + adc #$ff+1 + sta (buf2),y + iny + cpy #$64 + bne b1 + jsr free + jsr free + ldy #0 + lda (buf1),y + sta screen + lda (buf2),y + sta screen+1 + rts +} +// A block of memory previously allocated by a call to malloc is deallocated, making it available again for further allocations. +// If ptr is a null pointer, the function does nothing. +free: { + rts +} +// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. +// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values. +malloc: { + .label return = 6 + .label return_2 = 4 + lda heap_head + sta return + lda heap_head+1 + sta return+1 + lda #$64 + clc + adc heap_head + sta heap_head + bcc !+ + inc heap_head+1 + !: + rts +} diff --git a/src/test/ref/mixed-array-0.asm b/src/test/ref/mixed-array-0.asm new file mode 100644 index 000000000..3e2175924 --- /dev/null +++ b/src/test/ref/mixed-array-0.asm @@ -0,0 +1,15 @@ +// Test an array with mixed byte/number types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + lda msg + sta SCREEN + lda msg+1 + sta SCREEN+1 + lda msg+2 + sta SCREEN+2 + rts + msg: .byte 1, 2, 3 +} diff --git a/src/test/ref/mixed-array-1.asm b/src/test/ref/mixed-array-1.asm new file mode 100644 index 000000000..2d92feb78 --- /dev/null +++ b/src/test/ref/mixed-array-1.asm @@ -0,0 +1,15 @@ +// Test an array with mixed byte/number types +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + lda msg + sta SCREEN + lda msg+1 + sta SCREEN+1 + lda msg+2 + sta SCREEN+2 + rts + msg: .byte -1, 0, 1 +} diff --git a/src/test/ref/mul8u-min.asm b/src/test/ref/mul8u-min.asm new file mode 100644 index 000000000..88d7cb90b --- /dev/null +++ b/src/test/ref/mul8u-min.asm @@ -0,0 +1,70 @@ +// Minimal test of mul8u +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label _0 = 4 + .label i = 3 + .label a = 2 + lda #0 + sta i + sta a + b1: + ldy #0 + b2: + ldx a + tya + jsr mul8u + lda i + asl + tax + lda _0 + sta screen,x + lda _0+1 + sta screen+1,x + inc i + iny + cpy #6 + bne b2 + inc a + lda #6 + cmp a + bne b1 + rts +} +// Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word +// mul8u(byte register(X) a, byte register(A) b) +mul8u: { + .label mb = 6 + .label res = 4 + .label return = 4 + sta mb + lda #0 + sta mb+1 + sta res + sta res+1 + b1: + cpx #0 + bne b2 + rts + b2: + txa + and #1 + cmp #0 + beq b3 + lda res + clc + adc mb + sta res + lda res+1 + adc mb+1 + sta res+1 + b3: + txa + lsr + tax + asl mb + rol mb+1 + jmp b1 +} diff --git a/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm b/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm index b3658492e..64cf59ca2 100644 --- a/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm +++ b/src/test/ref/multiplexer-irq/simple-multiplexer-irq.asm @@ -129,7 +129,11 @@ plexSort: { sta PLEX_SORTED_IDX+1,x dex cpx #$ff - bne b6 + beq b4 + lda nxt_y + ldy PLEX_SORTED_IDX,x + cmp PLEX_YPOS,y + bcc b3 b4: inx lda nxt_idx @@ -154,12 +158,6 @@ plexSort: { bne plexFreePrepare1_b1 sta plex_free_next rts - b6: - lda nxt_y - ldy PLEX_SORTED_IDX,x - cmp PLEX_YPOS,y - bcc b3 - jmp b4 } // Initialize the program init: { @@ -173,7 +171,7 @@ init: { sta xp+1 tax b1: - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta PLEX_PTR,x txa asl @@ -241,7 +239,9 @@ plex_irq: { sta _4 lda plex_show_idx cmp #PLEX_COUNT - bcc b7 + bcs b4 + cpx _4 + bcc b3 b4: lda #IRQ_RASTER sta IRQ_STATUS @@ -257,10 +257,6 @@ plex_irq: { b1: stx RASTER jmp b2 - b7: - cpx _4 - bcc b3 - jmp b4 } // Show the next sprite. // plexSort() prepares showing the sprites @@ -290,17 +286,13 @@ plexShowSprite: { ldx plex_sprite_idx sta PLEX_SCREEN_PTR,x ldy plex_show_idx - ldx PLEX_SORTED_IDX,y - txa + lda PLEX_SORTED_IDX,y asl - tay - lda PLEX_XPOS,y + tax + lda PLEX_XPOS,x ldy plex_sprite_idx2 sta SPRITES_XPOS,y - txa - asl - tay - lda PLEX_XPOS+1,y + lda PLEX_XPOS+1,x cmp #0 bne b1 lda #$ff diff --git a/src/test/ref/no-recursion-heavy.asm b/src/test/ref/no-recursion-heavy.asm index 9b94f1c33..ec7449e53 100644 --- a/src/test/ref/no-recursion-heavy.asm +++ b/src/test/ref/no-recursion-heavy.asm @@ -5,6 +5,7 @@ .label bb = 3 .label bb_27 = 4 .label bc = 5 + .label bb_100 = 4 .label bb_101 = 4 .label bb_102 = 4 .label bb_103 = 4 @@ -13,7 +14,6 @@ .label bb_106 = 4 .label bb_107 = 4 .label bb_108 = 4 - .label bb_109 = 4 main: { lda #0 sta ba @@ -31,7 +31,7 @@ f0: { bne b1 inc bb lda bb - sta bb_101 + sta bb_100 jsr fa b1: lda #1 @@ -39,7 +39,7 @@ f0: { bne b2 inc bb lda bb - sta bb_102 + sta bb_101 jsr fa b2: lda #2 @@ -47,7 +47,7 @@ f0: { bne b3 inc bb lda bb - sta bb_103 + sta bb_102 jsr fa b3: lda #3 @@ -55,7 +55,7 @@ f0: { bne b4 inc bb lda bb - sta bb_104 + sta bb_103 jsr fa b4: lda #4 @@ -63,7 +63,7 @@ f0: { bne b5 inc bb lda bb - sta bb_105 + sta bb_104 jsr fa b5: lda #5 @@ -71,7 +71,7 @@ f0: { bne b6 inc bb lda bb - sta bb_106 + sta bb_105 jsr fa b6: lda #6 @@ -79,7 +79,7 @@ f0: { bne b7 inc bb lda bb - sta bb_107 + sta bb_106 jsr fa b7: lda #7 @@ -87,7 +87,7 @@ f0: { bne b8 inc bb lda bb - sta bb_108 + sta bb_107 jsr fa b8: lda #8 @@ -95,7 +95,7 @@ f0: { bne b9 inc bb lda bb - sta bb_109 + sta bb_108 jsr fa b9: lda #9 diff --git a/src/test/ref/noop-cast-elimination.asm b/src/test/ref/noop-cast-elimination.asm new file mode 100644 index 000000000..d8ab9747e --- /dev/null +++ b/src/test/ref/noop-cast-elimination.asm @@ -0,0 +1,39 @@ +// Test elimination of noop-casts (signed byte to byte) +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label sw = 2 + lda #<$1234 + sta sw + lda #>$1234 + sta sw+1 + ldx #0 + b1: + txa + sta $fe + ora #$7f + bmi !+ + lda #0 + !: + sta $ff + clc + lda sw + adc $fe + sta sw + lda sw+1 + adc $ff + sta sw+1 + txa + asl + tay + lda sw + sta screen,y + lda sw+1 + sta screen+1,y + inx + cpx #$b + bne b1 + rts +} diff --git a/src/test/ref/number-conversion.asm b/src/test/ref/number-conversion.asm new file mode 100644 index 000000000..412553a64 --- /dev/null +++ b/src/test/ref/number-conversion.asm @@ -0,0 +1,182 @@ +// Tests conversion of numbers to correct int types +// See https://gitlab.com/camelot/kickc/issues/181 +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_SIGNED_DWORD = 6 + .const TYPEID_BYTE = 1 + .const TYPEID_WORD = 3 + .const TYPEID_DWORD = 5 + .const RED = 2 + .const GREEN = 5 + .label SCREEN = $400 + .label COLS = $d800 +main: { + ldx #0 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + tay + jsr assertType + ldx #$28 + lda #TYPEID_BYTE + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_BYTE + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + ldx #$50 + lda #TYPEID_BYTE + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_BYTE + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_BYTE + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_WORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + tay + jsr assertType + lda #TYPEID_DWORD + sta assertType.t2 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + rts +} +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(2) t2) +assertType: { + .label t2 = 2 + tya + cmp t2 + beq b1 + lda #RED + sta COLS,x + b2: + tya + sta SCREEN,x + inx + rts + b1: + lda #GREEN + sta COLS,x + jmp b2 +} diff --git a/src/test/ref/number-conversion.cfg b/src/test/ref/number-conversion.cfg new file mode 100644 index 000000000..746b50917 --- /dev/null +++ b/src/test/ref/number-conversion.cfg @@ -0,0 +1,171 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call assertType + to:main::@1 +main::@1: scope:[main] from main + [6] phi() + [7] call assertType + to:main::@2 +main::@2: scope:[main] from main::@1 + [8] phi() + [9] call assertType + to:main::@3 +main::@3: scope:[main] from main::@2 + [10] phi() + [11] call assertType + to:main::@4 +main::@4: scope:[main] from main::@3 + [12] phi() + [13] call assertType + to:main::@5 +main::@5: scope:[main] from main::@4 + [14] phi() + [15] call assertType + to:main::@6 +main::@6: scope:[main] from main::@5 + [16] phi() + [17] call assertType + to:main::@7 +main::@7: scope:[main] from main::@6 + [18] phi() + [19] call assertType + to:main::@8 +main::@8: scope:[main] from main::@7 + [20] phi() + [21] call assertType + to:main::@9 +main::@9: scope:[main] from main::@8 + [22] phi() + [23] call assertType + to:main::@10 +main::@10: scope:[main] from main::@9 + [24] phi() + [25] call assertType + to:main::@11 +main::@11: scope:[main] from main::@10 + [26] phi() + [27] call assertType + to:main::@12 +main::@12: scope:[main] from main::@11 + [28] phi() + [29] call assertType + to:main::@13 +main::@13: scope:[main] from main::@12 + [30] phi() + [31] call assertType + to:main::@14 +main::@14: scope:[main] from main::@13 + [32] phi() + [33] call assertType + to:main::@15 +main::@15: scope:[main] from main::@14 + [34] phi() + [35] call assertType + to:main::@16 +main::@16: scope:[main] from main::@15 + [36] phi() + [37] call assertType + to:main::@17 +main::@17: scope:[main] from main::@16 + [38] phi() + [39] call assertType + to:main::@18 +main::@18: scope:[main] from main::@17 + [40] phi() + [41] call assertType + to:main::@19 +main::@19: scope:[main] from main::@18 + [42] phi() + [43] call assertType + to:main::@20 +main::@20: scope:[main] from main::@19 + [44] phi() + [45] call assertType + to:main::@21 +main::@21: scope:[main] from main::@20 + [46] phi() + [47] call assertType + to:main::@22 +main::@22: scope:[main] from main::@21 + [48] phi() + [49] call assertType + to:main::@23 +main::@23: scope:[main] from main::@22 + [50] phi() + [51] call assertType + to:main::@24 +main::@24: scope:[main] from main::@23 + [52] phi() + [53] call assertType + to:main::@25 +main::@25: scope:[main] from main::@24 + [54] phi() + [55] call assertType + to:main::@26 +main::@26: scope:[main] from main::@25 + [56] phi() + [57] call assertType + to:main::@27 +main::@27: scope:[main] from main::@26 + [58] phi() + [59] call assertType + to:main::@28 +main::@28: scope:[main] from main::@27 + [60] phi() + [61] call assertType + to:main::@29 +main::@29: scope:[main] from main::@28 + [62] phi() + [63] call assertType + to:main::@30 +main::@30: scope:[main] from main::@29 + [64] phi() + [65] call assertType + to:main::@31 +main::@31: scope:[main] from main::@30 + [66] phi() + [67] call assertType + to:main::@32 +main::@32: scope:[main] from main::@31 + [68] phi() + [69] call assertType + to:main::@33 +main::@33: scope:[main] from main::@32 + [70] phi() + [71] call assertType + to:main::@34 +main::@34: scope:[main] from main::@33 + [72] phi() + [73] call assertType + to:main::@return +main::@return: scope:[main] from main::@34 + [74] return + to:@return +assertType: scope:[assertType] from main main::@1 main::@10 main::@11 main::@12 main::@13 main::@14 main::@15 main::@16 main::@17 main::@18 main::@19 main::@2 main::@20 main::@21 main::@22 main::@23 main::@24 main::@25 main::@26 main::@27 main::@28 main::@29 main::@3 main::@30 main::@31 main::@32 main::@33 main::@34 main::@4 main::@5 main::@6 main::@7 main::@8 main::@9 + [75] (byte) idx#79 ← phi( main/(byte) 0 main::@1/(byte) idx#40 main::@10/(byte) idx#40 main::@11/(byte) idx#40 main::@12/(byte) idx#40 main::@13/(byte) idx#40 main::@14/(byte) idx#40 main::@15/(byte) idx#40 main::@16/(byte) idx#40 main::@17/(byte) idx#40 main::@18/(byte) idx#40 main::@19/(byte) idx#40 main::@2/(byte) idx#40 main::@20/(byte) idx#40 main::@21/(byte) $50 main::@22/(byte) idx#40 main::@23/(byte) idx#40 main::@24/(byte) idx#40 main::@25/(byte) idx#40 main::@26/(byte) idx#40 main::@27/(byte) idx#40 main::@28/(byte) idx#40 main::@29/(byte) idx#40 main::@3/(byte) idx#40 main::@30/(byte) idx#40 main::@31/(byte) idx#40 main::@32/(byte) idx#40 main::@33/(byte) idx#40 main::@34/(byte) idx#40 main::@4/(byte) idx#40 main::@5/(byte) idx#40 main::@6/(byte) idx#40 main::@7/(byte) idx#40 main::@8/(byte) idx#40 main::@9/(byte) $28 ) + [75] (byte) assertType::t2#35 ← phi( main/(const byte) TYPEID_SIGNED_BYTE main::@1/(const byte) TYPEID_SIGNED_WORD main::@10/(const byte) TYPEID_BYTE main::@11/(const byte) TYPEID_WORD main::@12/(const byte) TYPEID_WORD main::@13/(const byte) TYPEID_DWORD main::@14/(const byte) TYPEID_WORD main::@15/(const byte) TYPEID_WORD main::@16/(const byte) TYPEID_DWORD main::@17/(const byte) TYPEID_DWORD main::@18/(const byte) TYPEID_DWORD main::@19/(const byte) TYPEID_DWORD main::@2/(const byte) TYPEID_SIGNED_DWORD main::@20/(const byte) TYPEID_DWORD main::@21/(const byte) TYPEID_BYTE main::@22/(const byte) TYPEID_BYTE main::@23/(const byte) TYPEID_BYTE main::@24/(const byte) TYPEID_WORD main::@25/(const byte) TYPEID_WORD main::@26/(const byte) TYPEID_DWORD main::@27/(const byte) TYPEID_WORD main::@28/(const byte) TYPEID_WORD main::@29/(const byte) TYPEID_WORD main::@3/(const byte) TYPEID_SIGNED_WORD main::@30/(const byte) TYPEID_DWORD main::@31/(const byte) TYPEID_DWORD main::@32/(const byte) TYPEID_DWORD main::@33/(const byte) TYPEID_DWORD main::@34/(const byte) TYPEID_DWORD main::@4/(const byte) TYPEID_SIGNED_WORD main::@5/(const byte) TYPEID_SIGNED_DWORD main::@6/(const byte) TYPEID_SIGNED_DWORD main::@7/(const byte) TYPEID_SIGNED_DWORD main::@8/(const byte) TYPEID_SIGNED_DWORD main::@9/(const byte) TYPEID_BYTE ) + [75] (byte) assertType::t1#35 ← phi( main/(const byte) TYPEID_SIGNED_BYTE main::@1/(const byte) TYPEID_SIGNED_WORD main::@10/(const byte) TYPEID_BYTE main::@11/(const byte) TYPEID_WORD main::@12/(const byte) TYPEID_WORD main::@13/(const byte) TYPEID_DWORD main::@14/(const byte) TYPEID_WORD main::@15/(const byte) TYPEID_WORD main::@16/(const byte) TYPEID_DWORD main::@17/(const byte) TYPEID_DWORD main::@18/(const byte) TYPEID_DWORD main::@19/(const byte) TYPEID_DWORD main::@2/(const byte) TYPEID_SIGNED_DWORD main::@20/(const byte) TYPEID_DWORD main::@21/(const byte) TYPEID_BYTE main::@22/(const byte) TYPEID_BYTE main::@23/(const byte) TYPEID_BYTE main::@24/(const byte) TYPEID_WORD main::@25/(const byte) TYPEID_WORD main::@26/(const byte) TYPEID_DWORD main::@27/(const byte) TYPEID_WORD main::@28/(const byte) TYPEID_WORD main::@29/(const byte) TYPEID_WORD main::@3/(const byte) TYPEID_SIGNED_WORD main::@30/(const byte) TYPEID_DWORD main::@31/(const byte) TYPEID_DWORD main::@32/(const byte) TYPEID_DWORD main::@33/(const byte) TYPEID_DWORD main::@34/(const byte) TYPEID_SIGNED_DWORD main::@4/(const byte) TYPEID_SIGNED_WORD main::@5/(const byte) TYPEID_SIGNED_DWORD main::@6/(const byte) TYPEID_SIGNED_DWORD main::@7/(const byte) TYPEID_SIGNED_DWORD main::@8/(const byte) TYPEID_SIGNED_DWORD main::@9/(const byte) TYPEID_BYTE ) + [76] if((byte) assertType::t1#35==(byte) assertType::t2#35) goto assertType::@1 + to:assertType::@3 +assertType::@3: scope:[assertType] from assertType + [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 + to:assertType::@2 +assertType::@2: scope:[assertType] from assertType::@1 assertType::@3 + [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 + [79] (byte) idx#40 ← ++ (byte) idx#79 + to:assertType::@return +assertType::@return: scope:[assertType] from assertType::@2 + [80] return + to:@return +assertType::@1: scope:[assertType] from assertType + [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 + to:assertType::@2 diff --git a/src/test/ref/number-conversion.log b/src/test/ref/number-conversion.log new file mode 100644 index 000000000..72d68592f --- /dev/null +++ b/src/test/ref/number-conversion.log @@ -0,0 +1,3609 @@ +Resolved forward reference idx to (byte) idx +Resolved forward reference idx to (byte) idx +Resolved forward reference idx to (byte) idx +Adding pointer type conversion cast (byte*) SCREEN in (byte*) SCREEN ← (word) $400 +Adding pointer type conversion cast (byte*) COLS in (byte*) COLS ← (word) $d800 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @2 + (byte) idx#0 ← (byte) 0 + (number~) main::$0 ← (signed byte) $c + (number) $c + (byte~) main::$1 ← typeid (number~) main::$0 + (byte) assertType::t1#0 ← (byte~) main::$1 + (byte) assertType::t2#0 ← (const byte) TYPEID_SIGNED_BYTE + call assertType + to:main::@1 +main::@1: scope:[main] from main + (byte) idx#43 ← phi( main/(byte) idx#41 ) + (byte) idx#1 ← (byte) idx#43 + (number~) main::$3 ← (signed byte) $c + (number) $82 + (byte~) main::$4 ← typeid (number~) main::$3 + (byte) assertType::t1#1 ← (byte~) main::$4 + (byte) assertType::t2#1 ← (const byte) TYPEID_SIGNED_WORD + call assertType + to:main::@2 +main::@2: scope:[main] from main::@1 + (byte) idx#44 ← phi( main::@1/(byte) idx#41 ) + (byte) idx#2 ← (byte) idx#44 + (number~) main::$6 ← (signed byte) $c + (number) $80e8 + (byte~) main::$7 ← typeid (number~) main::$6 + (byte) assertType::t1#2 ← (byte~) main::$7 + (byte) assertType::t2#2 ← (const byte) TYPEID_SIGNED_DWORD + call assertType + to:main::@3 +main::@3: scope:[main] from main::@2 + (byte) idx#45 ← phi( main::@2/(byte) idx#41 ) + (byte) idx#3 ← (byte) idx#45 + (number~) main::$9 ← (signed word) $c + (number) $c + (byte~) main::$10 ← typeid (number~) main::$9 + (byte) assertType::t1#3 ← (byte~) main::$10 + (byte) assertType::t2#3 ← (const byte) TYPEID_SIGNED_WORD + call assertType + to:main::@4 +main::@4: scope:[main] from main::@3 + (byte) idx#46 ← phi( main::@3/(byte) idx#41 ) + (byte) idx#4 ← (byte) idx#46 + (number~) main::$12 ← (signed word) $c + (number) $82 + (byte~) main::$13 ← typeid (number~) main::$12 + (byte) assertType::t1#4 ← (byte~) main::$13 + (byte) assertType::t2#4 ← (const byte) TYPEID_SIGNED_WORD + call assertType + to:main::@5 +main::@5: scope:[main] from main::@4 + (byte) idx#47 ← phi( main::@4/(byte) idx#41 ) + (byte) idx#5 ← (byte) idx#47 + (number~) main::$15 ← (signed word) $c + (number) $186a0 + (byte~) main::$16 ← typeid (number~) main::$15 + (byte) assertType::t1#5 ← (byte~) main::$16 + (byte) assertType::t2#5 ← (const byte) TYPEID_SIGNED_DWORD + call assertType + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) idx#48 ← phi( main::@5/(byte) idx#41 ) + (byte) idx#6 ← (byte) idx#48 + (number~) main::$18 ← (signed dword) $c + (number) $c + (byte~) main::$19 ← typeid (number~) main::$18 + (byte) assertType::t1#6 ← (byte~) main::$19 + (byte) assertType::t2#6 ← (const byte) TYPEID_SIGNED_DWORD + call assertType + to:main::@7 +main::@7: scope:[main] from main::@6 + (byte) idx#49 ← phi( main::@6/(byte) idx#41 ) + (byte) idx#7 ← (byte) idx#49 + (number~) main::$21 ← (signed dword) $c + (number) $82 + (byte~) main::$22 ← typeid (number~) main::$21 + (byte) assertType::t1#7 ← (byte~) main::$22 + (byte) assertType::t2#7 ← (const byte) TYPEID_SIGNED_DWORD + call assertType + to:main::@8 +main::@8: scope:[main] from main::@7 + (byte) idx#50 ← phi( main::@7/(byte) idx#41 ) + (byte) idx#8 ← (byte) idx#50 + (number~) main::$24 ← (signed dword) $c + (number) $186a0 + (byte~) main::$25 ← typeid (number~) main::$24 + (byte) assertType::t1#8 ← (byte~) main::$25 + (byte) assertType::t2#8 ← (const byte) TYPEID_SIGNED_DWORD + call assertType + to:main::@9 +main::@9: scope:[main] from main::@8 + (byte) idx#51 ← phi( main::@8/(byte) idx#41 ) + (byte) idx#9 ← (byte) idx#51 + (byte) idx#10 ← (byte) $28 + (number~) main::$27 ← (byte) $c + (number) $c + (byte~) main::$28 ← typeid (number~) main::$27 + (byte) assertType::t1#9 ← (byte~) main::$28 + (byte) assertType::t2#9 ← (const byte) TYPEID_BYTE + call assertType + to:main::@10 +main::@10: scope:[main] from main::@9 + (byte) idx#52 ← phi( main::@9/(byte) idx#41 ) + (byte) idx#11 ← (byte) idx#52 + (number~) main::$30 ← (byte) $c + (number) $fa + (byte~) main::$31 ← typeid (number~) main::$30 + (byte) assertType::t1#10 ← (byte~) main::$31 + (byte) assertType::t2#10 ← (const byte) TYPEID_BYTE + call assertType + to:main::@11 +main::@11: scope:[main] from main::@10 + (byte) idx#53 ← phi( main::@10/(byte) idx#41 ) + (byte) idx#12 ← (byte) idx#53 + (number~) main::$33 ← (byte) $c + (number) $12c + (byte~) main::$34 ← typeid (number~) main::$33 + (byte) assertType::t1#11 ← (byte~) main::$34 + (byte) assertType::t2#11 ← (const byte) TYPEID_WORD + call assertType + to:main::@12 +main::@12: scope:[main] from main::@11 + (byte) idx#54 ← phi( main::@11/(byte) idx#41 ) + (byte) idx#13 ← (byte) idx#54 + (number~) main::$36 ← (byte) $c + (number) $fffe + (byte~) main::$37 ← typeid (number~) main::$36 + (byte) assertType::t1#12 ← (byte~) main::$37 + (byte) assertType::t2#12 ← (const byte) TYPEID_WORD + call assertType + to:main::@13 +main::@13: scope:[main] from main::@12 + (byte) idx#55 ← phi( main::@12/(byte) idx#41 ) + (byte) idx#14 ← (byte) idx#55 + (number~) main::$39 ← (byte) $c + (number) $101d0 + (byte~) main::$40 ← typeid (number~) main::$39 + (byte) assertType::t1#13 ← (byte~) main::$40 + (byte) assertType::t2#13 ← (const byte) TYPEID_DWORD + call assertType + to:main::@14 +main::@14: scope:[main] from main::@13 + (byte) idx#56 ← phi( main::@13/(byte) idx#41 ) + (byte) idx#15 ← (byte) idx#56 + (number~) main::$42 ← (word) $c + (number) $c + (byte~) main::$43 ← typeid (number~) main::$42 + (byte) assertType::t1#14 ← (byte~) main::$43 + (byte) assertType::t2#14 ← (const byte) TYPEID_WORD + call assertType + to:main::@15 +main::@15: scope:[main] from main::@14 + (byte) idx#57 ← phi( main::@14/(byte) idx#41 ) + (byte) idx#16 ← (byte) idx#57 + (number~) main::$45 ← (word) $c + (number) $82 + (byte~) main::$46 ← typeid (number~) main::$45 + (byte) assertType::t1#15 ← (byte~) main::$46 + (byte) assertType::t2#15 ← (const byte) TYPEID_WORD + call assertType + to:main::@16 +main::@16: scope:[main] from main::@15 + (byte) idx#58 ← phi( main::@15/(byte) idx#41 ) + (byte) idx#17 ← (byte) idx#58 + (number~) main::$48 ← (word) $c + (number) $101d0 + (byte~) main::$49 ← typeid (number~) main::$48 + (byte) assertType::t1#16 ← (byte~) main::$49 + (byte) assertType::t2#16 ← (const byte) TYPEID_DWORD + call assertType + to:main::@17 +main::@17: scope:[main] from main::@16 + (byte) idx#59 ← phi( main::@16/(byte) idx#41 ) + (byte) idx#18 ← (byte) idx#59 + (number~) main::$51 ← (dword) $c + (number) $c + (byte~) main::$52 ← typeid (number~) main::$51 + (byte) assertType::t1#17 ← (byte~) main::$52 + (byte) assertType::t2#17 ← (const byte) TYPEID_DWORD + call assertType + to:main::@18 +main::@18: scope:[main] from main::@17 + (byte) idx#60 ← phi( main::@17/(byte) idx#41 ) + (byte) idx#19 ← (byte) idx#60 + (number~) main::$54 ← (dword) $c + (number) $82 + (byte~) main::$55 ← typeid (number~) main::$54 + (byte) assertType::t1#18 ← (byte~) main::$55 + (byte) assertType::t2#18 ← (const byte) TYPEID_DWORD + call assertType + to:main::@19 +main::@19: scope:[main] from main::@18 + (byte) idx#61 ← phi( main::@18/(byte) idx#41 ) + (byte) idx#20 ← (byte) idx#61 + (number~) main::$57 ← (dword) $c + (number) $101d0 + (byte~) main::$58 ← typeid (number~) main::$57 + (byte) assertType::t1#19 ← (byte~) main::$58 + (byte) assertType::t2#19 ← (const byte) TYPEID_DWORD + call assertType + to:main::@20 +main::@20: scope:[main] from main::@19 + (byte) idx#62 ← phi( main::@19/(byte) idx#41 ) + (byte) idx#21 ← (byte) idx#62 + (number~) main::$60 ← (byte) $c + (number) $b2d05e00 + (byte~) main::$61 ← typeid (number~) main::$60 + (byte) assertType::t1#20 ← (byte~) main::$61 + (byte) assertType::t2#20 ← (const byte) TYPEID_DWORD + call assertType + to:main::@21 +main::@21: scope:[main] from main::@20 + (byte) idx#63 ← phi( main::@20/(byte) idx#41 ) + (byte) idx#22 ← (byte) idx#63 + (byte) idx#23 ← (byte) $50 + (number~) main::$63 ← - (number) $c + (number~) main::$64 ← (byte) $c + (number~) main::$63 + (byte~) main::$65 ← typeid (number~) main::$64 + (byte) assertType::t1#21 ← (byte~) main::$65 + (byte) assertType::t2#21 ← (const byte) TYPEID_BYTE + call assertType + to:main::@22 +main::@22: scope:[main] from main::@21 + (byte) idx#64 ← phi( main::@21/(byte) idx#41 ) + (byte) idx#24 ← (byte) idx#64 + (number~) main::$67 ← - (number) $78 + (number~) main::$68 ← (byte) $c + (number~) main::$67 + (byte~) main::$69 ← typeid (number~) main::$68 + (byte) assertType::t1#22 ← (byte~) main::$69 + (byte) assertType::t2#22 ← (const byte) TYPEID_BYTE + call assertType + to:main::@23 +main::@23: scope:[main] from main::@22 + (byte) idx#65 ← phi( main::@22/(byte) idx#41 ) + (byte) idx#25 ← (byte) idx#65 + (number~) main::$71 ← - (number) $fa + (number~) main::$72 ← (byte) $c + (number~) main::$71 + (byte~) main::$73 ← typeid (number~) main::$72 + (byte) assertType::t1#23 ← (byte~) main::$73 + (byte) assertType::t2#23 ← (const byte) TYPEID_BYTE + call assertType + to:main::@24 +main::@24: scope:[main] from main::@23 + (byte) idx#66 ← phi( main::@23/(byte) idx#41 ) + (byte) idx#26 ← (byte) idx#66 + (number~) main::$75 ← - (number) $104 + (number~) main::$76 ← (byte) $c + (number~) main::$75 + (byte~) main::$77 ← typeid (number~) main::$76 + (byte) assertType::t1#24 ← (byte~) main::$77 + (byte) assertType::t2#24 ← (const byte) TYPEID_WORD + call assertType + to:main::@25 +main::@25: scope:[main] from main::@24 + (byte) idx#67 ← phi( main::@24/(byte) idx#41 ) + (byte) idx#27 ← (byte) idx#67 + (number~) main::$79 ← - (number) $fde8 + (number~) main::$80 ← (byte) $c + (number~) main::$79 + (byte~) main::$81 ← typeid (number~) main::$80 + (byte) assertType::t1#25 ← (byte~) main::$81 + (byte) assertType::t2#25 ← (const byte) TYPEID_WORD + call assertType + to:main::@26 +main::@26: scope:[main] from main::@25 + (byte) idx#68 ← phi( main::@25/(byte) idx#41 ) + (byte) idx#28 ← (byte) idx#68 + (number~) main::$83 ← - (number) $101d0 + (number~) main::$84 ← (byte) $c + (number~) main::$83 + (byte~) main::$85 ← typeid (number~) main::$84 + (byte) assertType::t1#26 ← (byte~) main::$85 + (byte) assertType::t2#26 ← (const byte) TYPEID_DWORD + call assertType + to:main::@27 +main::@27: scope:[main] from main::@26 + (byte) idx#69 ← phi( main::@26/(byte) idx#41 ) + (byte) idx#29 ← (byte) idx#69 + (number~) main::$87 ← - (number) $c + (number~) main::$88 ← (word) $c + (number~) main::$87 + (byte~) main::$89 ← typeid (number~) main::$88 + (byte) assertType::t1#27 ← (byte~) main::$89 + (byte) assertType::t2#27 ← (const byte) TYPEID_WORD + call assertType + to:main::@28 +main::@28: scope:[main] from main::@27 + (byte) idx#70 ← phi( main::@27/(byte) idx#41 ) + (byte) idx#30 ← (byte) idx#70 + (number~) main::$91 ← - (number) $82 + (number~) main::$92 ← (word) $c + (number~) main::$91 + (byte~) main::$93 ← typeid (number~) main::$92 + (byte) assertType::t1#28 ← (byte~) main::$93 + (byte) assertType::t2#28 ← (const byte) TYPEID_WORD + call assertType + to:main::@29 +main::@29: scope:[main] from main::@28 + (byte) idx#71 ← phi( main::@28/(byte) idx#41 ) + (byte) idx#31 ← (byte) idx#71 + (number~) main::$95 ← - (number) $fde8 + (number~) main::$96 ← (word) $c + (number~) main::$95 + (byte~) main::$97 ← typeid (number~) main::$96 + (byte) assertType::t1#29 ← (byte~) main::$97 + (byte) assertType::t2#29 ← (const byte) TYPEID_WORD + call assertType + to:main::@30 +main::@30: scope:[main] from main::@29 + (byte) idx#72 ← phi( main::@29/(byte) idx#41 ) + (byte) idx#32 ← (byte) idx#72 + (number~) main::$99 ← - (number) $101d0 + (number~) main::$100 ← (word) $c + (number~) main::$99 + (byte~) main::$101 ← typeid (number~) main::$100 + (byte) assertType::t1#30 ← (byte~) main::$101 + (byte) assertType::t2#30 ← (const byte) TYPEID_DWORD + call assertType + to:main::@31 +main::@31: scope:[main] from main::@30 + (byte) idx#73 ← phi( main::@30/(byte) idx#41 ) + (byte) idx#33 ← (byte) idx#73 + (number~) main::$103 ← - (number) $c + (number~) main::$104 ← (dword) $c + (number~) main::$103 + (byte~) main::$105 ← typeid (number~) main::$104 + (byte) assertType::t1#31 ← (byte~) main::$105 + (byte) assertType::t2#31 ← (const byte) TYPEID_DWORD + call assertType + to:main::@32 +main::@32: scope:[main] from main::@31 + (byte) idx#74 ← phi( main::@31/(byte) idx#41 ) + (byte) idx#34 ← (byte) idx#74 + (number~) main::$107 ← - (number) $82 + (number~) main::$108 ← (dword) $c + (number~) main::$107 + (byte~) main::$109 ← typeid (number~) main::$108 + (byte) assertType::t1#32 ← (byte~) main::$109 + (byte) assertType::t2#32 ← (const byte) TYPEID_DWORD + call assertType + to:main::@33 +main::@33: scope:[main] from main::@32 + (byte) idx#75 ← phi( main::@32/(byte) idx#41 ) + (byte) idx#35 ← (byte) idx#75 + (number~) main::$111 ← - (number) $101d0 + (number~) main::$112 ← (dword) $c + (number~) main::$111 + (byte~) main::$113 ← typeid (number~) main::$112 + (byte) assertType::t1#33 ← (byte~) main::$113 + (byte) assertType::t2#33 ← (const byte) TYPEID_DWORD + call assertType + to:main::@34 +main::@34: scope:[main] from main::@33 + (byte) idx#76 ← phi( main::@33/(byte) idx#41 ) + (byte) idx#36 ← (byte) idx#76 + (number~) main::$115 ← - (number) $7d2b7500 + (number~) main::$116 ← (signed byte) $c + (number~) main::$115 + (byte~) main::$117 ← typeid (number~) main::$116 + (byte) assertType::t1#34 ← (byte~) main::$117 + (byte) assertType::t2#34 ← (const byte) TYPEID_DWORD + call assertType + to:main::@35 +main::@35: scope:[main] from main::@34 + (byte) idx#77 ← phi( main::@34/(byte) idx#41 ) + (byte) idx#37 ← (byte) idx#77 + to:main::@return +main::@return: scope:[main] from main::@35 + (byte) idx#78 ← phi( main::@35/(byte) idx#37 ) + (byte) idx#38 ← (byte) idx#78 + return + to:@return +@1: scope:[] from @begin + (byte) RED#0 ← (byte) 2 + (byte) GREEN#0 ← (byte) 5 + (word) $0 ← (word) $400 + (byte*) SCREEN#0 ← ((byte*)) (word) $0 + (word) $1 ← (word) $d800 + (byte*) COLS#0 ← ((byte*)) (word) $1 + (byte) idx#39 ← (byte) 0 + to:@2 +assertType: scope:[assertType] from main main::@1 main::@10 main::@11 main::@12 main::@13 main::@14 main::@15 main::@16 main::@17 main::@18 main::@19 main::@2 main::@20 main::@21 main::@22 main::@23 main::@24 main::@25 main::@26 main::@27 main::@28 main::@29 main::@3 main::@30 main::@31 main::@32 main::@33 main::@34 main::@4 main::@5 main::@6 main::@7 main::@8 main::@9 + (byte) idx#84 ← phi( main/(byte) idx#0 main::@1/(byte) idx#1 main::@10/(byte) idx#11 main::@11/(byte) idx#12 main::@12/(byte) idx#13 main::@13/(byte) idx#14 main::@14/(byte) idx#15 main::@15/(byte) idx#16 main::@16/(byte) idx#17 main::@17/(byte) idx#18 main::@18/(byte) idx#19 main::@19/(byte) idx#20 main::@2/(byte) idx#2 main::@20/(byte) idx#21 main::@21/(byte) idx#23 main::@22/(byte) idx#24 main::@23/(byte) idx#25 main::@24/(byte) idx#26 main::@25/(byte) idx#27 main::@26/(byte) idx#28 main::@27/(byte) idx#29 main::@28/(byte) idx#30 main::@29/(byte) idx#31 main::@3/(byte) idx#3 main::@30/(byte) idx#32 main::@31/(byte) idx#33 main::@32/(byte) idx#34 main::@33/(byte) idx#35 main::@34/(byte) idx#36 main::@4/(byte) idx#4 main::@5/(byte) idx#5 main::@6/(byte) idx#6 main::@7/(byte) idx#7 main::@8/(byte) idx#8 main::@9/(byte) idx#10 ) + (byte) assertType::t2#35 ← phi( main/(byte) assertType::t2#0 main::@1/(byte) assertType::t2#1 main::@10/(byte) assertType::t2#10 main::@11/(byte) assertType::t2#11 main::@12/(byte) assertType::t2#12 main::@13/(byte) assertType::t2#13 main::@14/(byte) assertType::t2#14 main::@15/(byte) assertType::t2#15 main::@16/(byte) assertType::t2#16 main::@17/(byte) assertType::t2#17 main::@18/(byte) assertType::t2#18 main::@19/(byte) assertType::t2#19 main::@2/(byte) assertType::t2#2 main::@20/(byte) assertType::t2#20 main::@21/(byte) assertType::t2#21 main::@22/(byte) assertType::t2#22 main::@23/(byte) assertType::t2#23 main::@24/(byte) assertType::t2#24 main::@25/(byte) assertType::t2#25 main::@26/(byte) assertType::t2#26 main::@27/(byte) assertType::t2#27 main::@28/(byte) assertType::t2#28 main::@29/(byte) assertType::t2#29 main::@3/(byte) assertType::t2#3 main::@30/(byte) assertType::t2#30 main::@31/(byte) assertType::t2#31 main::@32/(byte) assertType::t2#32 main::@33/(byte) assertType::t2#33 main::@34/(byte) assertType::t2#34 main::@4/(byte) assertType::t2#4 main::@5/(byte) assertType::t2#5 main::@6/(byte) assertType::t2#6 main::@7/(byte) assertType::t2#7 main::@8/(byte) assertType::t2#8 main::@9/(byte) assertType::t2#9 ) + (byte) assertType::t1#35 ← phi( main/(byte) assertType::t1#0 main::@1/(byte) assertType::t1#1 main::@10/(byte) assertType::t1#10 main::@11/(byte) assertType::t1#11 main::@12/(byte) assertType::t1#12 main::@13/(byte) assertType::t1#13 main::@14/(byte) assertType::t1#14 main::@15/(byte) assertType::t1#15 main::@16/(byte) assertType::t1#16 main::@17/(byte) assertType::t1#17 main::@18/(byte) assertType::t1#18 main::@19/(byte) assertType::t1#19 main::@2/(byte) assertType::t1#2 main::@20/(byte) assertType::t1#20 main::@21/(byte) assertType::t1#21 main::@22/(byte) assertType::t1#22 main::@23/(byte) assertType::t1#23 main::@24/(byte) assertType::t1#24 main::@25/(byte) assertType::t1#25 main::@26/(byte) assertType::t1#26 main::@27/(byte) assertType::t1#27 main::@28/(byte) assertType::t1#28 main::@29/(byte) assertType::t1#29 main::@3/(byte) assertType::t1#3 main::@30/(byte) assertType::t1#30 main::@31/(byte) assertType::t1#31 main::@32/(byte) assertType::t1#32 main::@33/(byte) assertType::t1#33 main::@34/(byte) assertType::t1#34 main::@4/(byte) assertType::t1#4 main::@5/(byte) assertType::t1#5 main::@6/(byte) assertType::t1#6 main::@7/(byte) assertType::t1#7 main::@8/(byte) assertType::t1#8 main::@9/(byte) assertType::t1#9 ) + (bool~) assertType::$0 ← (byte) assertType::t1#35 == (byte) assertType::t2#35 + if((bool~) assertType::$0) goto assertType::@1 + to:assertType::@3 +assertType::@1: scope:[assertType] from assertType + (byte) assertType::t1#37 ← phi( assertType/(byte) assertType::t1#35 ) + (byte) idx#79 ← phi( assertType/(byte) idx#84 ) + *((byte*) COLS#0 + (byte) idx#79) ← (byte) GREEN#0 + to:assertType::@2 +assertType::@3: scope:[assertType] from assertType + (byte) assertType::t1#38 ← phi( assertType/(byte) assertType::t1#35 ) + (byte) idx#80 ← phi( assertType/(byte) idx#84 ) + *((byte*) COLS#0 + (byte) idx#80) ← (byte) RED#0 + to:assertType::@2 +assertType::@2: scope:[assertType] from assertType::@1 assertType::@3 + (byte) idx#81 ← phi( assertType::@1/(byte) idx#79 assertType::@3/(byte) idx#80 ) + (byte) assertType::t1#36 ← phi( assertType::@1/(byte) assertType::t1#37 assertType::@3/(byte) assertType::t1#38 ) + *((byte*) SCREEN#0 + (byte) idx#81) ← (byte) assertType::t1#36 + (byte) idx#40 ← ++ (byte) idx#81 + to:assertType::@return +assertType::@return: scope:[assertType] from assertType::@2 + (byte) idx#82 ← phi( assertType::@2/(byte) idx#40 ) + (byte) idx#41 ← (byte) idx#82 + return + to:@return +@2: scope:[] from @1 + (byte) idx#85 ← phi( @1/(byte) idx#39 ) + call main + to:@3 +@3: scope:[] from @2 + (byte) idx#83 ← phi( @2/(byte) idx#38 ) + (byte) idx#42 ← (byte) idx#83 + to:@end +@end: scope:[] from @3 + +SYMBOL TABLE SSA +(word) $0 +(word) $1 +(label) @1 +(label) @2 +(label) @3 +(label) @begin +(label) @end +(byte*) COLS +(byte*) COLS#0 +(byte) GREEN +(byte) GREEN#0 +(byte) RED +(byte) RED#0 +(byte*) SCREEN +(byte*) SCREEN#0 +(const byte) TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(bool~) assertType::$0 +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#0 +(byte) assertType::t1#1 +(byte) assertType::t1#10 +(byte) assertType::t1#11 +(byte) assertType::t1#12 +(byte) assertType::t1#13 +(byte) assertType::t1#14 +(byte) assertType::t1#15 +(byte) assertType::t1#16 +(byte) assertType::t1#17 +(byte) assertType::t1#18 +(byte) assertType::t1#19 +(byte) assertType::t1#2 +(byte) assertType::t1#20 +(byte) assertType::t1#21 +(byte) assertType::t1#22 +(byte) assertType::t1#23 +(byte) assertType::t1#24 +(byte) assertType::t1#25 +(byte) assertType::t1#26 +(byte) assertType::t1#27 +(byte) assertType::t1#28 +(byte) assertType::t1#29 +(byte) assertType::t1#3 +(byte) assertType::t1#30 +(byte) assertType::t1#31 +(byte) assertType::t1#32 +(byte) assertType::t1#33 +(byte) assertType::t1#34 +(byte) assertType::t1#35 +(byte) assertType::t1#36 +(byte) assertType::t1#37 +(byte) assertType::t1#38 +(byte) assertType::t1#4 +(byte) assertType::t1#5 +(byte) assertType::t1#6 +(byte) assertType::t1#7 +(byte) assertType::t1#8 +(byte) assertType::t1#9 +(byte) assertType::t2 +(byte) assertType::t2#0 +(byte) assertType::t2#1 +(byte) assertType::t2#10 +(byte) assertType::t2#11 +(byte) assertType::t2#12 +(byte) assertType::t2#13 +(byte) assertType::t2#14 +(byte) assertType::t2#15 +(byte) assertType::t2#16 +(byte) assertType::t2#17 +(byte) assertType::t2#18 +(byte) assertType::t2#19 +(byte) assertType::t2#2 +(byte) assertType::t2#20 +(byte) assertType::t2#21 +(byte) assertType::t2#22 +(byte) assertType::t2#23 +(byte) assertType::t2#24 +(byte) assertType::t2#25 +(byte) assertType::t2#26 +(byte) assertType::t2#27 +(byte) assertType::t2#28 +(byte) assertType::t2#29 +(byte) assertType::t2#3 +(byte) assertType::t2#30 +(byte) assertType::t2#31 +(byte) assertType::t2#32 +(byte) assertType::t2#33 +(byte) assertType::t2#34 +(byte) assertType::t2#35 +(byte) assertType::t2#4 +(byte) assertType::t2#5 +(byte) assertType::t2#6 +(byte) assertType::t2#7 +(byte) assertType::t2#8 +(byte) assertType::t2#9 +(byte) idx +(byte) idx#0 +(byte) idx#1 +(byte) idx#10 +(byte) idx#11 +(byte) idx#12 +(byte) idx#13 +(byte) idx#14 +(byte) idx#15 +(byte) idx#16 +(byte) idx#17 +(byte) idx#18 +(byte) idx#19 +(byte) idx#2 +(byte) idx#20 +(byte) idx#21 +(byte) idx#22 +(byte) idx#23 +(byte) idx#24 +(byte) idx#25 +(byte) idx#26 +(byte) idx#27 +(byte) idx#28 +(byte) idx#29 +(byte) idx#3 +(byte) idx#30 +(byte) idx#31 +(byte) idx#32 +(byte) idx#33 +(byte) idx#34 +(byte) idx#35 +(byte) idx#36 +(byte) idx#37 +(byte) idx#38 +(byte) idx#39 +(byte) idx#4 +(byte) idx#40 +(byte) idx#41 +(byte) idx#42 +(byte) idx#43 +(byte) idx#44 +(byte) idx#45 +(byte) idx#46 +(byte) idx#47 +(byte) idx#48 +(byte) idx#49 +(byte) idx#5 +(byte) idx#50 +(byte) idx#51 +(byte) idx#52 +(byte) idx#53 +(byte) idx#54 +(byte) idx#55 +(byte) idx#56 +(byte) idx#57 +(byte) idx#58 +(byte) idx#59 +(byte) idx#6 +(byte) idx#60 +(byte) idx#61 +(byte) idx#62 +(byte) idx#63 +(byte) idx#64 +(byte) idx#65 +(byte) idx#66 +(byte) idx#67 +(byte) idx#68 +(byte) idx#69 +(byte) idx#7 +(byte) idx#70 +(byte) idx#71 +(byte) idx#72 +(byte) idx#73 +(byte) idx#74 +(byte) idx#75 +(byte) idx#76 +(byte) idx#77 +(byte) idx#78 +(byte) idx#79 +(byte) idx#8 +(byte) idx#80 +(byte) idx#81 +(byte) idx#82 +(byte) idx#83 +(byte) idx#84 +(byte) idx#85 +(byte) idx#9 +(void()) main() +(number~) main::$0 +(byte~) main::$1 +(byte~) main::$10 +(number~) main::$100 +(byte~) main::$101 +(number~) main::$103 +(number~) main::$104 +(byte~) main::$105 +(number~) main::$107 +(number~) main::$108 +(byte~) main::$109 +(number~) main::$111 +(number~) main::$112 +(byte~) main::$113 +(number~) main::$115 +(number~) main::$116 +(byte~) main::$117 +(number~) main::$12 +(byte~) main::$13 +(number~) main::$15 +(byte~) main::$16 +(number~) main::$18 +(byte~) main::$19 +(number~) main::$21 +(byte~) main::$22 +(number~) main::$24 +(byte~) main::$25 +(number~) main::$27 +(byte~) main::$28 +(number~) main::$3 +(number~) main::$30 +(byte~) main::$31 +(number~) main::$33 +(byte~) main::$34 +(number~) main::$36 +(byte~) main::$37 +(number~) main::$39 +(byte~) main::$4 +(byte~) main::$40 +(number~) main::$42 +(byte~) main::$43 +(number~) main::$45 +(byte~) main::$46 +(number~) main::$48 +(byte~) main::$49 +(number~) main::$51 +(byte~) main::$52 +(number~) main::$54 +(byte~) main::$55 +(number~) main::$57 +(byte~) main::$58 +(number~) main::$6 +(number~) main::$60 +(byte~) main::$61 +(number~) main::$63 +(number~) main::$64 +(byte~) main::$65 +(number~) main::$67 +(number~) main::$68 +(byte~) main::$69 +(byte~) main::$7 +(number~) main::$71 +(number~) main::$72 +(byte~) main::$73 +(number~) main::$75 +(number~) main::$76 +(byte~) main::$77 +(number~) main::$79 +(number~) main::$80 +(byte~) main::$81 +(number~) main::$83 +(number~) main::$84 +(byte~) main::$85 +(number~) main::$87 +(number~) main::$88 +(byte~) main::$89 +(number~) main::$9 +(number~) main::$91 +(number~) main::$92 +(byte~) main::$93 +(number~) main::$95 +(number~) main::$96 +(byte~) main::$97 +(number~) main::$99 +(label) main::@1 +(label) main::@10 +(label) main::@11 +(label) main::@12 +(label) main::@13 +(label) main::@14 +(label) main::@15 +(label) main::@16 +(label) main::@17 +(label) main::@18 +(label) main::@19 +(label) main::@2 +(label) main::@20 +(label) main::@21 +(label) main::@22 +(label) main::@23 +(label) main::@24 +(label) main::@25 +(label) main::@26 +(label) main::@27 +(label) main::@28 +(label) main::@29 +(label) main::@3 +(label) main::@30 +(label) main::@31 +(label) main::@32 +(label) main::@33 +(label) main::@34 +(label) main::@35 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@8 +(label) main::@9 +(label) main::@return + +Adding number conversion cast (signed byte) $c in (number~) main::$0 ← (signed byte) $c + (number) $c +Adding number conversion cast (signed word) $c in (number~) main::$3 ← (signed byte) $c + (number) $82 +Adding number conversion cast (signed word) $82 in (number~) main::$3 ← (signed word)(signed byte) $c + (number) $82 +Adding number conversion cast (signed dword) $c in (number~) main::$6 ← (signed byte) $c + (number) $80e8 +Adding number conversion cast (signed dword) $80e8 in (number~) main::$6 ← (signed dword)(signed byte) $c + (number) $80e8 +Adding number conversion cast (signed word) $c in (number~) main::$9 ← (signed word) $c + (number) $c +Adding number conversion cast (signed word) $82 in (number~) main::$12 ← (signed word) $c + (number) $82 +Adding number conversion cast (signed dword) $c in (number~) main::$15 ← (signed word) $c + (number) $186a0 +Adding number conversion cast (signed dword) $186a0 in (number~) main::$15 ← (signed dword)(signed word) $c + (number) $186a0 +Adding number conversion cast (signed dword) $c in (number~) main::$18 ← (signed dword) $c + (number) $c +Adding number conversion cast (signed dword) $82 in (number~) main::$21 ← (signed dword) $c + (number) $82 +Adding number conversion cast (signed dword) $186a0 in (number~) main::$24 ← (signed dword) $c + (number) $186a0 +Adding number conversion cast (byte) $c in (number~) main::$27 ← (byte) $c + (number) $c +Adding number conversion cast (byte) $fa in (number~) main::$30 ← (byte) $c + (number) $fa +Adding number conversion cast (word) $c in (number~) main::$33 ← (byte) $c + (number) $12c +Adding number conversion cast (word) $12c in (number~) main::$33 ← (word)(byte) $c + (number) $12c +Adding number conversion cast (word) $c in (number~) main::$36 ← (byte) $c + (number) $fffe +Adding number conversion cast (word) $fffe in (number~) main::$36 ← (word)(byte) $c + (number) $fffe +Adding number conversion cast (dword) $c in (number~) main::$39 ← (byte) $c + (number) $101d0 +Adding number conversion cast (dword) $101d0 in (number~) main::$39 ← (dword)(byte) $c + (number) $101d0 +Adding number conversion cast (word) $c in (number~) main::$42 ← (word) $c + (number) $c +Adding number conversion cast (word) $82 in (number~) main::$45 ← (word) $c + (number) $82 +Adding number conversion cast (dword) $c in (number~) main::$48 ← (word) $c + (number) $101d0 +Adding number conversion cast (dword) $101d0 in (number~) main::$48 ← (dword)(word) $c + (number) $101d0 +Adding number conversion cast (dword) $c in (number~) main::$51 ← (dword) $c + (number) $c +Adding number conversion cast (dword) $82 in (number~) main::$54 ← (dword) $c + (number) $82 +Adding number conversion cast (dword) $101d0 in (number~) main::$57 ← (dword) $c + (number) $101d0 +Adding number conversion cast (dword) $c in (number~) main::$60 ← (byte) $c + (number) $b2d05e00 +Adding number conversion cast (dword) $b2d05e00 in (number~) main::$60 ← (dword)(byte) $c + (number) $b2d05e00 +Inferred type updated to signed byte in (number~) main::$0 ← (signed byte) $c + (signed byte)(number) $c +Inferred type updated to signed word in (number~) main::$3 ← (signed word)(signed byte) $c + (signed word)(number) $82 +Inferred type updated to signed dword in (number~) main::$6 ← (signed dword)(signed byte) $c + (signed dword)(number) $80e8 +Inferred type updated to signed word in (number~) main::$9 ← (signed word) $c + (signed word)(number) $c +Inferred type updated to signed word in (number~) main::$12 ← (signed word) $c + (signed word)(number) $82 +Inferred type updated to signed dword in (number~) main::$15 ← (signed dword)(signed word) $c + (signed dword)(number) $186a0 +Inferred type updated to signed dword in (number~) main::$18 ← (signed dword) $c + (signed dword)(number) $c +Inferred type updated to signed dword in (number~) main::$21 ← (signed dword) $c + (signed dword)(number) $82 +Inferred type updated to signed dword in (number~) main::$24 ← (signed dword) $c + (signed dword)(number) $186a0 +Inferred type updated to byte in (number~) main::$27 ← (byte) $c + (byte)(number) $c +Inferred type updated to byte in (number~) main::$30 ← (byte) $c + (byte)(number) $fa +Inferred type updated to word in (number~) main::$33 ← (word)(byte) $c + (word)(number) $12c +Inferred type updated to word in (number~) main::$36 ← (word)(byte) $c + (word)(number) $fffe +Inferred type updated to dword in (number~) main::$39 ← (dword)(byte) $c + (dword)(number) $101d0 +Inferred type updated to word in (number~) main::$42 ← (word) $c + (word)(number) $c +Inferred type updated to word in (number~) main::$45 ← (word) $c + (word)(number) $82 +Inferred type updated to dword in (number~) main::$48 ← (dword)(word) $c + (dword)(number) $101d0 +Inferred type updated to dword in (number~) main::$51 ← (dword) $c + (dword)(number) $c +Inferred type updated to dword in (number~) main::$54 ← (dword) $c + (dword)(number) $82 +Inferred type updated to dword in (number~) main::$57 ← (dword) $c + (dword)(number) $101d0 +Inferred type updated to dword in (number~) main::$60 ← (dword)(byte) $c + (dword)(number) $b2d05e00 +Resolving typeid() (byte~) main::$1 ← typeid (signed byte~) main::$0 +Resolving typeid() (byte~) main::$4 ← typeid (signed word~) main::$3 +Resolving typeid() (byte~) main::$7 ← typeid (signed dword~) main::$6 +Resolving typeid() (byte~) main::$10 ← typeid (signed word~) main::$9 +Resolving typeid() (byte~) main::$13 ← typeid (signed word~) main::$12 +Resolving typeid() (byte~) main::$16 ← typeid (signed dword~) main::$15 +Resolving typeid() (byte~) main::$19 ← typeid (signed dword~) main::$18 +Resolving typeid() (byte~) main::$22 ← typeid (signed dword~) main::$21 +Resolving typeid() (byte~) main::$25 ← typeid (signed dword~) main::$24 +Resolving typeid() (byte~) main::$28 ← typeid (byte~) main::$27 +Resolving typeid() (byte~) main::$31 ← typeid (byte~) main::$30 +Resolving typeid() (byte~) main::$34 ← typeid (word~) main::$33 +Resolving typeid() (byte~) main::$37 ← typeid (word~) main::$36 +Resolving typeid() (byte~) main::$40 ← typeid (dword~) main::$39 +Resolving typeid() (byte~) main::$43 ← typeid (word~) main::$42 +Resolving typeid() (byte~) main::$46 ← typeid (word~) main::$45 +Resolving typeid() (byte~) main::$49 ← typeid (dword~) main::$48 +Resolving typeid() (byte~) main::$52 ← typeid (dword~) main::$51 +Resolving typeid() (byte~) main::$55 ← typeid (dword~) main::$54 +Resolving typeid() (byte~) main::$58 ← typeid (dword~) main::$57 +Resolving typeid() (byte~) main::$61 ← typeid (dword~) main::$60 +Successful SSA optimization PassNTypeIdSimplification +Alias (byte) assertType::t1#0 = (byte~) main::$1 +Alias (byte) idx#1 = (byte) idx#43 +Alias (byte) assertType::t1#1 = (byte~) main::$4 +Alias (byte) idx#2 = (byte) idx#44 +Alias (byte) assertType::t1#2 = (byte~) main::$7 +Alias (byte) idx#3 = (byte) idx#45 +Alias (byte) assertType::t1#3 = (byte~) main::$10 +Alias (byte) idx#4 = (byte) idx#46 +Alias (byte) assertType::t1#4 = (byte~) main::$13 +Alias (byte) idx#47 = (byte) idx#5 +Alias (byte) assertType::t1#5 = (byte~) main::$16 +Alias (byte) idx#48 = (byte) idx#6 +Alias (byte) assertType::t1#6 = (byte~) main::$19 +Alias (byte) idx#49 = (byte) idx#7 +Alias (byte) assertType::t1#7 = (byte~) main::$22 +Alias (byte) idx#50 = (byte) idx#8 +Alias (byte) assertType::t1#8 = (byte~) main::$25 +Alias (byte) idx#51 = (byte) idx#9 +Alias (byte) assertType::t1#9 = (byte~) main::$28 +Alias (byte) idx#11 = (byte) idx#52 +Alias (byte) assertType::t1#10 = (byte~) main::$31 +Alias (byte) idx#12 = (byte) idx#53 +Alias (byte) assertType::t1#11 = (byte~) main::$34 +Alias (byte) idx#13 = (byte) idx#54 +Alias (byte) assertType::t1#12 = (byte~) main::$37 +Alias (byte) idx#14 = (byte) idx#55 +Alias (byte) assertType::t1#13 = (byte~) main::$40 +Alias (byte) idx#15 = (byte) idx#56 +Alias (byte) assertType::t1#14 = (byte~) main::$43 +Alias (byte) idx#16 = (byte) idx#57 +Alias (byte) assertType::t1#15 = (byte~) main::$46 +Alias (byte) idx#17 = (byte) idx#58 +Alias (byte) assertType::t1#16 = (byte~) main::$49 +Alias (byte) idx#18 = (byte) idx#59 +Alias (byte) assertType::t1#17 = (byte~) main::$52 +Alias (byte) idx#19 = (byte) idx#60 +Alias (byte) assertType::t1#18 = (byte~) main::$55 +Alias (byte) idx#20 = (byte) idx#61 +Alias (byte) assertType::t1#19 = (byte~) main::$58 +Alias (byte) idx#21 = (byte) idx#62 +Alias (byte) assertType::t1#20 = (byte~) main::$61 +Alias (byte) idx#22 = (byte) idx#63 +Alias (byte) assertType::t1#21 = (byte~) main::$65 +Alias (byte) idx#24 = (byte) idx#64 +Alias (byte) assertType::t1#22 = (byte~) main::$69 +Alias (byte) idx#25 = (byte) idx#65 +Alias (byte) assertType::t1#23 = (byte~) main::$73 +Alias (byte) idx#26 = (byte) idx#66 +Alias (byte) assertType::t1#24 = (byte~) main::$77 +Alias (byte) idx#27 = (byte) idx#67 +Alias (byte) assertType::t1#25 = (byte~) main::$81 +Alias (byte) idx#28 = (byte) idx#68 +Alias (byte) assertType::t1#26 = (byte~) main::$85 +Alias (byte) idx#29 = (byte) idx#69 +Alias (byte) assertType::t1#27 = (byte~) main::$89 +Alias (byte) idx#30 = (byte) idx#70 +Alias (byte) assertType::t1#28 = (byte~) main::$93 +Alias (byte) idx#31 = (byte) idx#71 +Alias (byte) assertType::t1#29 = (byte~) main::$97 +Alias (byte) idx#32 = (byte) idx#72 +Alias (byte) assertType::t1#30 = (byte~) main::$101 +Alias (byte) idx#33 = (byte) idx#73 +Alias (byte) assertType::t1#31 = (byte~) main::$105 +Alias (byte) idx#34 = (byte) idx#74 +Alias (byte) assertType::t1#32 = (byte~) main::$109 +Alias (byte) idx#35 = (byte) idx#75 +Alias (byte) assertType::t1#33 = (byte~) main::$113 +Alias (byte) idx#36 = (byte) idx#76 +Alias (byte) assertType::t1#34 = (byte~) main::$117 +Alias (byte) idx#37 = (byte) idx#77 (byte) idx#78 (byte) idx#38 +Alias (byte) idx#79 = (byte) idx#84 (byte) idx#80 +Alias (byte) assertType::t1#35 = (byte) assertType::t1#37 (byte) assertType::t1#38 +Alias (byte) idx#40 = (byte) idx#82 (byte) idx#41 +Alias (byte) idx#39 = (byte) idx#85 +Alias (byte) idx#42 = (byte) idx#83 +Successful SSA optimization Pass2AliasElimination +Alias (byte) assertType::t1#35 = (byte) assertType::t1#36 +Alias (byte) idx#79 = (byte) idx#81 +Successful SSA optimization Pass2AliasElimination +Redundant Phi (byte) idx#1 (byte) idx#40 +Redundant Phi (byte) idx#2 (byte) idx#40 +Redundant Phi (byte) idx#3 (byte) idx#40 +Redundant Phi (byte) idx#4 (byte) idx#40 +Redundant Phi (byte) idx#47 (byte) idx#40 +Redundant Phi (byte) idx#48 (byte) idx#40 +Redundant Phi (byte) idx#49 (byte) idx#40 +Redundant Phi (byte) idx#50 (byte) idx#40 +Redundant Phi (byte) idx#51 (byte) idx#40 +Redundant Phi (byte) idx#11 (byte) idx#40 +Redundant Phi (byte) idx#12 (byte) idx#40 +Redundant Phi (byte) idx#13 (byte) idx#40 +Redundant Phi (byte) idx#14 (byte) idx#40 +Redundant Phi (byte) idx#15 (byte) idx#40 +Redundant Phi (byte) idx#16 (byte) idx#40 +Redundant Phi (byte) idx#17 (byte) idx#40 +Redundant Phi (byte) idx#18 (byte) idx#40 +Redundant Phi (byte) idx#19 (byte) idx#40 +Redundant Phi (byte) idx#20 (byte) idx#40 +Redundant Phi (byte) idx#21 (byte) idx#40 +Redundant Phi (byte) idx#22 (byte) idx#40 +Redundant Phi (byte) idx#24 (byte) idx#40 +Redundant Phi (byte) idx#25 (byte) idx#40 +Redundant Phi (byte) idx#26 (byte) idx#40 +Redundant Phi (byte) idx#27 (byte) idx#40 +Redundant Phi (byte) idx#28 (byte) idx#40 +Redundant Phi (byte) idx#29 (byte) idx#40 +Redundant Phi (byte) idx#30 (byte) idx#40 +Redundant Phi (byte) idx#31 (byte) idx#40 +Redundant Phi (byte) idx#32 (byte) idx#40 +Redundant Phi (byte) idx#33 (byte) idx#40 +Redundant Phi (byte) idx#34 (byte) idx#40 +Redundant Phi (byte) idx#35 (byte) idx#40 +Redundant Phi (byte) idx#36 (byte) idx#40 +Redundant Phi (byte) idx#37 (byte) idx#40 +Redundant Phi (byte) idx#42 (byte) idx#37 +Successful SSA optimization Pass2RedundantPhiElimination +Simple Condition (bool~) assertType::$0 [274] if((byte) assertType::t1#35==(byte) assertType::t2#35) goto assertType::@1 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [1] (signed byte~) main::$0 ← (signed byte) $c + (signed byte)(number) $c +Constant right-side identified [8] (signed word~) main::$3 ← (signed word)(signed byte) $c + (signed word)(number) $82 +Constant right-side identified [15] (signed dword~) main::$6 ← (signed dword)(signed byte) $c + (signed dword)(number) $80e8 +Constant right-side identified [22] (signed word~) main::$9 ← (signed word) $c + (signed word)(number) $c +Constant right-side identified [29] (signed word~) main::$12 ← (signed word) $c + (signed word)(number) $82 +Constant right-side identified [36] (signed dword~) main::$15 ← (signed dword)(signed word) $c + (signed dword)(number) $186a0 +Constant right-side identified [43] (signed dword~) main::$18 ← (signed dword) $c + (signed dword)(number) $c +Constant right-side identified [50] (signed dword~) main::$21 ← (signed dword) $c + (signed dword)(number) $82 +Constant right-side identified [57] (signed dword~) main::$24 ← (signed dword) $c + (signed dword)(number) $186a0 +Constant right-side identified [65] (byte~) main::$27 ← (byte) $c + (byte)(number) $c +Constant right-side identified [72] (byte~) main::$30 ← (byte) $c + (byte)(number) $fa +Constant right-side identified [79] (word~) main::$33 ← (word)(byte) $c + (word)(number) $12c +Constant right-side identified [86] (word~) main::$36 ← (word)(byte) $c + (word)(number) $fffe +Constant right-side identified [93] (dword~) main::$39 ← (dword)(byte) $c + (dword)(number) $101d0 +Constant right-side identified [100] (word~) main::$42 ← (word) $c + (word)(number) $c +Constant right-side identified [107] (word~) main::$45 ← (word) $c + (word)(number) $82 +Constant right-side identified [114] (dword~) main::$48 ← (dword)(word) $c + (dword)(number) $101d0 +Constant right-side identified [121] (dword~) main::$51 ← (dword) $c + (dword)(number) $c +Constant right-side identified [128] (dword~) main::$54 ← (dword) $c + (dword)(number) $82 +Constant right-side identified [135] (dword~) main::$57 ← (dword) $c + (dword)(number) $101d0 +Constant right-side identified [142] (dword~) main::$60 ← (dword)(byte) $c + (dword)(number) $b2d05e00 +Constant right-side identified [150] (number~) main::$63 ← - (number) $c +Constant right-side identified [158] (number~) main::$67 ← - (number) $78 +Constant right-side identified [166] (number~) main::$71 ← - (number) $fa +Constant right-side identified [174] (number~) main::$75 ← - (number) $104 +Constant right-side identified [182] (number~) main::$79 ← - (number) $fde8 +Constant right-side identified [190] (number~) main::$83 ← - (number) $101d0 +Constant right-side identified [198] (number~) main::$87 ← - (number) $c +Constant right-side identified [206] (number~) main::$91 ← - (number) $82 +Constant right-side identified [214] (number~) main::$95 ← - (number) $fde8 +Constant right-side identified [222] (number~) main::$99 ← - (number) $101d0 +Constant right-side identified [230] (number~) main::$103 ← - (number) $c +Constant right-side identified [238] (number~) main::$107 ← - (number) $82 +Constant right-side identified [246] (number~) main::$111 ← - (number) $101d0 +Constant right-side identified [254] (number~) main::$115 ← - (number) $7d2b7500 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) idx#0 = 0 +Constant (const signed byte) main::$0 = $c+(signed byte)$c +Constant (const byte) assertType::t1#0 = TYPEID_SIGNED_BYTE +Constant (const byte) assertType::t2#0 = TYPEID_SIGNED_BYTE +Constant (const signed word) main::$3 = (signed word)$c+(signed word)$82 +Constant (const byte) assertType::t1#1 = TYPEID_SIGNED_WORD +Constant (const byte) assertType::t2#1 = TYPEID_SIGNED_WORD +Constant (const signed dword) main::$6 = (signed dword)$c+(signed dword)$80e8 +Constant (const byte) assertType::t1#2 = TYPEID_SIGNED_DWORD +Constant (const byte) assertType::t2#2 = TYPEID_SIGNED_DWORD +Constant (const signed word) main::$9 = $c+(signed word)$c +Constant (const byte) assertType::t1#3 = TYPEID_SIGNED_WORD +Constant (const byte) assertType::t2#3 = TYPEID_SIGNED_WORD +Constant (const signed word) main::$12 = $c+(signed word)$82 +Constant (const byte) assertType::t1#4 = TYPEID_SIGNED_WORD +Constant (const byte) assertType::t2#4 = TYPEID_SIGNED_WORD +Constant (const signed dword) main::$15 = (signed dword)$c+(signed dword)$186a0 +Constant (const byte) assertType::t1#5 = TYPEID_SIGNED_DWORD +Constant (const byte) assertType::t2#5 = TYPEID_SIGNED_DWORD +Constant (const signed dword) main::$18 = $c+(signed dword)$c +Constant (const byte) assertType::t1#6 = TYPEID_SIGNED_DWORD +Constant (const byte) assertType::t2#6 = TYPEID_SIGNED_DWORD +Constant (const signed dword) main::$21 = $c+(signed dword)$82 +Constant (const byte) assertType::t1#7 = TYPEID_SIGNED_DWORD +Constant (const byte) assertType::t2#7 = TYPEID_SIGNED_DWORD +Constant (const signed dword) main::$24 = $c+(signed dword)$186a0 +Constant (const byte) assertType::t1#8 = TYPEID_SIGNED_DWORD +Constant (const byte) assertType::t2#8 = TYPEID_SIGNED_DWORD +Constant (const byte) idx#10 = $28 +Constant (const byte) main::$27 = $c+(byte)$c +Constant (const byte) assertType::t1#9 = TYPEID_BYTE +Constant (const byte) assertType::t2#9 = TYPEID_BYTE +Constant (const byte) main::$30 = $c+(byte)$fa +Constant (const byte) assertType::t1#10 = TYPEID_BYTE +Constant (const byte) assertType::t2#10 = TYPEID_BYTE +Constant (const word) main::$33 = (word)$c+(word)$12c +Constant (const byte) assertType::t1#11 = TYPEID_WORD +Constant (const byte) assertType::t2#11 = TYPEID_WORD +Constant (const word) main::$36 = (word)$c+(word)$fffe +Constant (const byte) assertType::t1#12 = TYPEID_WORD +Constant (const byte) assertType::t2#12 = TYPEID_WORD +Constant (const dword) main::$39 = (dword)$c+(dword)$101d0 +Constant (const byte) assertType::t1#13 = TYPEID_DWORD +Constant (const byte) assertType::t2#13 = TYPEID_DWORD +Constant (const word) main::$42 = $c+(word)$c +Constant (const byte) assertType::t1#14 = TYPEID_WORD +Constant (const byte) assertType::t2#14 = TYPEID_WORD +Constant (const word) main::$45 = $c+(word)$82 +Constant (const byte) assertType::t1#15 = TYPEID_WORD +Constant (const byte) assertType::t2#15 = TYPEID_WORD +Constant (const dword) main::$48 = (dword)$c+(dword)$101d0 +Constant (const byte) assertType::t1#16 = TYPEID_DWORD +Constant (const byte) assertType::t2#16 = TYPEID_DWORD +Constant (const dword) main::$51 = $c+(dword)$c +Constant (const byte) assertType::t1#17 = TYPEID_DWORD +Constant (const byte) assertType::t2#17 = TYPEID_DWORD +Constant (const dword) main::$54 = $c+(dword)$82 +Constant (const byte) assertType::t1#18 = TYPEID_DWORD +Constant (const byte) assertType::t2#18 = TYPEID_DWORD +Constant (const dword) main::$57 = $c+(dword)$101d0 +Constant (const byte) assertType::t1#19 = TYPEID_DWORD +Constant (const byte) assertType::t2#19 = TYPEID_DWORD +Constant (const dword) main::$60 = (dword)$c+(dword)$b2d05e00 +Constant (const byte) assertType::t1#20 = TYPEID_DWORD +Constant (const byte) assertType::t2#20 = TYPEID_DWORD +Constant (const byte) idx#23 = $50 +Constant (const number) main::$63 = -$c +Constant (const byte) assertType::t2#21 = TYPEID_BYTE +Constant (const number) main::$67 = -$78 +Constant (const byte) assertType::t2#22 = TYPEID_BYTE +Constant (const number) main::$71 = -$fa +Constant (const byte) assertType::t2#23 = TYPEID_BYTE +Constant (const number) main::$75 = -$104 +Constant (const byte) assertType::t2#24 = TYPEID_WORD +Constant (const number) main::$79 = -$fde8 +Constant (const byte) assertType::t2#25 = TYPEID_WORD +Constant (const number) main::$83 = -$101d0 +Constant (const byte) assertType::t2#26 = TYPEID_DWORD +Constant (const number) main::$87 = -$c +Constant (const byte) assertType::t2#27 = TYPEID_WORD +Constant (const number) main::$91 = -$82 +Constant (const byte) assertType::t2#28 = TYPEID_WORD +Constant (const number) main::$95 = -$fde8 +Constant (const byte) assertType::t2#29 = TYPEID_WORD +Constant (const number) main::$99 = -$101d0 +Constant (const byte) assertType::t2#30 = TYPEID_DWORD +Constant (const number) main::$103 = -$c +Constant (const byte) assertType::t2#31 = TYPEID_DWORD +Constant (const number) main::$107 = -$82 +Constant (const byte) assertType::t2#32 = TYPEID_DWORD +Constant (const number) main::$111 = -$101d0 +Constant (const byte) assertType::t2#33 = TYPEID_DWORD +Constant (const number) main::$115 = -$7d2b7500 +Constant (const byte) assertType::t2#34 = TYPEID_DWORD +Constant (const byte) RED#0 = 2 +Constant (const byte) GREEN#0 = 5 +Constant (const word) $0 = $400 +Constant (const word) $1 = $d800 +Constant (const byte) idx#39 = 0 +Successful SSA optimization Pass2ConstantIdentification +Eliminating unused constant (const signed byte) main::$0 +Eliminating unused constant (const signed word) main::$3 +Eliminating unused constant (const signed dword) main::$6 +Eliminating unused constant (const signed word) main::$9 +Eliminating unused constant (const signed word) main::$12 +Eliminating unused constant (const signed dword) main::$15 +Eliminating unused constant (const signed dword) main::$18 +Eliminating unused constant (const signed dword) main::$21 +Eliminating unused constant (const signed dword) main::$24 +Eliminating unused constant (const byte) main::$27 +Eliminating unused constant (const byte) main::$30 +Eliminating unused constant (const word) main::$33 +Eliminating unused constant (const word) main::$36 +Eliminating unused constant (const dword) main::$39 +Eliminating unused constant (const word) main::$42 +Eliminating unused constant (const word) main::$45 +Eliminating unused constant (const dword) main::$48 +Eliminating unused constant (const dword) main::$51 +Eliminating unused constant (const dword) main::$54 +Eliminating unused constant (const dword) main::$57 +Eliminating unused constant (const dword) main::$60 +Eliminating unused constant (const byte) idx#39 +Successful SSA optimization PassNEliminateUnusedVars +Eliminating Noop Cast (byte*) SCREEN#0 ← ((byte*)) (const word) $0 +Eliminating Noop Cast (byte*) COLS#0 ← ((byte*)) (const word) $1 +Successful SSA optimization Pass2NopCastElimination +Adding number conversion cast (byte) main::$63 in (number~) main::$64 ← (byte) $c + (const number) main::$63 +Adding number conversion cast (byte) main::$67 in (number~) main::$68 ← (byte) $c + (const number) main::$67 +Adding number conversion cast (byte) main::$71 in (number~) main::$72 ← (byte) $c + (const number) main::$71 +Adding number conversion cast (word) $c in (number~) main::$76 ← (byte) $c + (const number) main::$75 +Adding number conversion cast (word) main::$75 in (number~) main::$76 ← (word)(byte) $c + (const number) main::$75 +Adding number conversion cast (word) $c in (number~) main::$80 ← (byte) $c + (const number) main::$79 +Adding number conversion cast (word) main::$79 in (number~) main::$80 ← (word)(byte) $c + (const number) main::$79 +Adding number conversion cast (dword) $c in (number~) main::$84 ← (byte) $c + (const number) main::$83 +Adding number conversion cast (dword) main::$83 in (number~) main::$84 ← (dword)(byte) $c + (const number) main::$83 +Adding number conversion cast (word) main::$87 in (number~) main::$88 ← (word) $c + (const number) main::$87 +Adding number conversion cast (word) main::$91 in (number~) main::$92 ← (word) $c + (const number) main::$91 +Adding number conversion cast (word) main::$95 in (number~) main::$96 ← (word) $c + (const number) main::$95 +Adding number conversion cast (dword) $c in (number~) main::$100 ← (word) $c + (const number) main::$99 +Adding number conversion cast (dword) main::$99 in (number~) main::$100 ← (dword)(word) $c + (const number) main::$99 +Adding number conversion cast (dword) main::$103 in (number~) main::$104 ← (dword) $c + (const number) main::$103 +Adding number conversion cast (dword) main::$107 in (number~) main::$108 ← (dword) $c + (const number) main::$107 +Adding number conversion cast (dword) main::$111 in (number~) main::$112 ← (dword) $c + (const number) main::$111 +Adding number conversion cast (signed dword) $c in (number~) main::$116 ← (signed byte) $c + (const number) main::$115 +Adding number conversion cast (signed dword) main::$115 in (number~) main::$116 ← (signed dword)(signed byte) $c + (const number) main::$115 +Inferred type updated to byte in (number~) main::$64 ← (byte) $c + (byte)(const number) main::$63 +Inferred type updated to byte in (number~) main::$68 ← (byte) $c + (byte)(const number) main::$67 +Inferred type updated to byte in (number~) main::$72 ← (byte) $c + (byte)(const number) main::$71 +Inferred type updated to word in (number~) main::$76 ← (word)(byte) $c + (word)(const number) main::$75 +Inferred type updated to word in (number~) main::$80 ← (word)(byte) $c + (word)(const number) main::$79 +Inferred type updated to dword in (number~) main::$84 ← (dword)(byte) $c + (dword)(const number) main::$83 +Inferred type updated to word in (number~) main::$88 ← (word) $c + (word)(const number) main::$87 +Inferred type updated to word in (number~) main::$92 ← (word) $c + (word)(const number) main::$91 +Inferred type updated to word in (number~) main::$96 ← (word) $c + (word)(const number) main::$95 +Inferred type updated to dword in (number~) main::$100 ← (dword)(word) $c + (dword)(const number) main::$99 +Inferred type updated to dword in (number~) main::$104 ← (dword) $c + (dword)(const number) main::$103 +Inferred type updated to dword in (number~) main::$108 ← (dword) $c + (dword)(const number) main::$107 +Inferred type updated to dword in (number~) main::$112 ← (dword) $c + (dword)(const number) main::$111 +Inferred type updated to signed dword in (number~) main::$116 ← (signed dword)(signed byte) $c + (signed dword)(const number) main::$115 +Resolving typeid() (byte) assertType::t1#21 ← typeid (byte~) main::$64 +Resolving typeid() (byte) assertType::t1#22 ← typeid (byte~) main::$68 +Resolving typeid() (byte) assertType::t1#23 ← typeid (byte~) main::$72 +Resolving typeid() (byte) assertType::t1#24 ← typeid (word~) main::$76 +Resolving typeid() (byte) assertType::t1#25 ← typeid (word~) main::$80 +Resolving typeid() (byte) assertType::t1#26 ← typeid (dword~) main::$84 +Resolving typeid() (byte) assertType::t1#27 ← typeid (word~) main::$88 +Resolving typeid() (byte) assertType::t1#28 ← typeid (word~) main::$92 +Resolving typeid() (byte) assertType::t1#29 ← typeid (word~) main::$96 +Resolving typeid() (byte) assertType::t1#30 ← typeid (dword~) main::$100 +Resolving typeid() (byte) assertType::t1#31 ← typeid (dword~) main::$104 +Resolving typeid() (byte) assertType::t1#32 ← typeid (dword~) main::$108 +Resolving typeid() (byte) assertType::t1#33 ← typeid (dword~) main::$112 +Resolving typeid() (byte) assertType::t1#34 ← typeid (signed dword~) main::$116 +Successful SSA optimization PassNTypeIdSimplification +Culled Empty Block (label) main::@35 +Culled Empty Block (label) @1 +Culled Empty Block (label) @3 +Successful SSA optimization Pass2CullEmptyBlocks +Constant right-side identified [21] (byte~) main::$64 ← (byte) $c + (byte)(const number) main::$63 +Constant right-side identified [24] (byte~) main::$68 ← (byte) $c + (byte)(const number) main::$67 +Constant right-side identified [27] (byte~) main::$72 ← (byte) $c + (byte)(const number) main::$71 +Constant right-side identified [30] (word~) main::$76 ← (word)(byte) $c + (word)(const number) main::$75 +Constant right-side identified [33] (word~) main::$80 ← (word)(byte) $c + (word)(const number) main::$79 +Constant right-side identified [36] (dword~) main::$84 ← (dword)(byte) $c + (dword)(const number) main::$83 +Constant right-side identified [39] (word~) main::$88 ← (word) $c + (word)(const number) main::$87 +Constant right-side identified [42] (word~) main::$92 ← (word) $c + (word)(const number) main::$91 +Constant right-side identified [45] (word~) main::$96 ← (word) $c + (word)(const number) main::$95 +Constant right-side identified [48] (dword~) main::$100 ← (dword)(word) $c + (dword)(const number) main::$99 +Constant right-side identified [51] (dword~) main::$104 ← (dword) $c + (dword)(const number) main::$103 +Constant right-side identified [54] (dword~) main::$108 ← (dword) $c + (dword)(const number) main::$107 +Constant right-side identified [57] (dword~) main::$112 ← (dword) $c + (dword)(const number) main::$111 +Constant right-side identified [60] (signed dword~) main::$116 ← (signed dword)(signed byte) $c + (signed dword)(const number) main::$115 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) main::$64 = $c+(byte)main::$63 +Constant (const byte) assertType::t1#21 = TYPEID_BYTE +Constant (const byte) main::$68 = $c+(byte)main::$67 +Constant (const byte) assertType::t1#22 = TYPEID_BYTE +Constant (const byte) main::$72 = $c+(byte)main::$71 +Constant (const byte) assertType::t1#23 = TYPEID_BYTE +Constant (const word) main::$76 = (word)$c+(word)main::$75 +Constant (const byte) assertType::t1#24 = TYPEID_WORD +Constant (const word) main::$80 = (word)$c+(word)main::$79 +Constant (const byte) assertType::t1#25 = TYPEID_WORD +Constant (const dword) main::$84 = (dword)$c+(dword)main::$83 +Constant (const byte) assertType::t1#26 = TYPEID_DWORD +Constant (const word) main::$88 = $c+(word)main::$87 +Constant (const byte) assertType::t1#27 = TYPEID_WORD +Constant (const word) main::$92 = $c+(word)main::$91 +Constant (const byte) assertType::t1#28 = TYPEID_WORD +Constant (const word) main::$96 = $c+(word)main::$95 +Constant (const byte) assertType::t1#29 = TYPEID_WORD +Constant (const dword) main::$100 = (dword)$c+(dword)main::$99 +Constant (const byte) assertType::t1#30 = TYPEID_DWORD +Constant (const dword) main::$104 = $c+(dword)main::$103 +Constant (const byte) assertType::t1#31 = TYPEID_DWORD +Constant (const dword) main::$108 = $c+(dword)main::$107 +Constant (const byte) assertType::t1#32 = TYPEID_DWORD +Constant (const dword) main::$112 = $c+(dword)main::$111 +Constant (const byte) assertType::t1#33 = TYPEID_DWORD +Constant (const signed dword) main::$116 = (signed dword)$c+(signed dword)main::$115 +Constant (const byte) assertType::t1#34 = TYPEID_SIGNED_DWORD +Successful SSA optimization Pass2ConstantIdentification +Eliminating unused constant (const byte) main::$64 +Eliminating unused constant (const byte) main::$68 +Eliminating unused constant (const byte) main::$72 +Eliminating unused constant (const word) main::$76 +Eliminating unused constant (const word) main::$80 +Eliminating unused constant (const dword) main::$84 +Eliminating unused constant (const word) main::$88 +Eliminating unused constant (const word) main::$92 +Eliminating unused constant (const word) main::$96 +Eliminating unused constant (const dword) main::$100 +Eliminating unused constant (const dword) main::$104 +Eliminating unused constant (const dword) main::$108 +Eliminating unused constant (const dword) main::$112 +Eliminating unused constant (const signed dword) main::$116 +Successful SSA optimization PassNEliminateUnusedVars +Eliminating unused constant (const number) main::$63 +Eliminating unused constant (const number) main::$67 +Eliminating unused constant (const number) main::$71 +Eliminating unused constant (const number) main::$75 +Eliminating unused constant (const number) main::$79 +Eliminating unused constant (const number) main::$83 +Eliminating unused constant (const number) main::$87 +Eliminating unused constant (const number) main::$91 +Eliminating unused constant (const number) main::$95 +Eliminating unused constant (const number) main::$99 +Eliminating unused constant (const number) main::$103 +Eliminating unused constant (const number) main::$107 +Eliminating unused constant (const number) main::$111 +Eliminating unused constant (const number) main::$115 +Successful SSA optimization PassNEliminateUnusedVars +Inlining constant with var siblings (const byte) assertType::t1#0 +Inlining constant with var siblings (const byte) assertType::t2#0 +Inlining constant with var siblings (const byte) assertType::t1#1 +Inlining constant with var siblings (const byte) assertType::t2#1 +Inlining constant with var siblings (const byte) assertType::t1#2 +Inlining constant with var siblings (const byte) assertType::t2#2 +Inlining constant with var siblings (const byte) assertType::t1#3 +Inlining constant with var siblings (const byte) assertType::t2#3 +Inlining constant with var siblings (const byte) assertType::t1#4 +Inlining constant with var siblings (const byte) assertType::t2#4 +Inlining constant with var siblings (const byte) assertType::t1#5 +Inlining constant with var siblings (const byte) assertType::t2#5 +Inlining constant with var siblings (const byte) assertType::t1#6 +Inlining constant with var siblings (const byte) assertType::t2#6 +Inlining constant with var siblings (const byte) assertType::t1#7 +Inlining constant with var siblings (const byte) assertType::t2#7 +Inlining constant with var siblings (const byte) assertType::t1#8 +Inlining constant with var siblings (const byte) assertType::t2#8 +Inlining constant with var siblings (const byte) assertType::t1#9 +Inlining constant with var siblings (const byte) assertType::t2#9 +Inlining constant with var siblings (const byte) assertType::t1#10 +Inlining constant with var siblings (const byte) assertType::t2#10 +Inlining constant with var siblings (const byte) assertType::t1#11 +Inlining constant with var siblings (const byte) assertType::t2#11 +Inlining constant with var siblings (const byte) assertType::t1#12 +Inlining constant with var siblings (const byte) assertType::t2#12 +Inlining constant with var siblings (const byte) assertType::t1#13 +Inlining constant with var siblings (const byte) assertType::t2#13 +Inlining constant with var siblings (const byte) assertType::t1#14 +Inlining constant with var siblings (const byte) assertType::t2#14 +Inlining constant with var siblings (const byte) assertType::t1#15 +Inlining constant with var siblings (const byte) assertType::t2#15 +Inlining constant with var siblings (const byte) assertType::t1#16 +Inlining constant with var siblings (const byte) assertType::t2#16 +Inlining constant with var siblings (const byte) assertType::t1#17 +Inlining constant with var siblings (const byte) assertType::t2#17 +Inlining constant with var siblings (const byte) assertType::t1#18 +Inlining constant with var siblings (const byte) assertType::t2#18 +Inlining constant with var siblings (const byte) assertType::t1#19 +Inlining constant with var siblings (const byte) assertType::t2#19 +Inlining constant with var siblings (const byte) assertType::t1#20 +Inlining constant with var siblings (const byte) assertType::t2#20 +Inlining constant with var siblings (const byte) assertType::t2#21 +Inlining constant with var siblings (const byte) assertType::t2#22 +Inlining constant with var siblings (const byte) assertType::t2#23 +Inlining constant with var siblings (const byte) assertType::t2#24 +Inlining constant with var siblings (const byte) assertType::t2#25 +Inlining constant with var siblings (const byte) assertType::t2#26 +Inlining constant with var siblings (const byte) assertType::t2#27 +Inlining constant with var siblings (const byte) assertType::t2#28 +Inlining constant with var siblings (const byte) assertType::t2#29 +Inlining constant with var siblings (const byte) assertType::t2#30 +Inlining constant with var siblings (const byte) assertType::t2#31 +Inlining constant with var siblings (const byte) assertType::t2#32 +Inlining constant with var siblings (const byte) assertType::t2#33 +Inlining constant with var siblings (const byte) assertType::t2#34 +Inlining constant with var siblings (const byte) assertType::t1#21 +Inlining constant with var siblings (const byte) assertType::t1#22 +Inlining constant with var siblings (const byte) assertType::t1#23 +Inlining constant with var siblings (const byte) assertType::t1#24 +Inlining constant with var siblings (const byte) assertType::t1#25 +Inlining constant with var siblings (const byte) assertType::t1#26 +Inlining constant with var siblings (const byte) assertType::t1#27 +Inlining constant with var siblings (const byte) assertType::t1#28 +Inlining constant with var siblings (const byte) assertType::t1#29 +Inlining constant with var siblings (const byte) assertType::t1#30 +Inlining constant with var siblings (const byte) assertType::t1#31 +Inlining constant with var siblings (const byte) assertType::t1#32 +Inlining constant with var siblings (const byte) assertType::t1#33 +Inlining constant with var siblings (const byte) assertType::t1#34 +Inlining constant with var siblings (const byte) idx#0 +Inlining constant with var siblings (const byte) idx#10 +Inlining constant with var siblings (const byte) idx#23 +Constant inlined assertType::t2#5 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t2#6 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t2#7 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t2#8 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t2#9 = (const byte) TYPEID_BYTE +Constant inlined $0 = (word) $400 +Constant inlined $1 = (word) $d800 +Constant inlined assertType::t2#31 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#30 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#33 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#21 = (const byte) TYPEID_BYTE +Constant inlined assertType::t1#20 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#32 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#23 = (const byte) TYPEID_BYTE +Constant inlined assertType::t2#34 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#22 = (const byte) TYPEID_BYTE +Constant inlined assertType::t1#25 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#24 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#27 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#0 = (const byte) TYPEID_SIGNED_BYTE +Constant inlined assertType::t1#26 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#1 = (const byte) TYPEID_SIGNED_WORD +Constant inlined assertType::t1#29 = (const byte) TYPEID_WORD +Constant inlined idx#0 = (byte) 0 +Constant inlined assertType::t2#2 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t1#28 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#3 = (const byte) TYPEID_SIGNED_WORD +Constant inlined assertType::t2#4 = (const byte) TYPEID_SIGNED_WORD +Constant inlined idx#23 = (byte) $50 +Constant inlined assertType::t2#20 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#10 = (const byte) TYPEID_BYTE +Constant inlined assertType::t2#22 = (const byte) TYPEID_BYTE +Constant inlined assertType::t2#21 = (const byte) TYPEID_BYTE +Constant inlined assertType::t1#12 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#24 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#11 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#23 = (const byte) TYPEID_BYTE +Constant inlined assertType::t1#14 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#26 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#13 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#25 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#16 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#28 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#15 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#27 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#18 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#17 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#29 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#19 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#6 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined idx#10 = (byte) $28 +Constant inlined assertType::t1#7 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t1#8 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t1#9 = (const byte) TYPEID_BYTE +Constant inlined assertType::t2#11 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#10 = (const byte) TYPEID_BYTE +Constant inlined assertType::t2#13 = (const byte) TYPEID_DWORD +Constant inlined assertType::t2#12 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#15 = (const byte) TYPEID_WORD +Constant inlined assertType::t2#14 = (const byte) TYPEID_WORD +Constant inlined assertType::t1#0 = (const byte) TYPEID_SIGNED_BYTE +Constant inlined assertType::t2#17 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#1 = (const byte) TYPEID_SIGNED_WORD +Constant inlined assertType::t2#16 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#2 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t2#19 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#3 = (const byte) TYPEID_SIGNED_WORD +Constant inlined assertType::t2#18 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#4 = (const byte) TYPEID_SIGNED_WORD +Constant inlined assertType::t1#5 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t1#30 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#32 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#31 = (const byte) TYPEID_DWORD +Constant inlined assertType::t1#34 = (const byte) TYPEID_SIGNED_DWORD +Constant inlined assertType::t1#33 = (const byte) TYPEID_DWORD +Successful SSA optimization Pass2ConstantInlining +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@9 +Adding NOP phi() at start of main::@21 +CALL GRAPH +Calls in [] to main:2 +Calls in [main] to assertType:5 assertType:7 assertType:9 assertType:11 assertType:13 assertType:15 assertType:17 assertType:19 assertType:21 assertType:23 assertType:25 assertType:27 assertType:29 assertType:31 assertType:33 assertType:35 assertType:37 assertType:39 assertType:41 assertType:43 assertType:45 assertType:47 assertType:49 assertType:51 assertType:53 assertType:55 assertType:57 assertType:59 assertType:61 assertType:63 assertType:65 assertType:67 assertType:69 assertType:71 assertType:73 + +Created 3 initial phi equivalence classes +Coalesced [6] idx#86 ← idx#40 +Coalesced (already) [8] idx#97 ← idx#40 +Coalesced (already) [10] idx#107 ← idx#40 +Coalesced (already) [12] idx#113 ← idx#40 +Coalesced (already) [14] idx#114 ← idx#40 +Coalesced (already) [16] idx#115 ← idx#40 +Coalesced (already) [18] idx#116 ← idx#40 +Coalesced (already) [20] idx#117 ← idx#40 +Coalesced (already) [24] idx#87 ← idx#40 +Coalesced (already) [26] idx#88 ← idx#40 +Coalesced (already) [28] idx#89 ← idx#40 +Coalesced (already) [30] idx#90 ← idx#40 +Coalesced (already) [32] idx#91 ← idx#40 +Coalesced (already) [34] idx#92 ← idx#40 +Coalesced (already) [36] idx#93 ← idx#40 +Coalesced (already) [38] idx#94 ← idx#40 +Coalesced (already) [40] idx#95 ← idx#40 +Coalesced (already) [42] idx#96 ← idx#40 +Coalesced (already) [44] idx#98 ← idx#40 +Coalesced (already) [48] idx#99 ← idx#40 +Coalesced (already) [50] idx#100 ← idx#40 +Coalesced (already) [52] idx#101 ← idx#40 +Coalesced (already) [54] idx#102 ← idx#40 +Coalesced (already) [56] idx#103 ← idx#40 +Coalesced (already) [58] idx#104 ← idx#40 +Coalesced (already) [60] idx#105 ← idx#40 +Coalesced (already) [62] idx#106 ← idx#40 +Coalesced (already) [64] idx#108 ← idx#40 +Coalesced (already) [66] idx#109 ← idx#40 +Coalesced (already) [68] idx#110 ← idx#40 +Coalesced (already) [70] idx#111 ← idx#40 +Coalesced (already) [72] idx#112 ← idx#40 +Coalesced down to 3 phi equivalence classes +Renumbering block @2 to @1 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +Adding NOP phi() at start of main::@2 +Adding NOP phi() at start of main::@3 +Adding NOP phi() at start of main::@4 +Adding NOP phi() at start of main::@5 +Adding NOP phi() at start of main::@6 +Adding NOP phi() at start of main::@7 +Adding NOP phi() at start of main::@8 +Adding NOP phi() at start of main::@9 +Adding NOP phi() at start of main::@10 +Adding NOP phi() at start of main::@11 +Adding NOP phi() at start of main::@12 +Adding NOP phi() at start of main::@13 +Adding NOP phi() at start of main::@14 +Adding NOP phi() at start of main::@15 +Adding NOP phi() at start of main::@16 +Adding NOP phi() at start of main::@17 +Adding NOP phi() at start of main::@18 +Adding NOP phi() at start of main::@19 +Adding NOP phi() at start of main::@20 +Adding NOP phi() at start of main::@21 +Adding NOP phi() at start of main::@22 +Adding NOP phi() at start of main::@23 +Adding NOP phi() at start of main::@24 +Adding NOP phi() at start of main::@25 +Adding NOP phi() at start of main::@26 +Adding NOP phi() at start of main::@27 +Adding NOP phi() at start of main::@28 +Adding NOP phi() at start of main::@29 +Adding NOP phi() at start of main::@30 +Adding NOP phi() at start of main::@31 +Adding NOP phi() at start of main::@32 +Adding NOP phi() at start of main::@33 +Adding NOP phi() at start of main::@34 + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call assertType + to:main::@1 +main::@1: scope:[main] from main + [6] phi() + [7] call assertType + to:main::@2 +main::@2: scope:[main] from main::@1 + [8] phi() + [9] call assertType + to:main::@3 +main::@3: scope:[main] from main::@2 + [10] phi() + [11] call assertType + to:main::@4 +main::@4: scope:[main] from main::@3 + [12] phi() + [13] call assertType + to:main::@5 +main::@5: scope:[main] from main::@4 + [14] phi() + [15] call assertType + to:main::@6 +main::@6: scope:[main] from main::@5 + [16] phi() + [17] call assertType + to:main::@7 +main::@7: scope:[main] from main::@6 + [18] phi() + [19] call assertType + to:main::@8 +main::@8: scope:[main] from main::@7 + [20] phi() + [21] call assertType + to:main::@9 +main::@9: scope:[main] from main::@8 + [22] phi() + [23] call assertType + to:main::@10 +main::@10: scope:[main] from main::@9 + [24] phi() + [25] call assertType + to:main::@11 +main::@11: scope:[main] from main::@10 + [26] phi() + [27] call assertType + to:main::@12 +main::@12: scope:[main] from main::@11 + [28] phi() + [29] call assertType + to:main::@13 +main::@13: scope:[main] from main::@12 + [30] phi() + [31] call assertType + to:main::@14 +main::@14: scope:[main] from main::@13 + [32] phi() + [33] call assertType + to:main::@15 +main::@15: scope:[main] from main::@14 + [34] phi() + [35] call assertType + to:main::@16 +main::@16: scope:[main] from main::@15 + [36] phi() + [37] call assertType + to:main::@17 +main::@17: scope:[main] from main::@16 + [38] phi() + [39] call assertType + to:main::@18 +main::@18: scope:[main] from main::@17 + [40] phi() + [41] call assertType + to:main::@19 +main::@19: scope:[main] from main::@18 + [42] phi() + [43] call assertType + to:main::@20 +main::@20: scope:[main] from main::@19 + [44] phi() + [45] call assertType + to:main::@21 +main::@21: scope:[main] from main::@20 + [46] phi() + [47] call assertType + to:main::@22 +main::@22: scope:[main] from main::@21 + [48] phi() + [49] call assertType + to:main::@23 +main::@23: scope:[main] from main::@22 + [50] phi() + [51] call assertType + to:main::@24 +main::@24: scope:[main] from main::@23 + [52] phi() + [53] call assertType + to:main::@25 +main::@25: scope:[main] from main::@24 + [54] phi() + [55] call assertType + to:main::@26 +main::@26: scope:[main] from main::@25 + [56] phi() + [57] call assertType + to:main::@27 +main::@27: scope:[main] from main::@26 + [58] phi() + [59] call assertType + to:main::@28 +main::@28: scope:[main] from main::@27 + [60] phi() + [61] call assertType + to:main::@29 +main::@29: scope:[main] from main::@28 + [62] phi() + [63] call assertType + to:main::@30 +main::@30: scope:[main] from main::@29 + [64] phi() + [65] call assertType + to:main::@31 +main::@31: scope:[main] from main::@30 + [66] phi() + [67] call assertType + to:main::@32 +main::@32: scope:[main] from main::@31 + [68] phi() + [69] call assertType + to:main::@33 +main::@33: scope:[main] from main::@32 + [70] phi() + [71] call assertType + to:main::@34 +main::@34: scope:[main] from main::@33 + [72] phi() + [73] call assertType + to:main::@return +main::@return: scope:[main] from main::@34 + [74] return + to:@return +assertType: scope:[assertType] from main main::@1 main::@10 main::@11 main::@12 main::@13 main::@14 main::@15 main::@16 main::@17 main::@18 main::@19 main::@2 main::@20 main::@21 main::@22 main::@23 main::@24 main::@25 main::@26 main::@27 main::@28 main::@29 main::@3 main::@30 main::@31 main::@32 main::@33 main::@34 main::@4 main::@5 main::@6 main::@7 main::@8 main::@9 + [75] (byte) idx#79 ← phi( main/(byte) 0 main::@1/(byte) idx#40 main::@10/(byte) idx#40 main::@11/(byte) idx#40 main::@12/(byte) idx#40 main::@13/(byte) idx#40 main::@14/(byte) idx#40 main::@15/(byte) idx#40 main::@16/(byte) idx#40 main::@17/(byte) idx#40 main::@18/(byte) idx#40 main::@19/(byte) idx#40 main::@2/(byte) idx#40 main::@20/(byte) idx#40 main::@21/(byte) $50 main::@22/(byte) idx#40 main::@23/(byte) idx#40 main::@24/(byte) idx#40 main::@25/(byte) idx#40 main::@26/(byte) idx#40 main::@27/(byte) idx#40 main::@28/(byte) idx#40 main::@29/(byte) idx#40 main::@3/(byte) idx#40 main::@30/(byte) idx#40 main::@31/(byte) idx#40 main::@32/(byte) idx#40 main::@33/(byte) idx#40 main::@34/(byte) idx#40 main::@4/(byte) idx#40 main::@5/(byte) idx#40 main::@6/(byte) idx#40 main::@7/(byte) idx#40 main::@8/(byte) idx#40 main::@9/(byte) $28 ) + [75] (byte) assertType::t2#35 ← phi( main/(const byte) TYPEID_SIGNED_BYTE main::@1/(const byte) TYPEID_SIGNED_WORD main::@10/(const byte) TYPEID_BYTE main::@11/(const byte) TYPEID_WORD main::@12/(const byte) TYPEID_WORD main::@13/(const byte) TYPEID_DWORD main::@14/(const byte) TYPEID_WORD main::@15/(const byte) TYPEID_WORD main::@16/(const byte) TYPEID_DWORD main::@17/(const byte) TYPEID_DWORD main::@18/(const byte) TYPEID_DWORD main::@19/(const byte) TYPEID_DWORD main::@2/(const byte) TYPEID_SIGNED_DWORD main::@20/(const byte) TYPEID_DWORD main::@21/(const byte) TYPEID_BYTE main::@22/(const byte) TYPEID_BYTE main::@23/(const byte) TYPEID_BYTE main::@24/(const byte) TYPEID_WORD main::@25/(const byte) TYPEID_WORD main::@26/(const byte) TYPEID_DWORD main::@27/(const byte) TYPEID_WORD main::@28/(const byte) TYPEID_WORD main::@29/(const byte) TYPEID_WORD main::@3/(const byte) TYPEID_SIGNED_WORD main::@30/(const byte) TYPEID_DWORD main::@31/(const byte) TYPEID_DWORD main::@32/(const byte) TYPEID_DWORD main::@33/(const byte) TYPEID_DWORD main::@34/(const byte) TYPEID_DWORD main::@4/(const byte) TYPEID_SIGNED_WORD main::@5/(const byte) TYPEID_SIGNED_DWORD main::@6/(const byte) TYPEID_SIGNED_DWORD main::@7/(const byte) TYPEID_SIGNED_DWORD main::@8/(const byte) TYPEID_SIGNED_DWORD main::@9/(const byte) TYPEID_BYTE ) + [75] (byte) assertType::t1#35 ← phi( main/(const byte) TYPEID_SIGNED_BYTE main::@1/(const byte) TYPEID_SIGNED_WORD main::@10/(const byte) TYPEID_BYTE main::@11/(const byte) TYPEID_WORD main::@12/(const byte) TYPEID_WORD main::@13/(const byte) TYPEID_DWORD main::@14/(const byte) TYPEID_WORD main::@15/(const byte) TYPEID_WORD main::@16/(const byte) TYPEID_DWORD main::@17/(const byte) TYPEID_DWORD main::@18/(const byte) TYPEID_DWORD main::@19/(const byte) TYPEID_DWORD main::@2/(const byte) TYPEID_SIGNED_DWORD main::@20/(const byte) TYPEID_DWORD main::@21/(const byte) TYPEID_BYTE main::@22/(const byte) TYPEID_BYTE main::@23/(const byte) TYPEID_BYTE main::@24/(const byte) TYPEID_WORD main::@25/(const byte) TYPEID_WORD main::@26/(const byte) TYPEID_DWORD main::@27/(const byte) TYPEID_WORD main::@28/(const byte) TYPEID_WORD main::@29/(const byte) TYPEID_WORD main::@3/(const byte) TYPEID_SIGNED_WORD main::@30/(const byte) TYPEID_DWORD main::@31/(const byte) TYPEID_DWORD main::@32/(const byte) TYPEID_DWORD main::@33/(const byte) TYPEID_DWORD main::@34/(const byte) TYPEID_SIGNED_DWORD main::@4/(const byte) TYPEID_SIGNED_WORD main::@5/(const byte) TYPEID_SIGNED_DWORD main::@6/(const byte) TYPEID_SIGNED_DWORD main::@7/(const byte) TYPEID_SIGNED_DWORD main::@8/(const byte) TYPEID_SIGNED_DWORD main::@9/(const byte) TYPEID_BYTE ) + [76] if((byte) assertType::t1#35==(byte) assertType::t2#35) goto assertType::@1 + to:assertType::@3 +assertType::@3: scope:[assertType] from assertType + [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 + to:assertType::@2 +assertType::@2: scope:[assertType] from assertType::@1 assertType::@3 + [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 + [79] (byte) idx#40 ← ++ (byte) idx#79 + to:assertType::@return +assertType::@return: scope:[assertType] from assertType::@2 + [80] return + to:@return +assertType::@1: scope:[assertType] from assertType + [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 + to:assertType::@2 + + +VARIABLE REGISTER WEIGHTS +(byte*) COLS +(byte) GREEN +(byte) RED +(byte*) SCREEN +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(byte) assertType::t1 +(byte) assertType::t1#35 1.0 +(byte) assertType::t2 +(byte) assertType::t2#35 2.0 +(byte) idx +(byte) idx#40 0.9999999999999993 +(byte) idx#79 14.400000000000007 +(void()) main() + +Initial phi equivalence classes +[ assertType::t1#35 ] +[ assertType::t2#35 ] +[ idx#79 idx#40 ] +Complete equivalence classes +[ assertType::t1#35 ] +[ assertType::t2#35 ] +[ idx#79 idx#40 ] +Allocated zp ZP_BYTE:2 [ assertType::t1#35 ] +Allocated zp ZP_BYTE:3 [ assertType::t2#35 ] +Allocated zp ZP_BYTE:4 [ idx#79 idx#40 ] + +INITIAL ASM +//SEG0 File Comments +// Tests conversion of numbers to correct int types +// See https://gitlab.com/camelot/kickc/issues/181 +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_SIGNED_DWORD = 6 + .const TYPEID_BYTE = 1 + .const TYPEID_WORD = 3 + .const TYPEID_DWORD = 5 + .const RED = 2 + .const GREEN = 5 + .label idx = 4 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + //SEG11 [5] call assertType + //SEG12 [75] phi from main to assertType [phi:main->assertType] + assertType_from_main: + //SEG13 [75] phi (byte) idx#79 = (byte) 0 [phi:main->assertType#0] -- vbuz1=vbuc1 + lda #0 + sta idx + //SEG14 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_BYTE [phi:main->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG15 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_BYTE [phi:main->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t1 + jsr assertType + //SEG16 [6] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + jmp b1 + //SEG17 main::@1 + b1: + //SEG18 [7] call assertType + //SEG19 [75] phi from main::@1 to assertType [phi:main::@1->assertType] + assertType_from_b1: + //SEG20 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@1->assertType#0] -- register_copy + //SEG21 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG22 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@1->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG23 [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + jmp b2 + //SEG24 main::@2 + b2: + //SEG25 [9] call assertType + //SEG26 [75] phi from main::@2 to assertType [phi:main::@2->assertType] + assertType_from_b2: + //SEG27 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@2->assertType#0] -- register_copy + //SEG28 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG29 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@2->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG30 [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + b3_from_b2: + jmp b3 + //SEG31 main::@3 + b3: + //SEG32 [11] call assertType + //SEG33 [75] phi from main::@3 to assertType [phi:main::@3->assertType] + assertType_from_b3: + //SEG34 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@3->assertType#0] -- register_copy + //SEG35 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG36 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@3->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG37 [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + b4_from_b3: + jmp b4 + //SEG38 main::@4 + b4: + //SEG39 [13] call assertType + //SEG40 [75] phi from main::@4 to assertType [phi:main::@4->assertType] + assertType_from_b4: + //SEG41 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@4->assertType#0] -- register_copy + //SEG42 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG43 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@4->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t1 + jsr assertType + //SEG44 [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + b5_from_b4: + jmp b5 + //SEG45 main::@5 + b5: + //SEG46 [15] call assertType + //SEG47 [75] phi from main::@5 to assertType [phi:main::@5->assertType] + assertType_from_b5: + //SEG48 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@5->assertType#0] -- register_copy + //SEG49 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG50 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@5->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG51 [16] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + b6_from_b5: + jmp b6 + //SEG52 main::@6 + b6: + //SEG53 [17] call assertType + //SEG54 [75] phi from main::@6 to assertType [phi:main::@6->assertType] + assertType_from_b6: + //SEG55 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@6->assertType#0] -- register_copy + //SEG56 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG57 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@6->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG58 [18] phi from main::@6 to main::@7 [phi:main::@6->main::@7] + b7_from_b6: + jmp b7 + //SEG59 main::@7 + b7: + //SEG60 [19] call assertType + //SEG61 [75] phi from main::@7 to assertType [phi:main::@7->assertType] + assertType_from_b7: + //SEG62 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@7->assertType#0] -- register_copy + //SEG63 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG64 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@7->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG65 [20] phi from main::@7 to main::@8 [phi:main::@7->main::@8] + b8_from_b7: + jmp b8 + //SEG66 main::@8 + b8: + //SEG67 [21] call assertType + //SEG68 [75] phi from main::@8 to assertType [phi:main::@8->assertType] + assertType_from_b8: + //SEG69 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@8->assertType#0] -- register_copy + //SEG70 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG71 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@8->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + //SEG72 [22] phi from main::@8 to main::@9 [phi:main::@8->main::@9] + b9_from_b8: + jmp b9 + //SEG73 main::@9 + b9: + //SEG74 [23] call assertType + //SEG75 [75] phi from main::@9 to assertType [phi:main::@9->assertType] + assertType_from_b9: + //SEG76 [75] phi (byte) idx#79 = (byte) $28 [phi:main::@9->assertType#0] -- vbuz1=vbuc1 + lda #$28 + sta idx + //SEG77 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG78 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@9->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG79 [24] phi from main::@9 to main::@10 [phi:main::@9->main::@10] + b10_from_b9: + jmp b10 + //SEG80 main::@10 + b10: + //SEG81 [25] call assertType + //SEG82 [75] phi from main::@10 to assertType [phi:main::@10->assertType] + assertType_from_b10: + //SEG83 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@10->assertType#0] -- register_copy + //SEG84 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG85 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@10->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG86 [26] phi from main::@10 to main::@11 [phi:main::@10->main::@11] + b11_from_b10: + jmp b11 + //SEG87 main::@11 + b11: + //SEG88 [27] call assertType + //SEG89 [75] phi from main::@11 to assertType [phi:main::@11->assertType] + assertType_from_b11: + //SEG90 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@11->assertType#0] -- register_copy + //SEG91 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG92 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@11->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG93 [28] phi from main::@11 to main::@12 [phi:main::@11->main::@12] + b12_from_b11: + jmp b12 + //SEG94 main::@12 + b12: + //SEG95 [29] call assertType + //SEG96 [75] phi from main::@12 to assertType [phi:main::@12->assertType] + assertType_from_b12: + //SEG97 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@12->assertType#0] -- register_copy + //SEG98 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG99 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@12->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG100 [30] phi from main::@12 to main::@13 [phi:main::@12->main::@13] + b13_from_b12: + jmp b13 + //SEG101 main::@13 + b13: + //SEG102 [31] call assertType + //SEG103 [75] phi from main::@13 to assertType [phi:main::@13->assertType] + assertType_from_b13: + //SEG104 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@13->assertType#0] -- register_copy + //SEG105 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG106 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@13->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG107 [32] phi from main::@13 to main::@14 [phi:main::@13->main::@14] + b14_from_b13: + jmp b14 + //SEG108 main::@14 + b14: + //SEG109 [33] call assertType + //SEG110 [75] phi from main::@14 to assertType [phi:main::@14->assertType] + assertType_from_b14: + //SEG111 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@14->assertType#0] -- register_copy + //SEG112 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG113 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@14->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG114 [34] phi from main::@14 to main::@15 [phi:main::@14->main::@15] + b15_from_b14: + jmp b15 + //SEG115 main::@15 + b15: + //SEG116 [35] call assertType + //SEG117 [75] phi from main::@15 to assertType [phi:main::@15->assertType] + assertType_from_b15: + //SEG118 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@15->assertType#0] -- register_copy + //SEG119 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@15->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG120 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@15->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG121 [36] phi from main::@15 to main::@16 [phi:main::@15->main::@16] + b16_from_b15: + jmp b16 + //SEG122 main::@16 + b16: + //SEG123 [37] call assertType + //SEG124 [75] phi from main::@16 to assertType [phi:main::@16->assertType] + assertType_from_b16: + //SEG125 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@16->assertType#0] -- register_copy + //SEG126 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@16->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG127 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@16->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG128 [38] phi from main::@16 to main::@17 [phi:main::@16->main::@17] + b17_from_b16: + jmp b17 + //SEG129 main::@17 + b17: + //SEG130 [39] call assertType + //SEG131 [75] phi from main::@17 to assertType [phi:main::@17->assertType] + assertType_from_b17: + //SEG132 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@17->assertType#0] -- register_copy + //SEG133 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@17->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG134 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@17->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG135 [40] phi from main::@17 to main::@18 [phi:main::@17->main::@18] + b18_from_b17: + jmp b18 + //SEG136 main::@18 + b18: + //SEG137 [41] call assertType + //SEG138 [75] phi from main::@18 to assertType [phi:main::@18->assertType] + assertType_from_b18: + //SEG139 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@18->assertType#0] -- register_copy + //SEG140 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@18->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG141 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@18->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG142 [42] phi from main::@18 to main::@19 [phi:main::@18->main::@19] + b19_from_b18: + jmp b19 + //SEG143 main::@19 + b19: + //SEG144 [43] call assertType + //SEG145 [75] phi from main::@19 to assertType [phi:main::@19->assertType] + assertType_from_b19: + //SEG146 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@19->assertType#0] -- register_copy + //SEG147 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@19->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG148 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@19->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG149 [44] phi from main::@19 to main::@20 [phi:main::@19->main::@20] + b20_from_b19: + jmp b20 + //SEG150 main::@20 + b20: + //SEG151 [45] call assertType + //SEG152 [75] phi from main::@20 to assertType [phi:main::@20->assertType] + assertType_from_b20: + //SEG153 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@20->assertType#0] -- register_copy + //SEG154 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@20->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG155 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@20->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG156 [46] phi from main::@20 to main::@21 [phi:main::@20->main::@21] + b21_from_b20: + jmp b21 + //SEG157 main::@21 + b21: + //SEG158 [47] call assertType + //SEG159 [75] phi from main::@21 to assertType [phi:main::@21->assertType] + assertType_from_b21: + //SEG160 [75] phi (byte) idx#79 = (byte) $50 [phi:main::@21->assertType#0] -- vbuz1=vbuc1 + lda #$50 + sta idx + //SEG161 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@21->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG162 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@21->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG163 [48] phi from main::@21 to main::@22 [phi:main::@21->main::@22] + b22_from_b21: + jmp b22 + //SEG164 main::@22 + b22: + //SEG165 [49] call assertType + //SEG166 [75] phi from main::@22 to assertType [phi:main::@22->assertType] + assertType_from_b22: + //SEG167 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@22->assertType#0] -- register_copy + //SEG168 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@22->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG169 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@22->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG170 [50] phi from main::@22 to main::@23 [phi:main::@22->main::@23] + b23_from_b22: + jmp b23 + //SEG171 main::@23 + b23: + //SEG172 [51] call assertType + //SEG173 [75] phi from main::@23 to assertType [phi:main::@23->assertType] + assertType_from_b23: + //SEG174 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@23->assertType#0] -- register_copy + //SEG175 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@23->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG176 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@23->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t1 + jsr assertType + //SEG177 [52] phi from main::@23 to main::@24 [phi:main::@23->main::@24] + b24_from_b23: + jmp b24 + //SEG178 main::@24 + b24: + //SEG179 [53] call assertType + //SEG180 [75] phi from main::@24 to assertType [phi:main::@24->assertType] + assertType_from_b24: + //SEG181 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@24->assertType#0] -- register_copy + //SEG182 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@24->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG183 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@24->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG184 [54] phi from main::@24 to main::@25 [phi:main::@24->main::@25] + b25_from_b24: + jmp b25 + //SEG185 main::@25 + b25: + //SEG186 [55] call assertType + //SEG187 [75] phi from main::@25 to assertType [phi:main::@25->assertType] + assertType_from_b25: + //SEG188 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@25->assertType#0] -- register_copy + //SEG189 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@25->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG190 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@25->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG191 [56] phi from main::@25 to main::@26 [phi:main::@25->main::@26] + b26_from_b25: + jmp b26 + //SEG192 main::@26 + b26: + //SEG193 [57] call assertType + //SEG194 [75] phi from main::@26 to assertType [phi:main::@26->assertType] + assertType_from_b26: + //SEG195 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@26->assertType#0] -- register_copy + //SEG196 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@26->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG197 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@26->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG198 [58] phi from main::@26 to main::@27 [phi:main::@26->main::@27] + b27_from_b26: + jmp b27 + //SEG199 main::@27 + b27: + //SEG200 [59] call assertType + //SEG201 [75] phi from main::@27 to assertType [phi:main::@27->assertType] + assertType_from_b27: + //SEG202 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@27->assertType#0] -- register_copy + //SEG203 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@27->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG204 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@27->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG205 [60] phi from main::@27 to main::@28 [phi:main::@27->main::@28] + b28_from_b27: + jmp b28 + //SEG206 main::@28 + b28: + //SEG207 [61] call assertType + //SEG208 [75] phi from main::@28 to assertType [phi:main::@28->assertType] + assertType_from_b28: + //SEG209 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@28->assertType#0] -- register_copy + //SEG210 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@28->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG211 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@28->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG212 [62] phi from main::@28 to main::@29 [phi:main::@28->main::@29] + b29_from_b28: + jmp b29 + //SEG213 main::@29 + b29: + //SEG214 [63] call assertType + //SEG215 [75] phi from main::@29 to assertType [phi:main::@29->assertType] + assertType_from_b29: + //SEG216 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@29->assertType#0] -- register_copy + //SEG217 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@29->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG218 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@29->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t1 + jsr assertType + //SEG219 [64] phi from main::@29 to main::@30 [phi:main::@29->main::@30] + b30_from_b29: + jmp b30 + //SEG220 main::@30 + b30: + //SEG221 [65] call assertType + //SEG222 [75] phi from main::@30 to assertType [phi:main::@30->assertType] + assertType_from_b30: + //SEG223 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@30->assertType#0] -- register_copy + //SEG224 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@30->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG225 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@30->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG226 [66] phi from main::@30 to main::@31 [phi:main::@30->main::@31] + b31_from_b30: + jmp b31 + //SEG227 main::@31 + b31: + //SEG228 [67] call assertType + //SEG229 [75] phi from main::@31 to assertType [phi:main::@31->assertType] + assertType_from_b31: + //SEG230 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@31->assertType#0] -- register_copy + //SEG231 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@31->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG232 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@31->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG233 [68] phi from main::@31 to main::@32 [phi:main::@31->main::@32] + b32_from_b31: + jmp b32 + //SEG234 main::@32 + b32: + //SEG235 [69] call assertType + //SEG236 [75] phi from main::@32 to assertType [phi:main::@32->assertType] + assertType_from_b32: + //SEG237 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@32->assertType#0] -- register_copy + //SEG238 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@32->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG239 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@32->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG240 [70] phi from main::@32 to main::@33 [phi:main::@32->main::@33] + b33_from_b32: + jmp b33 + //SEG241 main::@33 + b33: + //SEG242 [71] call assertType + //SEG243 [75] phi from main::@33 to assertType [phi:main::@33->assertType] + assertType_from_b33: + //SEG244 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@33->assertType#0] -- register_copy + //SEG245 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@33->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG246 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@33->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t1 + jsr assertType + //SEG247 [72] phi from main::@33 to main::@34 [phi:main::@33->main::@34] + b34_from_b33: + jmp b34 + //SEG248 main::@34 + b34: + //SEG249 [73] call assertType + //SEG250 [75] phi from main::@34 to assertType [phi:main::@34->assertType] + assertType_from_b34: + //SEG251 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@34->assertType#0] -- register_copy + //SEG252 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@34->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG253 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@34->assertType#2] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t1 + jsr assertType + jmp breturn + //SEG254 main::@return + breturn: + //SEG255 [74] return + rts +} +//SEG256 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte zeropage(2) t1, byte zeropage(3) t2) +assertType: { + .label t1 = 2 + .label t2 = 3 + //SEG257 [76] if((byte) assertType::t1#35==(byte) assertType::t2#35) goto assertType::@1 -- vbuz1_eq_vbuz2_then_la1 + lda t1 + cmp t2 + beq b1 + jmp b3 + //SEG258 assertType::@3 + b3: + //SEG259 [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 -- pbuc1_derefidx_vbuz1=vbuc2 + lda #RED + ldy idx + sta $d800,y + jmp b2 + //SEG260 assertType::@2 + b2: + //SEG261 [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 -- pbuc1_derefidx_vbuz1=vbuz2 + lda t1 + ldy idx + sta $400,y + //SEG262 [79] (byte) idx#40 ← ++ (byte) idx#79 -- vbuz1=_inc_vbuz1 + inc idx + jmp breturn + //SEG263 assertType::@return + breturn: + //SEG264 [80] return + rts + //SEG265 assertType::@1 + b1: + //SEG266 [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuz1=vbuc2 + lda #GREEN + ldy idx + sta $d800,y + jmp b2 +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 [ assertType::t1#35 idx#79 ] ( main:2::assertType:5 [ assertType::t1#35 idx#79 ] main:2::assertType:7 [ assertType::t1#35 idx#79 ] main:2::assertType:9 [ assertType::t1#35 idx#79 ] main:2::assertType:11 [ assertType::t1#35 idx#79 ] main:2::assertType:13 [ assertType::t1#35 idx#79 ] main:2::assertType:15 [ assertType::t1#35 idx#79 ] main:2::assertType:17 [ assertType::t1#35 idx#79 ] main:2::assertType:19 [ assertType::t1#35 idx#79 ] main:2::assertType:21 [ assertType::t1#35 idx#79 ] main:2::assertType:23 [ assertType::t1#35 idx#79 ] main:2::assertType:25 [ assertType::t1#35 idx#79 ] main:2::assertType:27 [ assertType::t1#35 idx#79 ] main:2::assertType:29 [ assertType::t1#35 idx#79 ] main:2::assertType:31 [ assertType::t1#35 idx#79 ] main:2::assertType:33 [ assertType::t1#35 idx#79 ] main:2::assertType:35 [ assertType::t1#35 idx#79 ] main:2::assertType:37 [ assertType::t1#35 idx#79 ] main:2::assertType:39 [ assertType::t1#35 idx#79 ] main:2::assertType:41 [ assertType::t1#35 idx#79 ] main:2::assertType:43 [ assertType::t1#35 idx#79 ] main:2::assertType:45 [ assertType::t1#35 idx#79 ] main:2::assertType:47 [ assertType::t1#35 idx#79 ] main:2::assertType:49 [ assertType::t1#35 idx#79 ] main:2::assertType:51 [ assertType::t1#35 idx#79 ] main:2::assertType:53 [ assertType::t1#35 idx#79 ] main:2::assertType:55 [ assertType::t1#35 idx#79 ] main:2::assertType:57 [ assertType::t1#35 idx#79 ] main:2::assertType:59 [ assertType::t1#35 idx#79 ] main:2::assertType:61 [ assertType::t1#35 idx#79 ] main:2::assertType:63 [ assertType::t1#35 idx#79 ] main:2::assertType:65 [ assertType::t1#35 idx#79 ] main:2::assertType:67 [ assertType::t1#35 idx#79 ] main:2::assertType:69 [ assertType::t1#35 idx#79 ] main:2::assertType:71 [ assertType::t1#35 idx#79 ] main:2::assertType:73 [ assertType::t1#35 idx#79 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ assertType::t1#35 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ idx#79 idx#40 ] +Statement [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 [ idx#79 ] ( main:2::assertType:5 [ idx#79 ] main:2::assertType:7 [ idx#79 ] main:2::assertType:9 [ idx#79 ] main:2::assertType:11 [ idx#79 ] main:2::assertType:13 [ idx#79 ] main:2::assertType:15 [ idx#79 ] main:2::assertType:17 [ idx#79 ] main:2::assertType:19 [ idx#79 ] main:2::assertType:21 [ idx#79 ] main:2::assertType:23 [ idx#79 ] main:2::assertType:25 [ idx#79 ] main:2::assertType:27 [ idx#79 ] main:2::assertType:29 [ idx#79 ] main:2::assertType:31 [ idx#79 ] main:2::assertType:33 [ idx#79 ] main:2::assertType:35 [ idx#79 ] main:2::assertType:37 [ idx#79 ] main:2::assertType:39 [ idx#79 ] main:2::assertType:41 [ idx#79 ] main:2::assertType:43 [ idx#79 ] main:2::assertType:45 [ idx#79 ] main:2::assertType:47 [ idx#79 ] main:2::assertType:49 [ idx#79 ] main:2::assertType:51 [ idx#79 ] main:2::assertType:53 [ idx#79 ] main:2::assertType:55 [ idx#79 ] main:2::assertType:57 [ idx#79 ] main:2::assertType:59 [ idx#79 ] main:2::assertType:61 [ idx#79 ] main:2::assertType:63 [ idx#79 ] main:2::assertType:65 [ idx#79 ] main:2::assertType:67 [ idx#79 ] main:2::assertType:69 [ idx#79 ] main:2::assertType:71 [ idx#79 ] main:2::assertType:73 [ idx#79 ] ) always clobbers reg byte a +Statement [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 [ assertType::t1#35 idx#79 ] ( main:2::assertType:5 [ assertType::t1#35 idx#79 ] main:2::assertType:7 [ assertType::t1#35 idx#79 ] main:2::assertType:9 [ assertType::t1#35 idx#79 ] main:2::assertType:11 [ assertType::t1#35 idx#79 ] main:2::assertType:13 [ assertType::t1#35 idx#79 ] main:2::assertType:15 [ assertType::t1#35 idx#79 ] main:2::assertType:17 [ assertType::t1#35 idx#79 ] main:2::assertType:19 [ assertType::t1#35 idx#79 ] main:2::assertType:21 [ assertType::t1#35 idx#79 ] main:2::assertType:23 [ assertType::t1#35 idx#79 ] main:2::assertType:25 [ assertType::t1#35 idx#79 ] main:2::assertType:27 [ assertType::t1#35 idx#79 ] main:2::assertType:29 [ assertType::t1#35 idx#79 ] main:2::assertType:31 [ assertType::t1#35 idx#79 ] main:2::assertType:33 [ assertType::t1#35 idx#79 ] main:2::assertType:35 [ assertType::t1#35 idx#79 ] main:2::assertType:37 [ assertType::t1#35 idx#79 ] main:2::assertType:39 [ assertType::t1#35 idx#79 ] main:2::assertType:41 [ assertType::t1#35 idx#79 ] main:2::assertType:43 [ assertType::t1#35 idx#79 ] main:2::assertType:45 [ assertType::t1#35 idx#79 ] main:2::assertType:47 [ assertType::t1#35 idx#79 ] main:2::assertType:49 [ assertType::t1#35 idx#79 ] main:2::assertType:51 [ assertType::t1#35 idx#79 ] main:2::assertType:53 [ assertType::t1#35 idx#79 ] main:2::assertType:55 [ assertType::t1#35 idx#79 ] main:2::assertType:57 [ assertType::t1#35 idx#79 ] main:2::assertType:59 [ assertType::t1#35 idx#79 ] main:2::assertType:61 [ assertType::t1#35 idx#79 ] main:2::assertType:63 [ assertType::t1#35 idx#79 ] main:2::assertType:65 [ assertType::t1#35 idx#79 ] main:2::assertType:67 [ assertType::t1#35 idx#79 ] main:2::assertType:69 [ assertType::t1#35 idx#79 ] main:2::assertType:71 [ assertType::t1#35 idx#79 ] main:2::assertType:73 [ assertType::t1#35 idx#79 ] ) always clobbers reg byte a +Statement [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 [ assertType::t1#35 idx#79 ] ( main:2::assertType:5 [ assertType::t1#35 idx#79 ] main:2::assertType:7 [ assertType::t1#35 idx#79 ] main:2::assertType:9 [ assertType::t1#35 idx#79 ] main:2::assertType:11 [ assertType::t1#35 idx#79 ] main:2::assertType:13 [ assertType::t1#35 idx#79 ] main:2::assertType:15 [ assertType::t1#35 idx#79 ] main:2::assertType:17 [ assertType::t1#35 idx#79 ] main:2::assertType:19 [ assertType::t1#35 idx#79 ] main:2::assertType:21 [ assertType::t1#35 idx#79 ] main:2::assertType:23 [ assertType::t1#35 idx#79 ] main:2::assertType:25 [ assertType::t1#35 idx#79 ] main:2::assertType:27 [ assertType::t1#35 idx#79 ] main:2::assertType:29 [ assertType::t1#35 idx#79 ] main:2::assertType:31 [ assertType::t1#35 idx#79 ] main:2::assertType:33 [ assertType::t1#35 idx#79 ] main:2::assertType:35 [ assertType::t1#35 idx#79 ] main:2::assertType:37 [ assertType::t1#35 idx#79 ] main:2::assertType:39 [ assertType::t1#35 idx#79 ] main:2::assertType:41 [ assertType::t1#35 idx#79 ] main:2::assertType:43 [ assertType::t1#35 idx#79 ] main:2::assertType:45 [ assertType::t1#35 idx#79 ] main:2::assertType:47 [ assertType::t1#35 idx#79 ] main:2::assertType:49 [ assertType::t1#35 idx#79 ] main:2::assertType:51 [ assertType::t1#35 idx#79 ] main:2::assertType:53 [ assertType::t1#35 idx#79 ] main:2::assertType:55 [ assertType::t1#35 idx#79 ] main:2::assertType:57 [ assertType::t1#35 idx#79 ] main:2::assertType:59 [ assertType::t1#35 idx#79 ] main:2::assertType:61 [ assertType::t1#35 idx#79 ] main:2::assertType:63 [ assertType::t1#35 idx#79 ] main:2::assertType:65 [ assertType::t1#35 idx#79 ] main:2::assertType:67 [ assertType::t1#35 idx#79 ] main:2::assertType:69 [ assertType::t1#35 idx#79 ] main:2::assertType:71 [ assertType::t1#35 idx#79 ] main:2::assertType:73 [ assertType::t1#35 idx#79 ] ) always clobbers reg byte a +Statement [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 [ idx#79 ] ( main:2::assertType:5 [ idx#79 ] main:2::assertType:7 [ idx#79 ] main:2::assertType:9 [ idx#79 ] main:2::assertType:11 [ idx#79 ] main:2::assertType:13 [ idx#79 ] main:2::assertType:15 [ idx#79 ] main:2::assertType:17 [ idx#79 ] main:2::assertType:19 [ idx#79 ] main:2::assertType:21 [ idx#79 ] main:2::assertType:23 [ idx#79 ] main:2::assertType:25 [ idx#79 ] main:2::assertType:27 [ idx#79 ] main:2::assertType:29 [ idx#79 ] main:2::assertType:31 [ idx#79 ] main:2::assertType:33 [ idx#79 ] main:2::assertType:35 [ idx#79 ] main:2::assertType:37 [ idx#79 ] main:2::assertType:39 [ idx#79 ] main:2::assertType:41 [ idx#79 ] main:2::assertType:43 [ idx#79 ] main:2::assertType:45 [ idx#79 ] main:2::assertType:47 [ idx#79 ] main:2::assertType:49 [ idx#79 ] main:2::assertType:51 [ idx#79 ] main:2::assertType:53 [ idx#79 ] main:2::assertType:55 [ idx#79 ] main:2::assertType:57 [ idx#79 ] main:2::assertType:59 [ idx#79 ] main:2::assertType:61 [ idx#79 ] main:2::assertType:63 [ idx#79 ] main:2::assertType:65 [ idx#79 ] main:2::assertType:67 [ idx#79 ] main:2::assertType:69 [ idx#79 ] main:2::assertType:71 [ idx#79 ] main:2::assertType:73 [ idx#79 ] ) always clobbers reg byte a +Statement [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 [ assertType::t1#35 idx#79 ] ( main:2::assertType:5 [ assertType::t1#35 idx#79 ] main:2::assertType:7 [ assertType::t1#35 idx#79 ] main:2::assertType:9 [ assertType::t1#35 idx#79 ] main:2::assertType:11 [ assertType::t1#35 idx#79 ] main:2::assertType:13 [ assertType::t1#35 idx#79 ] main:2::assertType:15 [ assertType::t1#35 idx#79 ] main:2::assertType:17 [ assertType::t1#35 idx#79 ] main:2::assertType:19 [ assertType::t1#35 idx#79 ] main:2::assertType:21 [ assertType::t1#35 idx#79 ] main:2::assertType:23 [ assertType::t1#35 idx#79 ] main:2::assertType:25 [ assertType::t1#35 idx#79 ] main:2::assertType:27 [ assertType::t1#35 idx#79 ] main:2::assertType:29 [ assertType::t1#35 idx#79 ] main:2::assertType:31 [ assertType::t1#35 idx#79 ] main:2::assertType:33 [ assertType::t1#35 idx#79 ] main:2::assertType:35 [ assertType::t1#35 idx#79 ] main:2::assertType:37 [ assertType::t1#35 idx#79 ] main:2::assertType:39 [ assertType::t1#35 idx#79 ] main:2::assertType:41 [ assertType::t1#35 idx#79 ] main:2::assertType:43 [ assertType::t1#35 idx#79 ] main:2::assertType:45 [ assertType::t1#35 idx#79 ] main:2::assertType:47 [ assertType::t1#35 idx#79 ] main:2::assertType:49 [ assertType::t1#35 idx#79 ] main:2::assertType:51 [ assertType::t1#35 idx#79 ] main:2::assertType:53 [ assertType::t1#35 idx#79 ] main:2::assertType:55 [ assertType::t1#35 idx#79 ] main:2::assertType:57 [ assertType::t1#35 idx#79 ] main:2::assertType:59 [ assertType::t1#35 idx#79 ] main:2::assertType:61 [ assertType::t1#35 idx#79 ] main:2::assertType:63 [ assertType::t1#35 idx#79 ] main:2::assertType:65 [ assertType::t1#35 idx#79 ] main:2::assertType:67 [ assertType::t1#35 idx#79 ] main:2::assertType:69 [ assertType::t1#35 idx#79 ] main:2::assertType:71 [ assertType::t1#35 idx#79 ] main:2::assertType:73 [ assertType::t1#35 idx#79 ] ) always clobbers reg byte a +Potential registers zp ZP_BYTE:2 [ assertType::t1#35 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ assertType::t2#35 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ idx#79 idx#40 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [] 15.4: zp ZP_BYTE:4 [ idx#79 idx#40 ] +Uplift Scope [assertType] 2: zp ZP_BYTE:3 [ assertType::t2#35 ] 1: zp ZP_BYTE:2 [ assertType::t1#35 ] +Uplift Scope [main] + +Uplifting [] best 739 combination reg byte x [ idx#79 idx#40 ] +Uplifting [assertType] best 632 combination zp ZP_BYTE:3 [ assertType::t2#35 ] reg byte y [ assertType::t1#35 ] +Uplifting [main] best 632 combination +Attempting to uplift remaining variables inzp ZP_BYTE:3 [ assertType::t2#35 ] +Uplifting [assertType] best 632 combination zp ZP_BYTE:3 [ assertType::t2#35 ] +Allocated (was zp ZP_BYTE:3) zp ZP_BYTE:2 [ assertType::t2#35 ] + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests conversion of numbers to correct int types +// See https://gitlab.com/camelot/kickc/issues/181 +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_SIGNED_DWORD = 6 + .const TYPEID_BYTE = 1 + .const TYPEID_WORD = 3 + .const TYPEID_DWORD = 5 + .const RED = 2 + .const GREEN = 5 +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + //SEG11 [5] call assertType + //SEG12 [75] phi from main to assertType [phi:main->assertType] + assertType_from_main: + //SEG13 [75] phi (byte) idx#79 = (byte) 0 [phi:main->assertType#0] -- vbuxx=vbuc1 + ldx #0 + //SEG14 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_BYTE [phi:main->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG15 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_BYTE [phi:main->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_BYTE + jsr assertType + //SEG16 [6] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + jmp b1 + //SEG17 main::@1 + b1: + //SEG18 [7] call assertType + //SEG19 [75] phi from main::@1 to assertType [phi:main::@1->assertType] + assertType_from_b1: + //SEG20 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@1->assertType#0] -- register_copy + //SEG21 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG22 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@1->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG23 [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + b2_from_b1: + jmp b2 + //SEG24 main::@2 + b2: + //SEG25 [9] call assertType + //SEG26 [75] phi from main::@2 to assertType [phi:main::@2->assertType] + assertType_from_b2: + //SEG27 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@2->assertType#0] -- register_copy + //SEG28 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG29 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@2->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG30 [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + b3_from_b2: + jmp b3 + //SEG31 main::@3 + b3: + //SEG32 [11] call assertType + //SEG33 [75] phi from main::@3 to assertType [phi:main::@3->assertType] + assertType_from_b3: + //SEG34 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@3->assertType#0] -- register_copy + //SEG35 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG36 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@3->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG37 [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + b4_from_b3: + jmp b4 + //SEG38 main::@4 + b4: + //SEG39 [13] call assertType + //SEG40 [75] phi from main::@4 to assertType [phi:main::@4->assertType] + assertType_from_b4: + //SEG41 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@4->assertType#0] -- register_copy + //SEG42 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG43 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@4->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_WORD + jsr assertType + //SEG44 [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + b5_from_b4: + jmp b5 + //SEG45 main::@5 + b5: + //SEG46 [15] call assertType + //SEG47 [75] phi from main::@5 to assertType [phi:main::@5->assertType] + assertType_from_b5: + //SEG48 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@5->assertType#0] -- register_copy + //SEG49 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG50 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@5->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG51 [16] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + b6_from_b5: + jmp b6 + //SEG52 main::@6 + b6: + //SEG53 [17] call assertType + //SEG54 [75] phi from main::@6 to assertType [phi:main::@6->assertType] + assertType_from_b6: + //SEG55 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@6->assertType#0] -- register_copy + //SEG56 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG57 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@6->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG58 [18] phi from main::@6 to main::@7 [phi:main::@6->main::@7] + b7_from_b6: + jmp b7 + //SEG59 main::@7 + b7: + //SEG60 [19] call assertType + //SEG61 [75] phi from main::@7 to assertType [phi:main::@7->assertType] + assertType_from_b7: + //SEG62 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@7->assertType#0] -- register_copy + //SEG63 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG64 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@7->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG65 [20] phi from main::@7 to main::@8 [phi:main::@7->main::@8] + b8_from_b7: + jmp b8 + //SEG66 main::@8 + b8: + //SEG67 [21] call assertType + //SEG68 [75] phi from main::@8 to assertType [phi:main::@8->assertType] + assertType_from_b8: + //SEG69 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@8->assertType#0] -- register_copy + //SEG70 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG71 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@8->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG72 [22] phi from main::@8 to main::@9 [phi:main::@8->main::@9] + b9_from_b8: + jmp b9 + //SEG73 main::@9 + b9: + //SEG74 [23] call assertType + //SEG75 [75] phi from main::@9 to assertType [phi:main::@9->assertType] + assertType_from_b9: + //SEG76 [75] phi (byte) idx#79 = (byte) $28 [phi:main::@9->assertType#0] -- vbuxx=vbuc1 + ldx #$28 + //SEG77 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG78 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@9->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG79 [24] phi from main::@9 to main::@10 [phi:main::@9->main::@10] + b10_from_b9: + jmp b10 + //SEG80 main::@10 + b10: + //SEG81 [25] call assertType + //SEG82 [75] phi from main::@10 to assertType [phi:main::@10->assertType] + assertType_from_b10: + //SEG83 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@10->assertType#0] -- register_copy + //SEG84 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG85 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@10->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG86 [26] phi from main::@10 to main::@11 [phi:main::@10->main::@11] + b11_from_b10: + jmp b11 + //SEG87 main::@11 + b11: + //SEG88 [27] call assertType + //SEG89 [75] phi from main::@11 to assertType [phi:main::@11->assertType] + assertType_from_b11: + //SEG90 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@11->assertType#0] -- register_copy + //SEG91 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG92 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@11->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG93 [28] phi from main::@11 to main::@12 [phi:main::@11->main::@12] + b12_from_b11: + jmp b12 + //SEG94 main::@12 + b12: + //SEG95 [29] call assertType + //SEG96 [75] phi from main::@12 to assertType [phi:main::@12->assertType] + assertType_from_b12: + //SEG97 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@12->assertType#0] -- register_copy + //SEG98 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG99 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@12->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG100 [30] phi from main::@12 to main::@13 [phi:main::@12->main::@13] + b13_from_b12: + jmp b13 + //SEG101 main::@13 + b13: + //SEG102 [31] call assertType + //SEG103 [75] phi from main::@13 to assertType [phi:main::@13->assertType] + assertType_from_b13: + //SEG104 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@13->assertType#0] -- register_copy + //SEG105 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG106 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@13->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG107 [32] phi from main::@13 to main::@14 [phi:main::@13->main::@14] + b14_from_b13: + jmp b14 + //SEG108 main::@14 + b14: + //SEG109 [33] call assertType + //SEG110 [75] phi from main::@14 to assertType [phi:main::@14->assertType] + assertType_from_b14: + //SEG111 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@14->assertType#0] -- register_copy + //SEG112 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG113 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@14->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG114 [34] phi from main::@14 to main::@15 [phi:main::@14->main::@15] + b15_from_b14: + jmp b15 + //SEG115 main::@15 + b15: + //SEG116 [35] call assertType + //SEG117 [75] phi from main::@15 to assertType [phi:main::@15->assertType] + assertType_from_b15: + //SEG118 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@15->assertType#0] -- register_copy + //SEG119 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@15->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG120 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@15->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG121 [36] phi from main::@15 to main::@16 [phi:main::@15->main::@16] + b16_from_b15: + jmp b16 + //SEG122 main::@16 + b16: + //SEG123 [37] call assertType + //SEG124 [75] phi from main::@16 to assertType [phi:main::@16->assertType] + assertType_from_b16: + //SEG125 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@16->assertType#0] -- register_copy + //SEG126 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@16->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG127 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@16->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG128 [38] phi from main::@16 to main::@17 [phi:main::@16->main::@17] + b17_from_b16: + jmp b17 + //SEG129 main::@17 + b17: + //SEG130 [39] call assertType + //SEG131 [75] phi from main::@17 to assertType [phi:main::@17->assertType] + assertType_from_b17: + //SEG132 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@17->assertType#0] -- register_copy + //SEG133 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@17->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG134 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@17->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG135 [40] phi from main::@17 to main::@18 [phi:main::@17->main::@18] + b18_from_b17: + jmp b18 + //SEG136 main::@18 + b18: + //SEG137 [41] call assertType + //SEG138 [75] phi from main::@18 to assertType [phi:main::@18->assertType] + assertType_from_b18: + //SEG139 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@18->assertType#0] -- register_copy + //SEG140 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@18->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG141 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@18->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG142 [42] phi from main::@18 to main::@19 [phi:main::@18->main::@19] + b19_from_b18: + jmp b19 + //SEG143 main::@19 + b19: + //SEG144 [43] call assertType + //SEG145 [75] phi from main::@19 to assertType [phi:main::@19->assertType] + assertType_from_b19: + //SEG146 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@19->assertType#0] -- register_copy + //SEG147 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@19->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG148 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@19->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG149 [44] phi from main::@19 to main::@20 [phi:main::@19->main::@20] + b20_from_b19: + jmp b20 + //SEG150 main::@20 + b20: + //SEG151 [45] call assertType + //SEG152 [75] phi from main::@20 to assertType [phi:main::@20->assertType] + assertType_from_b20: + //SEG153 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@20->assertType#0] -- register_copy + //SEG154 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@20->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG155 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@20->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG156 [46] phi from main::@20 to main::@21 [phi:main::@20->main::@21] + b21_from_b20: + jmp b21 + //SEG157 main::@21 + b21: + //SEG158 [47] call assertType + //SEG159 [75] phi from main::@21 to assertType [phi:main::@21->assertType] + assertType_from_b21: + //SEG160 [75] phi (byte) idx#79 = (byte) $50 [phi:main::@21->assertType#0] -- vbuxx=vbuc1 + ldx #$50 + //SEG161 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@21->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG162 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@21->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG163 [48] phi from main::@21 to main::@22 [phi:main::@21->main::@22] + b22_from_b21: + jmp b22 + //SEG164 main::@22 + b22: + //SEG165 [49] call assertType + //SEG166 [75] phi from main::@22 to assertType [phi:main::@22->assertType] + assertType_from_b22: + //SEG167 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@22->assertType#0] -- register_copy + //SEG168 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@22->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG169 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@22->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG170 [50] phi from main::@22 to main::@23 [phi:main::@22->main::@23] + b23_from_b22: + jmp b23 + //SEG171 main::@23 + b23: + //SEG172 [51] call assertType + //SEG173 [75] phi from main::@23 to assertType [phi:main::@23->assertType] + assertType_from_b23: + //SEG174 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@23->assertType#0] -- register_copy + //SEG175 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@23->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG176 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@23->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_BYTE + jsr assertType + //SEG177 [52] phi from main::@23 to main::@24 [phi:main::@23->main::@24] + b24_from_b23: + jmp b24 + //SEG178 main::@24 + b24: + //SEG179 [53] call assertType + //SEG180 [75] phi from main::@24 to assertType [phi:main::@24->assertType] + assertType_from_b24: + //SEG181 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@24->assertType#0] -- register_copy + //SEG182 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@24->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG183 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@24->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG184 [54] phi from main::@24 to main::@25 [phi:main::@24->main::@25] + b25_from_b24: + jmp b25 + //SEG185 main::@25 + b25: + //SEG186 [55] call assertType + //SEG187 [75] phi from main::@25 to assertType [phi:main::@25->assertType] + assertType_from_b25: + //SEG188 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@25->assertType#0] -- register_copy + //SEG189 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@25->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG190 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@25->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG191 [56] phi from main::@25 to main::@26 [phi:main::@25->main::@26] + b26_from_b25: + jmp b26 + //SEG192 main::@26 + b26: + //SEG193 [57] call assertType + //SEG194 [75] phi from main::@26 to assertType [phi:main::@26->assertType] + assertType_from_b26: + //SEG195 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@26->assertType#0] -- register_copy + //SEG196 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@26->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG197 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@26->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG198 [58] phi from main::@26 to main::@27 [phi:main::@26->main::@27] + b27_from_b26: + jmp b27 + //SEG199 main::@27 + b27: + //SEG200 [59] call assertType + //SEG201 [75] phi from main::@27 to assertType [phi:main::@27->assertType] + assertType_from_b27: + //SEG202 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@27->assertType#0] -- register_copy + //SEG203 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@27->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG204 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@27->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG205 [60] phi from main::@27 to main::@28 [phi:main::@27->main::@28] + b28_from_b27: + jmp b28 + //SEG206 main::@28 + b28: + //SEG207 [61] call assertType + //SEG208 [75] phi from main::@28 to assertType [phi:main::@28->assertType] + assertType_from_b28: + //SEG209 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@28->assertType#0] -- register_copy + //SEG210 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@28->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG211 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@28->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG212 [62] phi from main::@28 to main::@29 [phi:main::@28->main::@29] + b29_from_b28: + jmp b29 + //SEG213 main::@29 + b29: + //SEG214 [63] call assertType + //SEG215 [75] phi from main::@29 to assertType [phi:main::@29->assertType] + assertType_from_b29: + //SEG216 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@29->assertType#0] -- register_copy + //SEG217 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@29->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG218 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@29->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_WORD + jsr assertType + //SEG219 [64] phi from main::@29 to main::@30 [phi:main::@29->main::@30] + b30_from_b29: + jmp b30 + //SEG220 main::@30 + b30: + //SEG221 [65] call assertType + //SEG222 [75] phi from main::@30 to assertType [phi:main::@30->assertType] + assertType_from_b30: + //SEG223 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@30->assertType#0] -- register_copy + //SEG224 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@30->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG225 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@30->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG226 [66] phi from main::@30 to main::@31 [phi:main::@30->main::@31] + b31_from_b30: + jmp b31 + //SEG227 main::@31 + b31: + //SEG228 [67] call assertType + //SEG229 [75] phi from main::@31 to assertType [phi:main::@31->assertType] + assertType_from_b31: + //SEG230 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@31->assertType#0] -- register_copy + //SEG231 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@31->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG232 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@31->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG233 [68] phi from main::@31 to main::@32 [phi:main::@31->main::@32] + b32_from_b31: + jmp b32 + //SEG234 main::@32 + b32: + //SEG235 [69] call assertType + //SEG236 [75] phi from main::@32 to assertType [phi:main::@32->assertType] + assertType_from_b32: + //SEG237 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@32->assertType#0] -- register_copy + //SEG238 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@32->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG239 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@32->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG240 [70] phi from main::@32 to main::@33 [phi:main::@32->main::@33] + b33_from_b32: + jmp b33 + //SEG241 main::@33 + b33: + //SEG242 [71] call assertType + //SEG243 [75] phi from main::@33 to assertType [phi:main::@33->assertType] + assertType_from_b33: + //SEG244 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@33->assertType#0] -- register_copy + //SEG245 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@33->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG246 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@33->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_DWORD + jsr assertType + //SEG247 [72] phi from main::@33 to main::@34 [phi:main::@33->main::@34] + b34_from_b33: + jmp b34 + //SEG248 main::@34 + b34: + //SEG249 [73] call assertType + //SEG250 [75] phi from main::@34 to assertType [phi:main::@34->assertType] + assertType_from_b34: + //SEG251 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@34->assertType#0] -- register_copy + //SEG252 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@34->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG253 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@34->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + jmp breturn + //SEG254 main::@return + breturn: + //SEG255 [74] return + rts +} +//SEG256 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(2) t2) +assertType: { + .label t2 = 2 + //SEG257 [76] if((byte) assertType::t1#35==(byte) assertType::t2#35) goto assertType::@1 -- vbuyy_eq_vbuz1_then_la1 + tya + cmp t2 + beq b1 + jmp b3 + //SEG258 assertType::@3 + b3: + //SEG259 [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #RED + sta $d800,x + jmp b2 + //SEG260 assertType::@2 + b2: + //SEG261 [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 -- pbuc1_derefidx_vbuxx=vbuyy + tya + sta $400,x + //SEG262 [79] (byte) idx#40 ← ++ (byte) idx#79 -- vbuxx=_inc_vbuxx + inx + jmp breturn + //SEG263 assertType::@return + breturn: + //SEG264 [80] return + rts + //SEG265 assertType::@1 + b1: + //SEG266 [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #GREEN + sta $d800,x + jmp b2 +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b2 +Removing instruction jmp b3 +Removing instruction jmp b4 +Removing instruction jmp b5 +Removing instruction jmp b6 +Removing instruction jmp b7 +Removing instruction jmp b8 +Removing instruction jmp b9 +Removing instruction jmp b10 +Removing instruction jmp b11 +Removing instruction jmp b12 +Removing instruction jmp b13 +Removing instruction jmp b14 +Removing instruction jmp b15 +Removing instruction jmp b16 +Removing instruction jmp b17 +Removing instruction jmp b18 +Removing instruction jmp b19 +Removing instruction jmp b20 +Removing instruction jmp b21 +Removing instruction jmp b22 +Removing instruction jmp b23 +Removing instruction jmp b24 +Removing instruction jmp b25 +Removing instruction jmp b26 +Removing instruction jmp b27 +Removing instruction jmp b28 +Removing instruction jmp b29 +Removing instruction jmp b30 +Removing instruction jmp b31 +Removing instruction jmp b32 +Removing instruction jmp b33 +Removing instruction jmp b34 +Removing instruction jmp breturn +Removing instruction jmp b3 +Removing instruction jmp b2 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing instruction ldy #TYPEID_SIGNED_BYTE with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_WORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_SIGNED_DWORD with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_BYTE with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_WORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Replacing instruction ldy #TYPEID_DWORD with TAY +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_main: +Removing instruction assertType_from_b1: +Removing instruction b2_from_b1: +Removing instruction assertType_from_b2: +Removing instruction b3_from_b2: +Removing instruction assertType_from_b3: +Removing instruction b4_from_b3: +Removing instruction assertType_from_b4: +Removing instruction b5_from_b4: +Removing instruction assertType_from_b5: +Removing instruction b6_from_b5: +Removing instruction assertType_from_b6: +Removing instruction b7_from_b6: +Removing instruction assertType_from_b7: +Removing instruction b8_from_b7: +Removing instruction assertType_from_b8: +Removing instruction b9_from_b8: +Removing instruction assertType_from_b9: +Removing instruction b10_from_b9: +Removing instruction assertType_from_b10: +Removing instruction b11_from_b10: +Removing instruction assertType_from_b11: +Removing instruction b12_from_b11: +Removing instruction assertType_from_b12: +Removing instruction b13_from_b12: +Removing instruction assertType_from_b13: +Removing instruction b14_from_b13: +Removing instruction assertType_from_b14: +Removing instruction b15_from_b14: +Removing instruction assertType_from_b15: +Removing instruction b16_from_b15: +Removing instruction assertType_from_b16: +Removing instruction b17_from_b16: +Removing instruction assertType_from_b17: +Removing instruction b18_from_b17: +Removing instruction assertType_from_b18: +Removing instruction b19_from_b18: +Removing instruction assertType_from_b19: +Removing instruction b20_from_b19: +Removing instruction assertType_from_b20: +Removing instruction b21_from_b20: +Removing instruction assertType_from_b21: +Removing instruction b22_from_b21: +Removing instruction assertType_from_b22: +Removing instruction b23_from_b22: +Removing instruction assertType_from_b23: +Removing instruction b24_from_b23: +Removing instruction assertType_from_b24: +Removing instruction b25_from_b24: +Removing instruction assertType_from_b25: +Removing instruction b26_from_b25: +Removing instruction assertType_from_b26: +Removing instruction b27_from_b26: +Removing instruction assertType_from_b27: +Removing instruction b28_from_b27: +Removing instruction assertType_from_b28: +Removing instruction b29_from_b28: +Removing instruction assertType_from_b29: +Removing instruction b30_from_b29: +Removing instruction assertType_from_b30: +Removing instruction b31_from_b30: +Removing instruction assertType_from_b31: +Removing instruction b32_from_b31: +Removing instruction assertType_from_b32: +Removing instruction b33_from_b32: +Removing instruction assertType_from_b33: +Removing instruction b34_from_b33: +Removing instruction assertType_from_b34: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction assertType_from_main: +Removing instruction b1: +Removing instruction b2: +Removing instruction b3: +Removing instruction b4: +Removing instruction b5: +Removing instruction b6: +Removing instruction b7: +Removing instruction b8: +Removing instruction b9: +Removing instruction b10: +Removing instruction b11: +Removing instruction b12: +Removing instruction b13: +Removing instruction b14: +Removing instruction b15: +Removing instruction b16: +Removing instruction b17: +Removing instruction b18: +Removing instruction b19: +Removing instruction b20: +Removing instruction b21: +Removing instruction b22: +Removing instruction b23: +Removing instruction b24: +Removing instruction b25: +Removing instruction b26: +Removing instruction b27: +Removing instruction b28: +Removing instruction b29: +Removing instruction b30: +Removing instruction b31: +Removing instruction b32: +Removing instruction b33: +Removing instruction b34: +Removing instruction breturn: +Removing instruction b3: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte*) COLS +(byte) GREEN +(const byte) GREEN#0 GREEN = (byte) 5 +(byte) RED +(const byte) RED#0 RED = (byte) 2 +(byte*) SCREEN +(const byte) TYPEID_BYTE TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#35 reg byte y 1.0 +(byte) assertType::t2 +(byte) assertType::t2#35 t2 zp ZP_BYTE:2 2.0 +(byte) idx +(byte) idx#40 reg byte x 0.9999999999999993 +(byte) idx#79 reg byte x 14.400000000000007 +(void()) main() +(label) main::@1 +(label) main::@10 +(label) main::@11 +(label) main::@12 +(label) main::@13 +(label) main::@14 +(label) main::@15 +(label) main::@16 +(label) main::@17 +(label) main::@18 +(label) main::@19 +(label) main::@2 +(label) main::@20 +(label) main::@21 +(label) main::@22 +(label) main::@23 +(label) main::@24 +(label) main::@25 +(label) main::@26 +(label) main::@27 +(label) main::@28 +(label) main::@29 +(label) main::@3 +(label) main::@30 +(label) main::@31 +(label) main::@32 +(label) main::@33 +(label) main::@34 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@8 +(label) main::@9 +(label) main::@return + +reg byte y [ assertType::t1#35 ] +zp ZP_BYTE:2 [ assertType::t2#35 ] +reg byte x [ idx#79 idx#40 ] + + +FINAL ASSEMBLER +Score: 506 + +//SEG0 File Comments +// Tests conversion of numbers to correct int types +// See https://gitlab.com/camelot/kickc/issues/181 +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels + .const TYPEID_SIGNED_BYTE = 2 + .const TYPEID_SIGNED_WORD = 4 + .const TYPEID_SIGNED_DWORD = 6 + .const TYPEID_BYTE = 1 + .const TYPEID_WORD = 3 + .const TYPEID_DWORD = 5 + .const RED = 2 + .const GREEN = 5 +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + //SEG11 [5] call assertType + //SEG12 [75] phi from main to assertType [phi:main->assertType] + //SEG13 [75] phi (byte) idx#79 = (byte) 0 [phi:main->assertType#0] -- vbuxx=vbuc1 + ldx #0 + //SEG14 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_BYTE [phi:main->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_BYTE + sta assertType.t2 + //SEG15 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_BYTE [phi:main->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG16 [6] phi from main to main::@1 [phi:main->main::@1] + //SEG17 main::@1 + //SEG18 [7] call assertType + //SEG19 [75] phi from main::@1 to assertType [phi:main::@1->assertType] + //SEG20 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@1->assertType#0] -- register_copy + //SEG21 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@1->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG22 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@1->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG23 [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2] + //SEG24 main::@2 + //SEG25 [9] call assertType + //SEG26 [75] phi from main::@2 to assertType [phi:main::@2->assertType] + //SEG27 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@2->assertType#0] -- register_copy + //SEG28 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@2->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG29 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@2->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG30 [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + //SEG31 main::@3 + //SEG32 [11] call assertType + //SEG33 [75] phi from main::@3 to assertType [phi:main::@3->assertType] + //SEG34 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@3->assertType#0] -- register_copy + //SEG35 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@3->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG36 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@3->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG37 [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4] + //SEG38 main::@4 + //SEG39 [13] call assertType + //SEG40 [75] phi from main::@4 to assertType [phi:main::@4->assertType] + //SEG41 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@4->assertType#0] -- register_copy + //SEG42 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@4->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_WORD + sta assertType.t2 + //SEG43 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_WORD [phi:main::@4->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG44 [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + //SEG45 main::@5 + //SEG46 [15] call assertType + //SEG47 [75] phi from main::@5 to assertType [phi:main::@5->assertType] + //SEG48 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@5->assertType#0] -- register_copy + //SEG49 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@5->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG50 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@5->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG51 [16] phi from main::@5 to main::@6 [phi:main::@5->main::@6] + //SEG52 main::@6 + //SEG53 [17] call assertType + //SEG54 [75] phi from main::@6 to assertType [phi:main::@6->assertType] + //SEG55 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@6->assertType#0] -- register_copy + //SEG56 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@6->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG57 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@6->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG58 [18] phi from main::@6 to main::@7 [phi:main::@6->main::@7] + //SEG59 main::@7 + //SEG60 [19] call assertType + //SEG61 [75] phi from main::@7 to assertType [phi:main::@7->assertType] + //SEG62 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@7->assertType#0] -- register_copy + //SEG63 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@7->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG64 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@7->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG65 [20] phi from main::@7 to main::@8 [phi:main::@7->main::@8] + //SEG66 main::@8 + //SEG67 [21] call assertType + //SEG68 [75] phi from main::@8 to assertType [phi:main::@8->assertType] + //SEG69 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@8->assertType#0] -- register_copy + //SEG70 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@8->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_SIGNED_DWORD + sta assertType.t2 + //SEG71 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@8->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG72 [22] phi from main::@8 to main::@9 [phi:main::@8->main::@9] + //SEG73 main::@9 + //SEG74 [23] call assertType + //SEG75 [75] phi from main::@9 to assertType [phi:main::@9->assertType] + //SEG76 [75] phi (byte) idx#79 = (byte) $28 [phi:main::@9->assertType#0] -- vbuxx=vbuc1 + ldx #$28 + //SEG77 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@9->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG78 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@9->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG79 [24] phi from main::@9 to main::@10 [phi:main::@9->main::@10] + //SEG80 main::@10 + //SEG81 [25] call assertType + //SEG82 [75] phi from main::@10 to assertType [phi:main::@10->assertType] + //SEG83 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@10->assertType#0] -- register_copy + //SEG84 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@10->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG85 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@10->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG86 [26] phi from main::@10 to main::@11 [phi:main::@10->main::@11] + //SEG87 main::@11 + //SEG88 [27] call assertType + //SEG89 [75] phi from main::@11 to assertType [phi:main::@11->assertType] + //SEG90 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@11->assertType#0] -- register_copy + //SEG91 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@11->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG92 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@11->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG93 [28] phi from main::@11 to main::@12 [phi:main::@11->main::@12] + //SEG94 main::@12 + //SEG95 [29] call assertType + //SEG96 [75] phi from main::@12 to assertType [phi:main::@12->assertType] + //SEG97 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@12->assertType#0] -- register_copy + //SEG98 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@12->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG99 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@12->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG100 [30] phi from main::@12 to main::@13 [phi:main::@12->main::@13] + //SEG101 main::@13 + //SEG102 [31] call assertType + //SEG103 [75] phi from main::@13 to assertType [phi:main::@13->assertType] + //SEG104 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@13->assertType#0] -- register_copy + //SEG105 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@13->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG106 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@13->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG107 [32] phi from main::@13 to main::@14 [phi:main::@13->main::@14] + //SEG108 main::@14 + //SEG109 [33] call assertType + //SEG110 [75] phi from main::@14 to assertType [phi:main::@14->assertType] + //SEG111 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@14->assertType#0] -- register_copy + //SEG112 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@14->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG113 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@14->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG114 [34] phi from main::@14 to main::@15 [phi:main::@14->main::@15] + //SEG115 main::@15 + //SEG116 [35] call assertType + //SEG117 [75] phi from main::@15 to assertType [phi:main::@15->assertType] + //SEG118 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@15->assertType#0] -- register_copy + //SEG119 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@15->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG120 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@15->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG121 [36] phi from main::@15 to main::@16 [phi:main::@15->main::@16] + //SEG122 main::@16 + //SEG123 [37] call assertType + //SEG124 [75] phi from main::@16 to assertType [phi:main::@16->assertType] + //SEG125 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@16->assertType#0] -- register_copy + //SEG126 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@16->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG127 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@16->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG128 [38] phi from main::@16 to main::@17 [phi:main::@16->main::@17] + //SEG129 main::@17 + //SEG130 [39] call assertType + //SEG131 [75] phi from main::@17 to assertType [phi:main::@17->assertType] + //SEG132 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@17->assertType#0] -- register_copy + //SEG133 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@17->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG134 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@17->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG135 [40] phi from main::@17 to main::@18 [phi:main::@17->main::@18] + //SEG136 main::@18 + //SEG137 [41] call assertType + //SEG138 [75] phi from main::@18 to assertType [phi:main::@18->assertType] + //SEG139 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@18->assertType#0] -- register_copy + //SEG140 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@18->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG141 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@18->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG142 [42] phi from main::@18 to main::@19 [phi:main::@18->main::@19] + //SEG143 main::@19 + //SEG144 [43] call assertType + //SEG145 [75] phi from main::@19 to assertType [phi:main::@19->assertType] + //SEG146 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@19->assertType#0] -- register_copy + //SEG147 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@19->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG148 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@19->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG149 [44] phi from main::@19 to main::@20 [phi:main::@19->main::@20] + //SEG150 main::@20 + //SEG151 [45] call assertType + //SEG152 [75] phi from main::@20 to assertType [phi:main::@20->assertType] + //SEG153 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@20->assertType#0] -- register_copy + //SEG154 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@20->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG155 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@20->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG156 [46] phi from main::@20 to main::@21 [phi:main::@20->main::@21] + //SEG157 main::@21 + //SEG158 [47] call assertType + //SEG159 [75] phi from main::@21 to assertType [phi:main::@21->assertType] + //SEG160 [75] phi (byte) idx#79 = (byte) $50 [phi:main::@21->assertType#0] -- vbuxx=vbuc1 + ldx #$50 + //SEG161 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@21->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG162 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@21->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG163 [48] phi from main::@21 to main::@22 [phi:main::@21->main::@22] + //SEG164 main::@22 + //SEG165 [49] call assertType + //SEG166 [75] phi from main::@22 to assertType [phi:main::@22->assertType] + //SEG167 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@22->assertType#0] -- register_copy + //SEG168 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@22->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG169 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@22->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG170 [50] phi from main::@22 to main::@23 [phi:main::@22->main::@23] + //SEG171 main::@23 + //SEG172 [51] call assertType + //SEG173 [75] phi from main::@23 to assertType [phi:main::@23->assertType] + //SEG174 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@23->assertType#0] -- register_copy + //SEG175 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_BYTE [phi:main::@23->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_BYTE + sta assertType.t2 + //SEG176 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_BYTE [phi:main::@23->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG177 [52] phi from main::@23 to main::@24 [phi:main::@23->main::@24] + //SEG178 main::@24 + //SEG179 [53] call assertType + //SEG180 [75] phi from main::@24 to assertType [phi:main::@24->assertType] + //SEG181 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@24->assertType#0] -- register_copy + //SEG182 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@24->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG183 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@24->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG184 [54] phi from main::@24 to main::@25 [phi:main::@24->main::@25] + //SEG185 main::@25 + //SEG186 [55] call assertType + //SEG187 [75] phi from main::@25 to assertType [phi:main::@25->assertType] + //SEG188 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@25->assertType#0] -- register_copy + //SEG189 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@25->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG190 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@25->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG191 [56] phi from main::@25 to main::@26 [phi:main::@25->main::@26] + //SEG192 main::@26 + //SEG193 [57] call assertType + //SEG194 [75] phi from main::@26 to assertType [phi:main::@26->assertType] + //SEG195 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@26->assertType#0] -- register_copy + //SEG196 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@26->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG197 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@26->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG198 [58] phi from main::@26 to main::@27 [phi:main::@26->main::@27] + //SEG199 main::@27 + //SEG200 [59] call assertType + //SEG201 [75] phi from main::@27 to assertType [phi:main::@27->assertType] + //SEG202 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@27->assertType#0] -- register_copy + //SEG203 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@27->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG204 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@27->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG205 [60] phi from main::@27 to main::@28 [phi:main::@27->main::@28] + //SEG206 main::@28 + //SEG207 [61] call assertType + //SEG208 [75] phi from main::@28 to assertType [phi:main::@28->assertType] + //SEG209 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@28->assertType#0] -- register_copy + //SEG210 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@28->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG211 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@28->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG212 [62] phi from main::@28 to main::@29 [phi:main::@28->main::@29] + //SEG213 main::@29 + //SEG214 [63] call assertType + //SEG215 [75] phi from main::@29 to assertType [phi:main::@29->assertType] + //SEG216 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@29->assertType#0] -- register_copy + //SEG217 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_WORD [phi:main::@29->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_WORD + sta assertType.t2 + //SEG218 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_WORD [phi:main::@29->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG219 [64] phi from main::@29 to main::@30 [phi:main::@29->main::@30] + //SEG220 main::@30 + //SEG221 [65] call assertType + //SEG222 [75] phi from main::@30 to assertType [phi:main::@30->assertType] + //SEG223 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@30->assertType#0] -- register_copy + //SEG224 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@30->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG225 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@30->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG226 [66] phi from main::@30 to main::@31 [phi:main::@30->main::@31] + //SEG227 main::@31 + //SEG228 [67] call assertType + //SEG229 [75] phi from main::@31 to assertType [phi:main::@31->assertType] + //SEG230 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@31->assertType#0] -- register_copy + //SEG231 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@31->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG232 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@31->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG233 [68] phi from main::@31 to main::@32 [phi:main::@31->main::@32] + //SEG234 main::@32 + //SEG235 [69] call assertType + //SEG236 [75] phi from main::@32 to assertType [phi:main::@32->assertType] + //SEG237 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@32->assertType#0] -- register_copy + //SEG238 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@32->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG239 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@32->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG240 [70] phi from main::@32 to main::@33 [phi:main::@32->main::@33] + //SEG241 main::@33 + //SEG242 [71] call assertType + //SEG243 [75] phi from main::@33 to assertType [phi:main::@33->assertType] + //SEG244 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@33->assertType#0] -- register_copy + //SEG245 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@33->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG246 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_DWORD [phi:main::@33->assertType#2] -- vbuyy=vbuc1 + tay + jsr assertType + //SEG247 [72] phi from main::@33 to main::@34 [phi:main::@33->main::@34] + //SEG248 main::@34 + //SEG249 [73] call assertType + //SEG250 [75] phi from main::@34 to assertType [phi:main::@34->assertType] + //SEG251 [75] phi (byte) idx#79 = (byte) idx#40 [phi:main::@34->assertType#0] -- register_copy + //SEG252 [75] phi (byte) assertType::t2#35 = (const byte) TYPEID_DWORD [phi:main::@34->assertType#1] -- vbuz1=vbuc1 + lda #TYPEID_DWORD + sta assertType.t2 + //SEG253 [75] phi (byte) assertType::t1#35 = (const byte) TYPEID_SIGNED_DWORD [phi:main::@34->assertType#2] -- vbuyy=vbuc1 + ldy #TYPEID_SIGNED_DWORD + jsr assertType + //SEG254 main::@return + //SEG255 [74] return + rts +} +//SEG256 assertType +// Check that the two passed type IDs are equal. +// Shows a letter symbolizing t1 +// If they are equal the letter is green - if not it is red. +// assertType(byte register(Y) t1, byte zeropage(2) t2) +assertType: { + .label t2 = 2 + //SEG257 [76] if((byte) assertType::t1#35==(byte) assertType::t2#35) goto assertType::@1 -- vbuyy_eq_vbuz1_then_la1 + tya + cmp t2 + beq b1 + //SEG258 assertType::@3 + //SEG259 [77] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) RED#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #RED + sta $d800,x + //SEG260 assertType::@2 + b2: + //SEG261 [78] *((byte*)(word) $400 + (byte) idx#79) ← (byte) assertType::t1#35 -- pbuc1_derefidx_vbuxx=vbuyy + tya + sta $400,x + //SEG262 [79] (byte) idx#40 ← ++ (byte) idx#79 -- vbuxx=_inc_vbuxx + inx + //SEG263 assertType::@return + //SEG264 [80] return + rts + //SEG265 assertType::@1 + b1: + //SEG266 [81] *((byte*)(word) $d800 + (byte) idx#79) ← (const byte) GREEN#0 -- pbuc1_derefidx_vbuxx=vbuc2 + lda #GREEN + sta $d800,x + jmp b2 +} + diff --git a/src/test/ref/number-conversion.sym b/src/test/ref/number-conversion.sym new file mode 100644 index 000000000..78d7bc585 --- /dev/null +++ b/src/test/ref/number-conversion.sym @@ -0,0 +1,67 @@ +(label) @1 +(label) @begin +(label) @end +(byte*) COLS +(byte) GREEN +(const byte) GREEN#0 GREEN = (byte) 5 +(byte) RED +(const byte) RED#0 RED = (byte) 2 +(byte*) SCREEN +(const byte) TYPEID_BYTE TYPEID_BYTE = (number) 1 +(const byte) TYPEID_DWORD TYPEID_DWORD = (number) 5 +(const byte) TYPEID_SIGNED_BYTE TYPEID_SIGNED_BYTE = (number) 2 +(const byte) TYPEID_SIGNED_DWORD TYPEID_SIGNED_DWORD = (number) 6 +(const byte) TYPEID_SIGNED_WORD TYPEID_SIGNED_WORD = (number) 4 +(const byte) TYPEID_WORD TYPEID_WORD = (number) 3 +(void()) assertType((byte) assertType::t1 , (byte) assertType::t2) +(label) assertType::@1 +(label) assertType::@2 +(label) assertType::@3 +(label) assertType::@return +(byte) assertType::t1 +(byte) assertType::t1#35 reg byte y 1.0 +(byte) assertType::t2 +(byte) assertType::t2#35 t2 zp ZP_BYTE:2 2.0 +(byte) idx +(byte) idx#40 reg byte x 0.9999999999999993 +(byte) idx#79 reg byte x 14.400000000000007 +(void()) main() +(label) main::@1 +(label) main::@10 +(label) main::@11 +(label) main::@12 +(label) main::@13 +(label) main::@14 +(label) main::@15 +(label) main::@16 +(label) main::@17 +(label) main::@18 +(label) main::@19 +(label) main::@2 +(label) main::@20 +(label) main::@21 +(label) main::@22 +(label) main::@23 +(label) main::@24 +(label) main::@25 +(label) main::@26 +(label) main::@27 +(label) main::@28 +(label) main::@29 +(label) main::@3 +(label) main::@30 +(label) main::@31 +(label) main::@32 +(label) main::@33 +(label) main::@34 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@8 +(label) main::@9 +(label) main::@return + +reg byte y [ assertType::t1#35 ] +zp ZP_BYTE:2 [ assertType::t2#35 ] +reg byte x [ idx#79 idx#40 ] diff --git a/src/test/ref/number-inference-sum.asm b/src/test/ref/number-inference-sum.asm new file mode 100644 index 000000000..9715ba4f5 --- /dev/null +++ b/src/test/ref/number-inference-sum.asm @@ -0,0 +1,20 @@ +// Test inference of number types using a long sum +// Currently fails - because the compiler does not handle byte+byte correctly (not truncating the result to 8 bits) +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label bgcol = $d020 + .const RED = 2 + .const b1 = $fa + .const b2 = b1+$fa + .const w = b2+1 + lda #w + sta screen+1 + lda #RED + sta bgcol + rts +} diff --git a/src/test/ref/number-type.asm b/src/test/ref/number-type.asm new file mode 100644 index 000000000..8944e6dbf --- /dev/null +++ b/src/test/ref/number-type.asm @@ -0,0 +1,69 @@ +// Tests the number type used for constant expressions +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + jsr testBytes + jsr testSBytes + rts +} +testSBytes: { + // Constant values resolvable to signed bytes + .label SCREEN = $428 + lda #-$c + sta SCREEN + lda #-6-6 + sta SCREEN+1 + lda #-$12+6 + sta SCREEN+2 + lda #-$714+$708 + sta SCREEN+3 + lda #-1-2-3-6 + sta SCREEN+4 + lda #-2*6 + sta SCREEN+5 + lda #-3<<2 + sta SCREEN+6 + lda #-$18>>1 + sta SCREEN+7 + lda #-4&-9 + sta SCREEN+8 + lda #-$10|-$fc + sta SCREEN+9 + lda #(-2-2)*$f/5 + sta SCREEN+$a + lda #$ff&$1000-$c + sta SCREEN+$b + rts +} +testBytes: { + // Constant values resolvable to bytes + .label SCREEN = $400 + lda #$c + sta SCREEN + lda #6+6 + sta SCREEN+1 + lda #$12-6 + sta SCREEN+2 + lda #$714-$708 + sta SCREEN+3 + lda #1+2+3+6 + sta SCREEN+4 + lda #2*6 + sta SCREEN+5 + lda #3<<2 + sta SCREEN+6 + lda #$18>>1 + sta SCREEN+7 + lda #$f&$1c + sta SCREEN+8 + lda #4|8 + sta SCREEN+9 + lda #5^9 + sta SCREEN+$a + lda #(2+2)*$f/5 + sta SCREEN+$b + lda #$ff&$1000+$c + sta SCREEN+$c + rts +} diff --git a/src/test/ref/number-type.cfg b/src/test/ref/number-type.cfg new file mode 100644 index 000000000..11a77d0ae --- /dev/null +++ b/src/test/ref/number-type.cfg @@ -0,0 +1,55 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call testBytes + to:main::@1 +main::@1: scope:[main] from main + [6] phi() + [7] call testSBytes + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return +testSBytes: scope:[testSBytes] from main::@1 + [9] *((const signed byte*) testSBytes::SCREEN#0) ← ((signed byte))-(number) $c + [10] *((const signed byte*) testSBytes::SCREEN#0+(number) 1) ← ((signed byte))-(number) 6-(number) 6 + [11] *((const signed byte*) testSBytes::SCREEN#0+(number) 2) ← ((signed byte))-(number) $12+(number) 6 + [12] *((const signed byte*) testSBytes::SCREEN#0+(number) 3) ← ((signed byte))-(number) $714+(number) $708 + [13] *((const signed byte*) testSBytes::SCREEN#0+(number) 4) ← ((signed byte))-(number) 1-(number) 2-(number) 3-(number) 6 + [14] *((const signed byte*) testSBytes::SCREEN#0+(number) 5) ← ((signed byte))-(number) 2*(number) 6 + [15] *((const signed byte*) testSBytes::SCREEN#0+(number) 6) ← ((signed byte))-(number) 3<<(number) 2 + [16] *((const signed byte*) testSBytes::SCREEN#0+(number) 7) ← ((signed byte))-(number) $18>>(number) 1 + [17] *((const signed byte*) testSBytes::SCREEN#0+(number) 8) ← ((signed byte))-(number) 4&-(number) 9 + [18] *((const signed byte*) testSBytes::SCREEN#0+(number) 9) ← ((signed byte))-(number) $10|-(number) $fc + [19] *((const signed byte*) testSBytes::SCREEN#0+(number) $a) ← ((signed byte))-(number) 2-(number) 2*(number) $f/(number) 5 + [20] *((const signed byte*) testSBytes::SCREEN#0+(number) $b) ← ((signed byte))(number) $1000-(number) $c + to:testSBytes::@return +testSBytes::@return: scope:[testSBytes] from testSBytes + [21] return + to:@return +testBytes: scope:[testBytes] from main + [22] *((const byte*) testBytes::SCREEN#0) ← (byte) $c + [23] *((const byte*) testBytes::SCREEN#0+(number) 1) ← ((byte))(number) 6+(number) 6 + [24] *((const byte*) testBytes::SCREEN#0+(number) 2) ← ((byte))(number) $12-(number) 6 + [25] *((const byte*) testBytes::SCREEN#0+(number) 3) ← ((byte))(number) $714-(number) $708 + [26] *((const byte*) testBytes::SCREEN#0+(number) 4) ← ((byte))(number) 1+(number) 2+(number) 3+(number) 6 + [27] *((const byte*) testBytes::SCREEN#0+(number) 5) ← ((byte))(number) 2*(number) 6 + [28] *((const byte*) testBytes::SCREEN#0+(number) 6) ← ((byte))(number) 3<<(number) 2 + [29] *((const byte*) testBytes::SCREEN#0+(number) 7) ← ((byte))(number) $18>>(number) 1 + [30] *((const byte*) testBytes::SCREEN#0+(number) 8) ← ((byte))(number) $f&(number) $1c + [31] *((const byte*) testBytes::SCREEN#0+(number) 9) ← ((byte))(number) 4|(number) 8 + [32] *((const byte*) testBytes::SCREEN#0+(number) $a) ← ((byte))(number) 5^(number) 9 + [33] *((const byte*) testBytes::SCREEN#0+(number) $b) ← ((byte))(number) 2+(number) 2*(number) $f/(number) 5 + [34] *((const byte*) testBytes::SCREEN#0+(number) $c) ← ((byte))(number) $1000+(number) $c + to:testBytes::@return +testBytes::@return: scope:[testBytes] from testBytes + [35] return + to:@return diff --git a/src/test/ref/number-type.log b/src/test/ref/number-type.log new file mode 100644 index 000000000..55a8e6375 --- /dev/null +++ b/src/test/ref/number-type.log @@ -0,0 +1,1204 @@ +Adding pointer type conversion cast (byte*) testBytes::SCREEN in (byte*) testBytes::SCREEN ← (number) $400 +Adding pointer type conversion cast (signed byte*) testSBytes::SCREEN in (signed byte*) testSBytes::SCREEN ← (number) $428 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@3 +main: scope:[main] from @3 + call testBytes + to:main::@1 +main::@1: scope:[main] from main + call testSBytes + to:main::@2 +main::@2: scope:[main] from main::@1 + to:main::@return +main::@return: scope:[main] from main::@2 + return + to:@return +testBytes: scope:[testBytes] from main + (number) testBytes::$17 ← (number) $400 + (byte*) testBytes::SCREEN#0 ← ((byte*)) (number) testBytes::$17 + (byte) testBytes::idx#0 ← (number) 0 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#0) ← (number) $c + (byte) testBytes::idx#1 ← ++ (byte) testBytes::idx#0 + (number~) testBytes::$0 ← (number) 6 + (number) 6 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#1) ← (number~) testBytes::$0 + (byte) testBytes::idx#2 ← ++ (byte) testBytes::idx#1 + (number~) testBytes::$1 ← (number) $12 - (number) 6 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#2) ← (number~) testBytes::$1 + (byte) testBytes::idx#3 ← ++ (byte) testBytes::idx#2 + (number~) testBytes::$2 ← (number) $714 - (number) $708 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#3) ← (number~) testBytes::$2 + (byte) testBytes::idx#4 ← ++ (byte) testBytes::idx#3 + (number~) testBytes::$3 ← (number) 1 + (number) 2 + (number~) testBytes::$4 ← (number~) testBytes::$3 + (number) 3 + (number~) testBytes::$5 ← (number~) testBytes::$4 + (number) 6 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#4) ← (number~) testBytes::$5 + (byte) testBytes::idx#5 ← ++ (byte) testBytes::idx#4 + (number~) testBytes::$6 ← (number) 2 * (number) 6 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#5) ← (number~) testBytes::$6 + (byte) testBytes::idx#6 ← ++ (byte) testBytes::idx#5 + (number~) testBytes::$7 ← (number) 3 << (number) 2 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#6) ← (number~) testBytes::$7 + (byte) testBytes::idx#7 ← ++ (byte) testBytes::idx#6 + (number~) testBytes::$8 ← (number) $18 >> (number) 1 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#7) ← (number~) testBytes::$8 + (byte) testBytes::idx#8 ← ++ (byte) testBytes::idx#7 + (number~) testBytes::$9 ← (number) $f & (number) $1c + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#8) ← (number~) testBytes::$9 + (byte) testBytes::idx#9 ← ++ (byte) testBytes::idx#8 + (number~) testBytes::$10 ← (number) 4 | (number) 8 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#9) ← (number~) testBytes::$10 + (byte) testBytes::idx#10 ← ++ (byte) testBytes::idx#9 + (number~) testBytes::$11 ← (number) 5 ^ (number) 9 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#10) ← (number~) testBytes::$11 + (byte) testBytes::idx#11 ← ++ (byte) testBytes::idx#10 + (number~) testBytes::$12 ← (number) 2 + (number) 2 + (number~) testBytes::$13 ← (number) $f / (number) 5 + (number~) testBytes::$14 ← (number~) testBytes::$12 * (number~) testBytes::$13 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#11) ← (number~) testBytes::$14 + (byte) testBytes::idx#12 ← ++ (byte) testBytes::idx#11 + (number~) testBytes::$15 ← (number) $1000 + (number) $c + (byte~) testBytes::$16 ← ((byte)) (number~) testBytes::$15 + *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#12) ← (byte~) testBytes::$16 + (byte) testBytes::idx#13 ← ++ (byte) testBytes::idx#12 + to:testBytes::@return +testBytes::@return: scope:[testBytes] from testBytes + return + to:@return +testSBytes: scope:[testSBytes] from main::@1 + (number) testSBytes::$29 ← (number) $428 + (signed byte*) testSBytes::SCREEN#0 ← ((signed byte*)) (number) testSBytes::$29 + (byte) testSBytes::idx#0 ← (number) 0 + (number~) testSBytes::$0 ← - (number) $c + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#0) ← (number~) testSBytes::$0 + (byte) testSBytes::idx#1 ← ++ (byte) testSBytes::idx#0 + (number~) testSBytes::$1 ← - (number) 6 + (number~) testSBytes::$2 ← (number~) testSBytes::$1 - (number) 6 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#1) ← (number~) testSBytes::$2 + (byte) testSBytes::idx#2 ← ++ (byte) testSBytes::idx#1 + (number~) testSBytes::$3 ← - (number) $12 + (number~) testSBytes::$4 ← (number~) testSBytes::$3 + (number) 6 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#2) ← (number~) testSBytes::$4 + (byte) testSBytes::idx#3 ← ++ (byte) testSBytes::idx#2 + (number~) testSBytes::$5 ← - (number) $714 + (number~) testSBytes::$6 ← (number~) testSBytes::$5 + (number) $708 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#3) ← (number~) testSBytes::$6 + (byte) testSBytes::idx#4 ← ++ (byte) testSBytes::idx#3 + (number~) testSBytes::$7 ← - (number) 1 + (number~) testSBytes::$8 ← (number~) testSBytes::$7 - (number) 2 + (number~) testSBytes::$9 ← (number~) testSBytes::$8 - (number) 3 + (number~) testSBytes::$10 ← (number~) testSBytes::$9 - (number) 6 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#4) ← (number~) testSBytes::$10 + (byte) testSBytes::idx#5 ← ++ (byte) testSBytes::idx#4 + (number~) testSBytes::$11 ← - (number) 2 + (number~) testSBytes::$12 ← (number~) testSBytes::$11 * (number) 6 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#5) ← (number~) testSBytes::$12 + (byte) testSBytes::idx#6 ← ++ (byte) testSBytes::idx#5 + (number~) testSBytes::$13 ← - (number) 3 + (number~) testSBytes::$14 ← (number~) testSBytes::$13 << (number) 2 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#6) ← (number~) testSBytes::$14 + (byte) testSBytes::idx#7 ← ++ (byte) testSBytes::idx#6 + (number~) testSBytes::$15 ← - (number) $18 + (number~) testSBytes::$16 ← (number~) testSBytes::$15 >> (number) 1 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#7) ← (number~) testSBytes::$16 + (byte) testSBytes::idx#8 ← ++ (byte) testSBytes::idx#7 + (number~) testSBytes::$17 ← - (number) 4 + (number~) testSBytes::$18 ← - (number) 9 + (number~) testSBytes::$19 ← (number~) testSBytes::$17 & (number~) testSBytes::$18 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#8) ← (number~) testSBytes::$19 + (byte) testSBytes::idx#9 ← ++ (byte) testSBytes::idx#8 + (number~) testSBytes::$20 ← - (number) $10 + (number~) testSBytes::$21 ← - (number) $fc + (number~) testSBytes::$22 ← (number~) testSBytes::$20 | (number~) testSBytes::$21 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#9) ← (number~) testSBytes::$22 + (byte) testSBytes::idx#10 ← ++ (byte) testSBytes::idx#9 + (number~) testSBytes::$23 ← - (number) 2 + (number~) testSBytes::$24 ← (number~) testSBytes::$23 - (number) 2 + (number~) testSBytes::$25 ← (number) $f / (number) 5 + (number~) testSBytes::$26 ← (number~) testSBytes::$24 * (number~) testSBytes::$25 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#10) ← (number~) testSBytes::$26 + (byte) testSBytes::idx#11 ← ++ (byte) testSBytes::idx#10 + (number~) testSBytes::$27 ← (number) $1000 - (number) $c + (signed byte~) testSBytes::$28 ← ((signed byte)) (number~) testSBytes::$27 + *((signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#11) ← (signed byte~) testSBytes::$28 + (byte) testSBytes::idx#12 ← ++ (byte) testSBytes::idx#11 + to:testSBytes::@return +testSBytes::@return: scope:[testSBytes] from testSBytes + return + to:@return +@3: scope:[] from @begin + call main + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +SYMBOL TABLE SSA +(label) @3 +(label) @4 +(label) @begin +(label) @end +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return +(void()) testBytes() +(number~) testBytes::$0 +(number~) testBytes::$1 +(number~) testBytes::$10 +(number~) testBytes::$11 +(number~) testBytes::$12 +(number~) testBytes::$13 +(number~) testBytes::$14 +(number~) testBytes::$15 +(byte~) testBytes::$16 +(number) testBytes::$17 +(number~) testBytes::$2 +(number~) testBytes::$3 +(number~) testBytes::$4 +(number~) testBytes::$5 +(number~) testBytes::$6 +(number~) testBytes::$7 +(number~) testBytes::$8 +(number~) testBytes::$9 +(label) testBytes::@return +(byte*) testBytes::SCREEN +(byte*) testBytes::SCREEN#0 +(byte) testBytes::idx +(byte) testBytes::idx#0 +(byte) testBytes::idx#1 +(byte) testBytes::idx#10 +(byte) testBytes::idx#11 +(byte) testBytes::idx#12 +(byte) testBytes::idx#13 +(byte) testBytes::idx#2 +(byte) testBytes::idx#3 +(byte) testBytes::idx#4 +(byte) testBytes::idx#5 +(byte) testBytes::idx#6 +(byte) testBytes::idx#7 +(byte) testBytes::idx#8 +(byte) testBytes::idx#9 +(void()) testSBytes() +(number~) testSBytes::$0 +(number~) testSBytes::$1 +(number~) testSBytes::$10 +(number~) testSBytes::$11 +(number~) testSBytes::$12 +(number~) testSBytes::$13 +(number~) testSBytes::$14 +(number~) testSBytes::$15 +(number~) testSBytes::$16 +(number~) testSBytes::$17 +(number~) testSBytes::$18 +(number~) testSBytes::$19 +(number~) testSBytes::$2 +(number~) testSBytes::$20 +(number~) testSBytes::$21 +(number~) testSBytes::$22 +(number~) testSBytes::$23 +(number~) testSBytes::$24 +(number~) testSBytes::$25 +(number~) testSBytes::$26 +(number~) testSBytes::$27 +(signed byte~) testSBytes::$28 +(number) testSBytes::$29 +(number~) testSBytes::$3 +(number~) testSBytes::$4 +(number~) testSBytes::$5 +(number~) testSBytes::$6 +(number~) testSBytes::$7 +(number~) testSBytes::$8 +(number~) testSBytes::$9 +(label) testSBytes::@return +(signed byte*) testSBytes::SCREEN +(signed byte*) testSBytes::SCREEN#0 +(byte) testSBytes::idx +(byte) testSBytes::idx#0 +(byte) testSBytes::idx#1 +(byte) testSBytes::idx#10 +(byte) testSBytes::idx#11 +(byte) testSBytes::idx#12 +(byte) testSBytes::idx#2 +(byte) testSBytes::idx#3 +(byte) testSBytes::idx#4 +(byte) testSBytes::idx#5 +(byte) testSBytes::idx#6 +(byte) testSBytes::idx#7 +(byte) testSBytes::idx#8 +(byte) testSBytes::idx#9 + +Adding number conversion cast (byte) 0 in (byte) testBytes::idx#0 ← (number) 0 +Adding number conversion cast (byte) $c in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#0) ← (number) $c +Adding number conversion cast (byte) 0 in (byte) testSBytes::idx#0 ← (number) 0 +Culled Empty Block (label) main::@2 +Culled Empty Block (label) @4 +Successful SSA optimization Pass2CullEmptyBlocks +Constant right-side identified [5] (byte) testBytes::idx#0 ← ((byte)) (number) 0 +Constant right-side identified [6] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#0) ← ((byte)) (number) $c +Constant right-side identified [8] (number~) testBytes::$0 ← (number) 6 + (number) 6 +Constant right-side identified [11] (number~) testBytes::$1 ← (number) $12 - (number) 6 +Constant right-side identified [14] (number~) testBytes::$2 ← (number) $714 - (number) $708 +Constant right-side identified [17] (number~) testBytes::$3 ← (number) 1 + (number) 2 +Constant right-side identified [22] (number~) testBytes::$6 ← (number) 2 * (number) 6 +Constant right-side identified [25] (number~) testBytes::$7 ← (number) 3 << (number) 2 +Constant right-side identified [28] (number~) testBytes::$8 ← (number) $18 >> (number) 1 +Constant right-side identified [31] (number~) testBytes::$9 ← (number) $f & (number) $1c +Constant right-side identified [34] (number~) testBytes::$10 ← (number) 4 | (number) 8 +Constant right-side identified [37] (number~) testBytes::$11 ← (number) 5 ^ (number) 9 +Constant right-side identified [40] (number~) testBytes::$12 ← (number) 2 + (number) 2 +Constant right-side identified [41] (number~) testBytes::$13 ← (number) $f / (number) 5 +Constant right-side identified [45] (number~) testBytes::$15 ← (number) $1000 + (number) $c +Constant right-side identified [52] (byte) testSBytes::idx#0 ← ((byte)) (number) 0 +Constant right-side identified [53] (number~) testSBytes::$0 ← - (number) $c +Constant right-side identified [56] (number~) testSBytes::$1 ← - (number) 6 +Constant right-side identified [60] (number~) testSBytes::$3 ← - (number) $12 +Constant right-side identified [64] (number~) testSBytes::$5 ← - (number) $714 +Constant right-side identified [68] (number~) testSBytes::$7 ← - (number) 1 +Constant right-side identified [74] (number~) testSBytes::$11 ← - (number) 2 +Constant right-side identified [78] (number~) testSBytes::$13 ← - (number) 3 +Constant right-side identified [82] (number~) testSBytes::$15 ← - (number) $18 +Constant right-side identified [86] (number~) testSBytes::$17 ← - (number) 4 +Constant right-side identified [87] (number~) testSBytes::$18 ← - (number) 9 +Constant right-side identified [91] (number~) testSBytes::$20 ← - (number) $10 +Constant right-side identified [92] (number~) testSBytes::$21 ← - (number) $fc +Constant right-side identified [96] (number~) testSBytes::$23 ← - (number) 2 +Constant right-side identified [98] (number~) testSBytes::$25 ← (number) $f / (number) 5 +Constant right-side identified [102] (number~) testSBytes::$27 ← (number) $1000 - (number) $c +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const number) testBytes::$17 = $400 +Constant (const byte) testBytes::idx#0 = ((byte))0 +Constant (const number) testBytes::$0 = 6+6 +Constant (const number) testBytes::$1 = $12-6 +Constant (const number) testBytes::$2 = $714-$708 +Constant (const number) testBytes::$3 = 1+2 +Constant (const number) testBytes::$6 = 2*6 +Constant (const number) testBytes::$7 = 3<<2 +Constant (const number) testBytes::$8 = $18>>1 +Constant (const number) testBytes::$9 = $f&$1c +Constant (const number) testBytes::$10 = 4|8 +Constant (const number) testBytes::$11 = 5^9 +Constant (const number) testBytes::$12 = 2+2 +Constant (const number) testBytes::$13 = $f/5 +Constant (const number) testBytes::$15 = $1000+$c +Constant (const number) testSBytes::$29 = $428 +Constant (const byte) testSBytes::idx#0 = ((byte))0 +Constant (const number) testSBytes::$0 = -$c +Constant (const number) testSBytes::$1 = -6 +Constant (const number) testSBytes::$3 = -$12 +Constant (const number) testSBytes::$5 = -$714 +Constant (const number) testSBytes::$7 = -1 +Constant (const number) testSBytes::$11 = -2 +Constant (const number) testSBytes::$13 = -3 +Constant (const number) testSBytes::$15 = -$18 +Constant (const number) testSBytes::$17 = -4 +Constant (const number) testSBytes::$18 = -9 +Constant (const number) testSBytes::$20 = -$10 +Constant (const number) testSBytes::$21 = -$fc +Constant (const number) testSBytes::$23 = -2 +Constant (const number) testSBytes::$25 = $f/5 +Constant (const number) testSBytes::$27 = $1000-$c +Successful SSA optimization Pass2ConstantIdentification +Eliminating unused variable (byte) testBytes::idx#13 and assignment [33] (byte) testBytes::idx#13 ← ++ (byte) testBytes::idx#12 +Eliminating unused variable (byte) testSBytes::idx#12 and assignment [73] (byte) testSBytes::idx#12 ← ++ (byte) testSBytes::idx#11 +Successful SSA optimization PassNEliminateUnusedVars +Simplifying constant integer cast $c +Adding number conversion cast (byte) testBytes::$0 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#1) ← (const number) testBytes::$0 +Adding number conversion cast (byte) testBytes::$1 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#2) ← (const number) testBytes::$1 +Adding number conversion cast (byte) testBytes::$2 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#3) ← (const number) testBytes::$2 +Adding number conversion cast (byte) testBytes::$6 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#5) ← (const number) testBytes::$6 +Adding number conversion cast (byte) testBytes::$7 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#6) ← (const number) testBytes::$7 +Adding number conversion cast (byte) testBytes::$8 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#7) ← (const number) testBytes::$8 +Adding number conversion cast (byte) testBytes::$9 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#8) ← (const number) testBytes::$9 +Adding number conversion cast (byte) testBytes::$10 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#9) ← (const number) testBytes::$10 +Adding number conversion cast (byte) testBytes::$11 in *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#10) ← (const number) testBytes::$11 +Adding number conversion cast (signed byte) testSBytes::$0 in *((signed byte*) testSBytes::SCREEN#0 + (const byte) testSBytes::idx#0) ← (const number) testSBytes::$0 +Constant right-side identified [3] (byte*) testBytes::SCREEN#0 ← ((byte*)) (const number) testBytes::$17 +Constant right-side identified [5] (byte) testBytes::idx#1 ← ++ (const byte) testBytes::idx#0 +Constant right-side identified [6] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#1) ← ((byte)) (const number) testBytes::$0 +Constant right-side identified [8] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#2) ← ((byte)) (const number) testBytes::$1 +Constant right-side identified [10] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#3) ← ((byte)) (const number) testBytes::$2 +Constant right-side identified [12] (number~) testBytes::$4 ← (const number) testBytes::$3 + (number) 3 +Constant right-side identified [16] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#5) ← ((byte)) (const number) testBytes::$6 +Constant right-side identified [18] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#6) ← ((byte)) (const number) testBytes::$7 +Constant right-side identified [20] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#7) ← ((byte)) (const number) testBytes::$8 +Constant right-side identified [22] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#8) ← ((byte)) (const number) testBytes::$9 +Constant right-side identified [24] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#9) ← ((byte)) (const number) testBytes::$10 +Constant right-side identified [26] *((byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#10) ← ((byte)) (const number) testBytes::$11 +Constant right-side identified [28] (number~) testBytes::$14 ← (const number) testBytes::$12 * (const number) testBytes::$13 +Constant right-side identified [31] (byte~) testBytes::$16 ← ((byte)) (const number) testBytes::$15 +Constant right-side identified [34] (signed byte*) testSBytes::SCREEN#0 ← ((signed byte*)) (const number) testSBytes::$29 +Constant right-side identified [35] *((signed byte*) testSBytes::SCREEN#0 + (const byte) testSBytes::idx#0) ← ((signed byte)) (const number) testSBytes::$0 +Constant right-side identified [36] (byte) testSBytes::idx#1 ← ++ (const byte) testSBytes::idx#0 +Constant right-side identified [37] (number~) testSBytes::$2 ← (const number) testSBytes::$1 - (number) 6 +Constant right-side identified [40] (number~) testSBytes::$4 ← (const number) testSBytes::$3 + (number) 6 +Constant right-side identified [43] (number~) testSBytes::$6 ← (const number) testSBytes::$5 + (number) $708 +Constant right-side identified [46] (number~) testSBytes::$8 ← (const number) testSBytes::$7 - (number) 2 +Constant right-side identified [51] (number~) testSBytes::$12 ← (const number) testSBytes::$11 * (number) 6 +Constant right-side identified [54] (number~) testSBytes::$14 ← (const number) testSBytes::$13 << (number) 2 +Constant right-side identified [57] (number~) testSBytes::$16 ← (const number) testSBytes::$15 >> (number) 1 +Constant right-side identified [60] (number~) testSBytes::$19 ← (const number) testSBytes::$17 & (const number) testSBytes::$18 +Constant right-side identified [63] (number~) testSBytes::$22 ← (const number) testSBytes::$20 | (const number) testSBytes::$21 +Constant right-side identified [66] (number~) testSBytes::$24 ← (const number) testSBytes::$23 - (number) 2 +Constant right-side identified [70] (signed byte~) testSBytes::$28 ← ((signed byte)) (const number) testSBytes::$27 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte*) testBytes::SCREEN#0 = ((byte*))testBytes::$17 +Constant (const byte) testBytes::idx#1 = ++testBytes::idx#0 +Constant (const number) testBytes::$4 = testBytes::$3+3 +Constant (const number) testBytes::$14 = testBytes::$12*testBytes::$13 +Constant (const byte) testBytes::$16 = ((byte))testBytes::$15 +Constant (const signed byte*) testSBytes::SCREEN#0 = ((signed byte*))testSBytes::$29 +Constant (const byte) testSBytes::idx#1 = ++testSBytes::idx#0 +Constant (const number) testSBytes::$2 = testSBytes::$1-6 +Constant (const number) testSBytes::$4 = testSBytes::$3+6 +Constant (const number) testSBytes::$6 = testSBytes::$5+$708 +Constant (const number) testSBytes::$8 = testSBytes::$7-2 +Constant (const number) testSBytes::$12 = testSBytes::$11*6 +Constant (const number) testSBytes::$14 = testSBytes::$13<<2 +Constant (const number) testSBytes::$16 = testSBytes::$15>>1 +Constant (const number) testSBytes::$19 = testSBytes::$17&testSBytes::$18 +Constant (const number) testSBytes::$22 = testSBytes::$20|testSBytes::$21 +Constant (const number) testSBytes::$24 = testSBytes::$23-2 +Constant (const signed byte) testSBytes::$28 = ((signed byte))testSBytes::$27 +Successful SSA optimization Pass2ConstantIdentification +Adding number conversion cast (byte) testBytes::$14 in *((const byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#11) ← (const number) testBytes::$14 +Adding number conversion cast (signed byte) testSBytes::$2 in *((const signed byte*) testSBytes::SCREEN#0 + (const byte) testSBytes::idx#1) ← (const number) testSBytes::$2 +Adding number conversion cast (signed byte) testSBytes::$4 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#2) ← (const number) testSBytes::$4 +Adding number conversion cast (signed byte) testSBytes::$6 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#3) ← (const number) testSBytes::$6 +Adding number conversion cast (signed byte) testSBytes::$12 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#5) ← (const number) testSBytes::$12 +Adding number conversion cast (signed byte) testSBytes::$14 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#6) ← (const number) testSBytes::$14 +Adding number conversion cast (signed byte) testSBytes::$16 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#7) ← (const number) testSBytes::$16 +Adding number conversion cast (signed byte) testSBytes::$19 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#8) ← (const number) testSBytes::$19 +Adding number conversion cast (signed byte) testSBytes::$22 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#9) ← (const number) testSBytes::$22 +Constant right-side identified [5] (byte) testBytes::idx#2 ← ++ (const byte) testBytes::idx#1 +Constant right-side identified [10] (number~) testBytes::$5 ← (const number) testBytes::$4 + (number) 6 +Constant right-side identified [25] *((const byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#11) ← ((byte)) (const number) testBytes::$14 +Constant right-side identified [30] *((const signed byte*) testSBytes::SCREEN#0 + (const byte) testSBytes::idx#1) ← ((signed byte)) (const number) testSBytes::$2 +Constant right-side identified [31] (byte) testSBytes::idx#2 ← ++ (const byte) testSBytes::idx#1 +Constant right-side identified [32] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#2) ← ((signed byte)) (const number) testSBytes::$4 +Constant right-side identified [34] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#3) ← ((signed byte)) (const number) testSBytes::$6 +Constant right-side identified [36] (number~) testSBytes::$9 ← (const number) testSBytes::$8 - (number) 3 +Constant right-side identified [40] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#5) ← ((signed byte)) (const number) testSBytes::$12 +Constant right-side identified [42] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#6) ← ((signed byte)) (const number) testSBytes::$14 +Constant right-side identified [44] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#7) ← ((signed byte)) (const number) testSBytes::$16 +Constant right-side identified [46] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#8) ← ((signed byte)) (const number) testSBytes::$19 +Constant right-side identified [48] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#9) ← ((signed byte)) (const number) testSBytes::$22 +Constant right-side identified [50] (number~) testSBytes::$26 ← (const number) testSBytes::$24 * (const number) testSBytes::$25 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#2 = ++testBytes::idx#1 +Constant (const number) testBytes::$5 = testBytes::$4+6 +Constant (const byte) testSBytes::idx#2 = ++testSBytes::idx#1 +Constant (const number) testSBytes::$9 = testSBytes::$8-3 +Constant (const number) testSBytes::$26 = testSBytes::$24*testSBytes::$25 +Successful SSA optimization Pass2ConstantIdentification +Adding number conversion cast (byte) testBytes::$5 in *((const byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#4) ← (const number) testBytes::$5 +Adding number conversion cast (signed byte) testSBytes::$26 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#10) ← (const number) testSBytes::$26 +Constant right-side identified [6] (byte) testBytes::idx#3 ← ++ (const byte) testBytes::idx#2 +Constant right-side identified [9] *((const byte*) testBytes::SCREEN#0 + (byte) testBytes::idx#4) ← ((byte)) (const number) testBytes::$5 +Constant right-side identified [30] (byte) testSBytes::idx#3 ← ++ (const byte) testSBytes::idx#2 +Constant right-side identified [33] (number~) testSBytes::$10 ← (const number) testSBytes::$9 - (number) 6 +Constant right-side identified [46] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#10) ← ((signed byte)) (const number) testSBytes::$26 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#3 = ++testBytes::idx#2 +Constant (const byte) testSBytes::idx#3 = ++testSBytes::idx#2 +Constant (const number) testSBytes::$10 = testSBytes::$9-6 +Successful SSA optimization Pass2ConstantIdentification +Adding number conversion cast (signed byte) testSBytes::$10 in *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#4) ← (const number) testSBytes::$10 +Constant right-side identified [7] (byte) testBytes::idx#4 ← ++ (const byte) testBytes::idx#3 +Constant right-side identified [30] (byte) testSBytes::idx#4 ← ++ (const byte) testSBytes::idx#3 +Constant right-side identified [31] *((const signed byte*) testSBytes::SCREEN#0 + (byte) testSBytes::idx#4) ← ((signed byte)) (const number) testSBytes::$10 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#4 = ++testBytes::idx#3 +Constant (const byte) testSBytes::idx#4 = ++testSBytes::idx#3 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [8] (byte) testBytes::idx#5 ← ++ (const byte) testBytes::idx#4 +Constant right-side identified [30] (byte) testSBytes::idx#5 ← ++ (const byte) testSBytes::idx#4 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#5 = ++testBytes::idx#4 +Constant (const byte) testSBytes::idx#5 = ++testSBytes::idx#4 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [9] (byte) testBytes::idx#6 ← ++ (const byte) testBytes::idx#5 +Constant right-side identified [30] (byte) testSBytes::idx#6 ← ++ (const byte) testSBytes::idx#5 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#6 = ++testBytes::idx#5 +Constant (const byte) testSBytes::idx#6 = ++testSBytes::idx#5 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [10] (byte) testBytes::idx#7 ← ++ (const byte) testBytes::idx#6 +Constant right-side identified [30] (byte) testSBytes::idx#7 ← ++ (const byte) testSBytes::idx#6 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#7 = ++testBytes::idx#6 +Constant (const byte) testSBytes::idx#7 = ++testSBytes::idx#6 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [11] (byte) testBytes::idx#8 ← ++ (const byte) testBytes::idx#7 +Constant right-side identified [30] (byte) testSBytes::idx#8 ← ++ (const byte) testSBytes::idx#7 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#8 = ++testBytes::idx#7 +Constant (const byte) testSBytes::idx#8 = ++testSBytes::idx#7 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [12] (byte) testBytes::idx#9 ← ++ (const byte) testBytes::idx#8 +Constant right-side identified [30] (byte) testSBytes::idx#9 ← ++ (const byte) testSBytes::idx#8 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#9 = ++testBytes::idx#8 +Constant (const byte) testSBytes::idx#9 = ++testSBytes::idx#8 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [13] (byte) testBytes::idx#10 ← ++ (const byte) testBytes::idx#9 +Constant right-side identified [30] (byte) testSBytes::idx#10 ← ++ (const byte) testSBytes::idx#9 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#10 = ++testBytes::idx#9 +Constant (const byte) testSBytes::idx#10 = ++testSBytes::idx#9 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [14] (byte) testBytes::idx#11 ← ++ (const byte) testBytes::idx#10 +Constant right-side identified [30] (byte) testSBytes::idx#11 ← ++ (const byte) testSBytes::idx#10 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#11 = ++testBytes::idx#10 +Constant (const byte) testSBytes::idx#11 = ++testSBytes::idx#10 +Successful SSA optimization Pass2ConstantIdentification +Constant right-side identified [15] (byte) testBytes::idx#12 ← ++ (const byte) testBytes::idx#11 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) testBytes::idx#12 = ++testBytes::idx#11 +Successful SSA optimization Pass2ConstantIdentification +Inlining constant with different constant siblings (const byte) testBytes::idx#0 +Inlining constant with different constant siblings (const byte) testBytes::idx#1 +Inlining constant with different constant siblings (const byte) testBytes::idx#2 +Inlining constant with different constant siblings (const byte) testBytes::idx#3 +Inlining constant with different constant siblings (const byte) testBytes::idx#4 +Inlining constant with different constant siblings (const byte) testBytes::idx#5 +Inlining constant with different constant siblings (const byte) testBytes::idx#6 +Inlining constant with different constant siblings (const byte) testBytes::idx#7 +Inlining constant with different constant siblings (const byte) testBytes::idx#8 +Inlining constant with different constant siblings (const byte) testBytes::idx#9 +Inlining constant with different constant siblings (const byte) testBytes::idx#10 +Inlining constant with different constant siblings (const byte) testBytes::idx#11 +Inlining constant with different constant siblings (const byte) testBytes::idx#12 +Inlining constant with different constant siblings (const byte) testSBytes::idx#0 +Inlining constant with different constant siblings (const byte) testSBytes::idx#1 +Inlining constant with different constant siblings (const byte) testSBytes::idx#2 +Inlining constant with different constant siblings (const byte) testSBytes::idx#3 +Inlining constant with different constant siblings (const byte) testSBytes::idx#4 +Inlining constant with different constant siblings (const byte) testSBytes::idx#5 +Inlining constant with different constant siblings (const byte) testSBytes::idx#6 +Inlining constant with different constant siblings (const byte) testSBytes::idx#7 +Inlining constant with different constant siblings (const byte) testSBytes::idx#8 +Inlining constant with different constant siblings (const byte) testSBytes::idx#9 +Inlining constant with different constant siblings (const byte) testSBytes::idx#10 +Inlining constant with different constant siblings (const byte) testSBytes::idx#11 +Constant inlined testBytes::idx#5 = ++++++++++((byte))(number) 0 +Constant inlined testBytes::idx#6 = ++++++++++++((byte))(number) 0 +Constant inlined testBytes::idx#3 = ++++++((byte))(number) 0 +Constant inlined testBytes::idx#4 = ++++++++((byte))(number) 0 +Constant inlined testBytes::idx#1 = ++((byte))(number) 0 +Constant inlined testBytes::idx#2 = ++++((byte))(number) 0 +Constant inlined testBytes::idx#0 = ((byte))(number) 0 +Constant inlined testBytes::idx#9 = ++++++++++++++++++((byte))(number) 0 +Constant inlined testBytes::idx#7 = ++++++++++++++((byte))(number) 0 +Constant inlined testBytes::idx#8 = ++++++++++++++++((byte))(number) 0 +Constant inlined testSBytes::$28 = ((signed byte))(number) $1000-(number) $c +Constant inlined testSBytes::$29 = (number) $428 +Constant inlined testSBytes::$7 = -(number) 1 +Constant inlined testSBytes::$6 = -(number) $714+(number) $708 +Constant inlined testSBytes::$9 = -(number) 1-(number) 2-(number) 3 +Constant inlined testSBytes::$8 = -(number) 1-(number) 2 +Constant inlined testSBytes::$3 = -(number) $12 +Constant inlined testSBytes::$2 = -(number) 6-(number) 6 +Constant inlined testSBytes::$5 = -(number) $714 +Constant inlined testSBytes::$4 = -(number) $12+(number) 6 +Constant inlined testSBytes::$1 = -(number) 6 +Constant inlined testSBytes::$0 = -(number) $c +Constant inlined testSBytes::$13 = -(number) 3 +Constant inlined testSBytes::$14 = -(number) 3<<(number) 2 +Constant inlined testSBytes::$15 = -(number) $18 +Constant inlined testSBytes::$16 = -(number) $18>>(number) 1 +Constant inlined testSBytes::$10 = -(number) 1-(number) 2-(number) 3-(number) 6 +Constant inlined testSBytes::$11 = -(number) 2 +Constant inlined testSBytes::$12 = -(number) 2*(number) 6 +Constant inlined testBytes::idx#12 = ++++++++++++++++++++++++((byte))(number) 0 +Constant inlined testBytes::$2 = (number) $714-(number) $708 +Constant inlined testBytes::$14 = (number) 2+(number) 2*(number) $f/(number) 5 +Constant inlined testSBytes::$24 = -(number) 2-(number) 2 +Constant inlined testBytes::idx#11 = ++++++++++++++++++++++((byte))(number) 0 +Constant inlined testBytes::$1 = (number) $12-(number) 6 +Constant inlined testBytes::$15 = (number) $1000+(number) $c +Constant inlined testSBytes::$25 = (number) $f/(number) 5 +Constant inlined testBytes::idx#10 = ++++++++++++++++++++((byte))(number) 0 +Constant inlined testBytes::$0 = (number) 6+(number) 6 +Constant inlined testBytes::$12 = (number) 2+(number) 2 +Constant inlined testSBytes::$26 = -(number) 2-(number) 2*(number) $f/(number) 5 +Constant inlined testBytes::$13 = (number) $f/(number) 5 +Constant inlined testSBytes::$27 = (number) $1000-(number) $c +Constant inlined testBytes::$10 = (number) 4|(number) 8 +Constant inlined testSBytes::$20 = -(number) $10 +Constant inlined testBytes::$11 = (number) 5^(number) 9 +Constant inlined testSBytes::$21 = -(number) $fc +Constant inlined testSBytes::$22 = -(number) $10|-(number) $fc +Constant inlined testSBytes::$23 = -(number) 2 +Constant inlined testBytes::$9 = (number) $f&(number) $1c +Constant inlined testBytes::$8 = (number) $18>>(number) 1 +Constant inlined testBytes::$7 = (number) 3<<(number) 2 +Constant inlined testSBytes::idx#10 = ++++++++++++++++++++((byte))(number) 0 +Constant inlined testBytes::$6 = (number) 2*(number) 6 +Constant inlined testBytes::$5 = (number) 1+(number) 2+(number) 3+(number) 6 +Constant inlined testBytes::$4 = (number) 1+(number) 2+(number) 3 +Constant inlined testBytes::$3 = (number) 1+(number) 2 +Constant inlined testSBytes::idx#9 = ++++++++++++++++++((byte))(number) 0 +Constant inlined testSBytes::idx#11 = ++++++++++++++++++++++((byte))(number) 0 +Constant inlined testSBytes::idx#8 = ++++++++++++++++((byte))(number) 0 +Constant inlined testSBytes::idx#5 = ++++++++++((byte))(number) 0 +Constant inlined testSBytes::idx#4 = ++++++++((byte))(number) 0 +Constant inlined testSBytes::idx#7 = ++++++++++++++((byte))(number) 0 +Constant inlined testSBytes::idx#6 = ++++++++++++((byte))(number) 0 +Constant inlined testSBytes::$17 = -(number) 4 +Constant inlined testSBytes::idx#1 = ++((byte))(number) 0 +Constant inlined testSBytes::$18 = -(number) 9 +Constant inlined testSBytes::idx#0 = ((byte))(number) 0 +Constant inlined testBytes::$16 = ((byte))(number) $1000+(number) $c +Constant inlined testSBytes::$19 = -(number) 4&-(number) 9 +Constant inlined testSBytes::idx#3 = ++++++((byte))(number) 0 +Constant inlined testBytes::$17 = (number) $400 +Constant inlined testSBytes::idx#2 = ++++((byte))(number) 0 +Successful SSA optimization Pass2ConstantInlining +Consolidated array index constant in *(testBytes::SCREEN#0+((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++++++++++++((byte))0) +Consolidated array index constant in *(testBytes::SCREEN#0+++++++++++++++++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++++++++++++((byte))0) +Consolidated array index constant in *(testSBytes::SCREEN#0+++++++++++++++++++++++((byte))0) +Successful SSA optimization Pass2ConstantAdditionElimination +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant plus zero testBytes::SCREEN#0+0 +Simplifying constant integer increment ++0 +Simplifying constant integer increment ++0 +Simplifying constant integer increment ++1 +Simplifying constant integer increment ++2 +Simplifying constant integer increment ++3 +Simplifying constant integer increment ++4 +Simplifying constant integer increment ++5 +Simplifying constant integer increment ++6 +Simplifying constant integer increment ++7 +Simplifying constant integer increment ++8 +Simplifying constant integer increment ++9 +Simplifying constant integer increment ++$a +Simplifying constant plus zero testSBytes::SCREEN#0+0 +Simplifying constant integer increment ++0 +Simplifying constant integer increment ++0 +Simplifying constant integer increment ++1 +Simplifying constant integer increment ++2 +Simplifying constant integer increment ++3 +Simplifying constant integer increment ++4 +Simplifying constant integer increment ++5 +Simplifying constant integer increment ++6 +Simplifying constant integer increment ++7 +Simplifying constant integer increment ++8 +Simplifying constant integer increment ++9 +Successful SSA optimization Pass2ConstantSimplification +Simplifying constant integer increment ++1 +Simplifying constant integer increment ++2 +Simplifying constant integer increment ++3 +Simplifying constant integer increment ++4 +Simplifying constant integer increment ++5 +Simplifying constant integer increment ++6 +Simplifying constant integer increment ++7 +Simplifying constant integer increment ++8 +Simplifying constant integer increment ++9 +Simplifying constant integer increment ++$a +Simplifying constant integer increment ++$b +Simplifying constant integer increment ++1 +Simplifying constant integer increment ++2 +Simplifying constant integer increment ++3 +Simplifying constant integer increment ++4 +Simplifying constant integer increment ++5 +Simplifying constant integer increment ++6 +Simplifying constant integer increment ++7 +Simplifying constant integer increment ++8 +Simplifying constant integer increment ++9 +Simplifying constant integer increment ++$a +Successful SSA optimization Pass2ConstantSimplification +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @3 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 +CALL GRAPH +Calls in [] to main:2 +Calls in [main] to testBytes:5 testSBytes:7 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Renumbering block @3 to @1 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@1 + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + [5] call testBytes + to:main::@1 +main::@1: scope:[main] from main + [6] phi() + [7] call testSBytes + to:main::@return +main::@return: scope:[main] from main::@1 + [8] return + to:@return +testSBytes: scope:[testSBytes] from main::@1 + [9] *((const signed byte*) testSBytes::SCREEN#0) ← ((signed byte))-(number) $c + [10] *((const signed byte*) testSBytes::SCREEN#0+(number) 1) ← ((signed byte))-(number) 6-(number) 6 + [11] *((const signed byte*) testSBytes::SCREEN#0+(number) 2) ← ((signed byte))-(number) $12+(number) 6 + [12] *((const signed byte*) testSBytes::SCREEN#0+(number) 3) ← ((signed byte))-(number) $714+(number) $708 + [13] *((const signed byte*) testSBytes::SCREEN#0+(number) 4) ← ((signed byte))-(number) 1-(number) 2-(number) 3-(number) 6 + [14] *((const signed byte*) testSBytes::SCREEN#0+(number) 5) ← ((signed byte))-(number) 2*(number) 6 + [15] *((const signed byte*) testSBytes::SCREEN#0+(number) 6) ← ((signed byte))-(number) 3<<(number) 2 + [16] *((const signed byte*) testSBytes::SCREEN#0+(number) 7) ← ((signed byte))-(number) $18>>(number) 1 + [17] *((const signed byte*) testSBytes::SCREEN#0+(number) 8) ← ((signed byte))-(number) 4&-(number) 9 + [18] *((const signed byte*) testSBytes::SCREEN#0+(number) 9) ← ((signed byte))-(number) $10|-(number) $fc + [19] *((const signed byte*) testSBytes::SCREEN#0+(number) $a) ← ((signed byte))-(number) 2-(number) 2*(number) $f/(number) 5 + [20] *((const signed byte*) testSBytes::SCREEN#0+(number) $b) ← ((signed byte))(number) $1000-(number) $c + to:testSBytes::@return +testSBytes::@return: scope:[testSBytes] from testSBytes + [21] return + to:@return +testBytes: scope:[testBytes] from main + [22] *((const byte*) testBytes::SCREEN#0) ← (byte) $c + [23] *((const byte*) testBytes::SCREEN#0+(number) 1) ← ((byte))(number) 6+(number) 6 + [24] *((const byte*) testBytes::SCREEN#0+(number) 2) ← ((byte))(number) $12-(number) 6 + [25] *((const byte*) testBytes::SCREEN#0+(number) 3) ← ((byte))(number) $714-(number) $708 + [26] *((const byte*) testBytes::SCREEN#0+(number) 4) ← ((byte))(number) 1+(number) 2+(number) 3+(number) 6 + [27] *((const byte*) testBytes::SCREEN#0+(number) 5) ← ((byte))(number) 2*(number) 6 + [28] *((const byte*) testBytes::SCREEN#0+(number) 6) ← ((byte))(number) 3<<(number) 2 + [29] *((const byte*) testBytes::SCREEN#0+(number) 7) ← ((byte))(number) $18>>(number) 1 + [30] *((const byte*) testBytes::SCREEN#0+(number) 8) ← ((byte))(number) $f&(number) $1c + [31] *((const byte*) testBytes::SCREEN#0+(number) 9) ← ((byte))(number) 4|(number) 8 + [32] *((const byte*) testBytes::SCREEN#0+(number) $a) ← ((byte))(number) 5^(number) 9 + [33] *((const byte*) testBytes::SCREEN#0+(number) $b) ← ((byte))(number) 2+(number) 2*(number) $f/(number) 5 + [34] *((const byte*) testBytes::SCREEN#0+(number) $c) ← ((byte))(number) $1000+(number) $c + to:testBytes::@return +testBytes::@return: scope:[testBytes] from testBytes + [35] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(void()) testBytes() +(byte*) testBytes::SCREEN +(byte) testBytes::idx +(void()) testSBytes() +(signed byte*) testSBytes::SCREEN +(byte) testSBytes::idx + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +//SEG0 File Comments +// Tests the number type used for constant expressions +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + //SEG11 [5] call testBytes + jsr testBytes + //SEG12 [6] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + jmp b1 + //SEG13 main::@1 + b1: + //SEG14 [7] call testSBytes + jsr testSBytes + jmp breturn + //SEG15 main::@return + breturn: + //SEG16 [8] return + rts +} +//SEG17 testSBytes +testSBytes: { + // Constant values resolvable to signed bytes + .label SCREEN = $428 + //SEG18 [9] *((const signed byte*) testSBytes::SCREEN#0) ← ((signed byte))-(number) $c -- _deref_pbsc1=vbsc2 + lda #-$c + sta SCREEN + //SEG19 [10] *((const signed byte*) testSBytes::SCREEN#0+(number) 1) ← ((signed byte))-(number) 6-(number) 6 -- _deref_pbsc1=vbsc2 + lda #-6-6 + sta SCREEN+1 + //SEG20 [11] *((const signed byte*) testSBytes::SCREEN#0+(number) 2) ← ((signed byte))-(number) $12+(number) 6 -- _deref_pbsc1=vbsc2 + lda #-$12+6 + sta SCREEN+2 + //SEG21 [12] *((const signed byte*) testSBytes::SCREEN#0+(number) 3) ← ((signed byte))-(number) $714+(number) $708 -- _deref_pbsc1=vbsc2 + lda #-$714+$708 + sta SCREEN+3 + //SEG22 [13] *((const signed byte*) testSBytes::SCREEN#0+(number) 4) ← ((signed byte))-(number) 1-(number) 2-(number) 3-(number) 6 -- _deref_pbsc1=vbsc2 + lda #-1-2-3-6 + sta SCREEN+4 + //SEG23 [14] *((const signed byte*) testSBytes::SCREEN#0+(number) 5) ← ((signed byte))-(number) 2*(number) 6 -- _deref_pbsc1=vbsc2 + lda #-2*6 + sta SCREEN+5 + //SEG24 [15] *((const signed byte*) testSBytes::SCREEN#0+(number) 6) ← ((signed byte))-(number) 3<<(number) 2 -- _deref_pbsc1=vbsc2 + lda #-3<<2 + sta SCREEN+6 + //SEG25 [16] *((const signed byte*) testSBytes::SCREEN#0+(number) 7) ← ((signed byte))-(number) $18>>(number) 1 -- _deref_pbsc1=vbsc2 + lda #-$18>>1 + sta SCREEN+7 + //SEG26 [17] *((const signed byte*) testSBytes::SCREEN#0+(number) 8) ← ((signed byte))-(number) 4&-(number) 9 -- _deref_pbsc1=vbsc2 + lda #-4&-9 + sta SCREEN+8 + //SEG27 [18] *((const signed byte*) testSBytes::SCREEN#0+(number) 9) ← ((signed byte))-(number) $10|-(number) $fc -- _deref_pbsc1=vbsc2 + lda #-$10|-$fc + sta SCREEN+9 + //SEG28 [19] *((const signed byte*) testSBytes::SCREEN#0+(number) $a) ← ((signed byte))-(number) 2-(number) 2*(number) $f/(number) 5 -- _deref_pbsc1=vbsc2 + lda #(-2-2)*$f/5 + sta SCREEN+$a + //SEG29 [20] *((const signed byte*) testSBytes::SCREEN#0+(number) $b) ← ((signed byte))(number) $1000-(number) $c -- _deref_pbsc1=vbsc2 + lda #$ff&$1000-$c + sta SCREEN+$b + jmp breturn + //SEG30 testSBytes::@return + breturn: + //SEG31 [21] return + rts +} +//SEG32 testBytes +testBytes: { + // Constant values resolvable to bytes + .label SCREEN = $400 + //SEG33 [22] *((const byte*) testBytes::SCREEN#0) ← (byte) $c -- _deref_pbuc1=vbuc2 + lda #$c + sta SCREEN + //SEG34 [23] *((const byte*) testBytes::SCREEN#0+(number) 1) ← ((byte))(number) 6+(number) 6 -- _deref_pbuc1=vbuc2 + lda #6+6 + sta SCREEN+1 + //SEG35 [24] *((const byte*) testBytes::SCREEN#0+(number) 2) ← ((byte))(number) $12-(number) 6 -- _deref_pbuc1=vbuc2 + lda #$12-6 + sta SCREEN+2 + //SEG36 [25] *((const byte*) testBytes::SCREEN#0+(number) 3) ← ((byte))(number) $714-(number) $708 -- _deref_pbuc1=vbuc2 + lda #$714-$708 + sta SCREEN+3 + //SEG37 [26] *((const byte*) testBytes::SCREEN#0+(number) 4) ← ((byte))(number) 1+(number) 2+(number) 3+(number) 6 -- _deref_pbuc1=vbuc2 + lda #1+2+3+6 + sta SCREEN+4 + //SEG38 [27] *((const byte*) testBytes::SCREEN#0+(number) 5) ← ((byte))(number) 2*(number) 6 -- _deref_pbuc1=vbuc2 + lda #2*6 + sta SCREEN+5 + //SEG39 [28] *((const byte*) testBytes::SCREEN#0+(number) 6) ← ((byte))(number) 3<<(number) 2 -- _deref_pbuc1=vbuc2 + lda #3<<2 + sta SCREEN+6 + //SEG40 [29] *((const byte*) testBytes::SCREEN#0+(number) 7) ← ((byte))(number) $18>>(number) 1 -- _deref_pbuc1=vbuc2 + lda #$18>>1 + sta SCREEN+7 + //SEG41 [30] *((const byte*) testBytes::SCREEN#0+(number) 8) ← ((byte))(number) $f&(number) $1c -- _deref_pbuc1=vbuc2 + lda #$f&$1c + sta SCREEN+8 + //SEG42 [31] *((const byte*) testBytes::SCREEN#0+(number) 9) ← ((byte))(number) 4|(number) 8 -- _deref_pbuc1=vbuc2 + lda #4|8 + sta SCREEN+9 + //SEG43 [32] *((const byte*) testBytes::SCREEN#0+(number) $a) ← ((byte))(number) 5^(number) 9 -- _deref_pbuc1=vbuc2 + lda #5^9 + sta SCREEN+$a + //SEG44 [33] *((const byte*) testBytes::SCREEN#0+(number) $b) ← ((byte))(number) 2+(number) 2*(number) $f/(number) 5 -- _deref_pbuc1=vbuc2 + lda #(2+2)*$f/5 + sta SCREEN+$b + //SEG45 [34] *((const byte*) testBytes::SCREEN#0+(number) $c) ← ((byte))(number) $1000+(number) $c -- _deref_pbuc1=vbuc2 + lda #$ff&$1000+$c + sta SCREEN+$c + jmp breturn + //SEG46 testBytes::@return + breturn: + //SEG47 [35] return + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [9] *((const signed byte*) testSBytes::SCREEN#0) ← ((signed byte))-(number) $c [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [10] *((const signed byte*) testSBytes::SCREEN#0+(number) 1) ← ((signed byte))-(number) 6-(number) 6 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [11] *((const signed byte*) testSBytes::SCREEN#0+(number) 2) ← ((signed byte))-(number) $12+(number) 6 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [12] *((const signed byte*) testSBytes::SCREEN#0+(number) 3) ← ((signed byte))-(number) $714+(number) $708 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [13] *((const signed byte*) testSBytes::SCREEN#0+(number) 4) ← ((signed byte))-(number) 1-(number) 2-(number) 3-(number) 6 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [14] *((const signed byte*) testSBytes::SCREEN#0+(number) 5) ← ((signed byte))-(number) 2*(number) 6 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [15] *((const signed byte*) testSBytes::SCREEN#0+(number) 6) ← ((signed byte))-(number) 3<<(number) 2 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [16] *((const signed byte*) testSBytes::SCREEN#0+(number) 7) ← ((signed byte))-(number) $18>>(number) 1 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [17] *((const signed byte*) testSBytes::SCREEN#0+(number) 8) ← ((signed byte))-(number) 4&-(number) 9 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [18] *((const signed byte*) testSBytes::SCREEN#0+(number) 9) ← ((signed byte))-(number) $10|-(number) $fc [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [19] *((const signed byte*) testSBytes::SCREEN#0+(number) $a) ← ((signed byte))-(number) 2-(number) 2*(number) $f/(number) 5 [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [20] *((const signed byte*) testSBytes::SCREEN#0+(number) $b) ← ((signed byte))(number) $1000-(number) $c [ ] ( main:2::testSBytes:7 [ ] ) always clobbers reg byte a +Statement [22] *((const byte*) testBytes::SCREEN#0) ← (byte) $c [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [23] *((const byte*) testBytes::SCREEN#0+(number) 1) ← ((byte))(number) 6+(number) 6 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [24] *((const byte*) testBytes::SCREEN#0+(number) 2) ← ((byte))(number) $12-(number) 6 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [25] *((const byte*) testBytes::SCREEN#0+(number) 3) ← ((byte))(number) $714-(number) $708 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [26] *((const byte*) testBytes::SCREEN#0+(number) 4) ← ((byte))(number) 1+(number) 2+(number) 3+(number) 6 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [27] *((const byte*) testBytes::SCREEN#0+(number) 5) ← ((byte))(number) 2*(number) 6 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [28] *((const byte*) testBytes::SCREEN#0+(number) 6) ← ((byte))(number) 3<<(number) 2 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [29] *((const byte*) testBytes::SCREEN#0+(number) 7) ← ((byte))(number) $18>>(number) 1 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [30] *((const byte*) testBytes::SCREEN#0+(number) 8) ← ((byte))(number) $f&(number) $1c [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [31] *((const byte*) testBytes::SCREEN#0+(number) 9) ← ((byte))(number) 4|(number) 8 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [32] *((const byte*) testBytes::SCREEN#0+(number) $a) ← ((byte))(number) 5^(number) 9 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [33] *((const byte*) testBytes::SCREEN#0+(number) $b) ← ((byte))(number) 2+(number) 2*(number) $f/(number) 5 [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a +Statement [34] *((const byte*) testBytes::SCREEN#0+(number) $c) ← ((byte))(number) $1000+(number) $c [ ] ( main:2::testBytes:5 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [testBytes] +Uplift Scope [testSBytes] +Uplift Scope [] + +Uplifting [main] best 204 combination +Uplifting [testBytes] best 204 combination +Uplifting [testSBytes] best 204 combination +Uplifting [] best 204 combination + +ASSEMBLER BEFORE OPTIMIZATION +//SEG0 File Comments +// Tests the number type used for constant expressions +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +bbegin: +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +b1_from_bbegin: + jmp b1 +//SEG5 @1 +b1: +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +main_from_b1: + jsr main +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +bend_from_b1: + jmp bend +//SEG9 @end +bend: +//SEG10 main +main: { + //SEG11 [5] call testBytes + jsr testBytes + //SEG12 [6] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + jmp b1 + //SEG13 main::@1 + b1: + //SEG14 [7] call testSBytes + jsr testSBytes + jmp breturn + //SEG15 main::@return + breturn: + //SEG16 [8] return + rts +} +//SEG17 testSBytes +testSBytes: { + // Constant values resolvable to signed bytes + .label SCREEN = $428 + //SEG18 [9] *((const signed byte*) testSBytes::SCREEN#0) ← ((signed byte))-(number) $c -- _deref_pbsc1=vbsc2 + lda #-$c + sta SCREEN + //SEG19 [10] *((const signed byte*) testSBytes::SCREEN#0+(number) 1) ← ((signed byte))-(number) 6-(number) 6 -- _deref_pbsc1=vbsc2 + lda #-6-6 + sta SCREEN+1 + //SEG20 [11] *((const signed byte*) testSBytes::SCREEN#0+(number) 2) ← ((signed byte))-(number) $12+(number) 6 -- _deref_pbsc1=vbsc2 + lda #-$12+6 + sta SCREEN+2 + //SEG21 [12] *((const signed byte*) testSBytes::SCREEN#0+(number) 3) ← ((signed byte))-(number) $714+(number) $708 -- _deref_pbsc1=vbsc2 + lda #-$714+$708 + sta SCREEN+3 + //SEG22 [13] *((const signed byte*) testSBytes::SCREEN#0+(number) 4) ← ((signed byte))-(number) 1-(number) 2-(number) 3-(number) 6 -- _deref_pbsc1=vbsc2 + lda #-1-2-3-6 + sta SCREEN+4 + //SEG23 [14] *((const signed byte*) testSBytes::SCREEN#0+(number) 5) ← ((signed byte))-(number) 2*(number) 6 -- _deref_pbsc1=vbsc2 + lda #-2*6 + sta SCREEN+5 + //SEG24 [15] *((const signed byte*) testSBytes::SCREEN#0+(number) 6) ← ((signed byte))-(number) 3<<(number) 2 -- _deref_pbsc1=vbsc2 + lda #-3<<2 + sta SCREEN+6 + //SEG25 [16] *((const signed byte*) testSBytes::SCREEN#0+(number) 7) ← ((signed byte))-(number) $18>>(number) 1 -- _deref_pbsc1=vbsc2 + lda #-$18>>1 + sta SCREEN+7 + //SEG26 [17] *((const signed byte*) testSBytes::SCREEN#0+(number) 8) ← ((signed byte))-(number) 4&-(number) 9 -- _deref_pbsc1=vbsc2 + lda #-4&-9 + sta SCREEN+8 + //SEG27 [18] *((const signed byte*) testSBytes::SCREEN#0+(number) 9) ← ((signed byte))-(number) $10|-(number) $fc -- _deref_pbsc1=vbsc2 + lda #-$10|-$fc + sta SCREEN+9 + //SEG28 [19] *((const signed byte*) testSBytes::SCREEN#0+(number) $a) ← ((signed byte))-(number) 2-(number) 2*(number) $f/(number) 5 -- _deref_pbsc1=vbsc2 + lda #(-2-2)*$f/5 + sta SCREEN+$a + //SEG29 [20] *((const signed byte*) testSBytes::SCREEN#0+(number) $b) ← ((signed byte))(number) $1000-(number) $c -- _deref_pbsc1=vbsc2 + lda #$ff&$1000-$c + sta SCREEN+$b + jmp breturn + //SEG30 testSBytes::@return + breturn: + //SEG31 [21] return + rts +} +//SEG32 testBytes +testBytes: { + // Constant values resolvable to bytes + .label SCREEN = $400 + //SEG33 [22] *((const byte*) testBytes::SCREEN#0) ← (byte) $c -- _deref_pbuc1=vbuc2 + lda #$c + sta SCREEN + //SEG34 [23] *((const byte*) testBytes::SCREEN#0+(number) 1) ← ((byte))(number) 6+(number) 6 -- _deref_pbuc1=vbuc2 + lda #6+6 + sta SCREEN+1 + //SEG35 [24] *((const byte*) testBytes::SCREEN#0+(number) 2) ← ((byte))(number) $12-(number) 6 -- _deref_pbuc1=vbuc2 + lda #$12-6 + sta SCREEN+2 + //SEG36 [25] *((const byte*) testBytes::SCREEN#0+(number) 3) ← ((byte))(number) $714-(number) $708 -- _deref_pbuc1=vbuc2 + lda #$714-$708 + sta SCREEN+3 + //SEG37 [26] *((const byte*) testBytes::SCREEN#0+(number) 4) ← ((byte))(number) 1+(number) 2+(number) 3+(number) 6 -- _deref_pbuc1=vbuc2 + lda #1+2+3+6 + sta SCREEN+4 + //SEG38 [27] *((const byte*) testBytes::SCREEN#0+(number) 5) ← ((byte))(number) 2*(number) 6 -- _deref_pbuc1=vbuc2 + lda #2*6 + sta SCREEN+5 + //SEG39 [28] *((const byte*) testBytes::SCREEN#0+(number) 6) ← ((byte))(number) 3<<(number) 2 -- _deref_pbuc1=vbuc2 + lda #3<<2 + sta SCREEN+6 + //SEG40 [29] *((const byte*) testBytes::SCREEN#0+(number) 7) ← ((byte))(number) $18>>(number) 1 -- _deref_pbuc1=vbuc2 + lda #$18>>1 + sta SCREEN+7 + //SEG41 [30] *((const byte*) testBytes::SCREEN#0+(number) 8) ← ((byte))(number) $f&(number) $1c -- _deref_pbuc1=vbuc2 + lda #$f&$1c + sta SCREEN+8 + //SEG42 [31] *((const byte*) testBytes::SCREEN#0+(number) 9) ← ((byte))(number) 4|(number) 8 -- _deref_pbuc1=vbuc2 + lda #4|8 + sta SCREEN+9 + //SEG43 [32] *((const byte*) testBytes::SCREEN#0+(number) $a) ← ((byte))(number) 5^(number) 9 -- _deref_pbuc1=vbuc2 + lda #5^9 + sta SCREEN+$a + //SEG44 [33] *((const byte*) testBytes::SCREEN#0+(number) $b) ← ((byte))(number) 2+(number) 2*(number) $f/(number) 5 -- _deref_pbuc1=vbuc2 + lda #(2+2)*$f/5 + sta SCREEN+$b + //SEG45 [34] *((const byte*) testBytes::SCREEN#0+(number) $c) ← ((byte))(number) $1000+(number) $c -- _deref_pbuc1=vbuc2 + lda #$ff&$1000+$c + sta SCREEN+$c + jmp breturn + //SEG46 testBytes::@return + breturn: + //SEG47 [35] return + rts +} + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp breturn +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Removing instruction b1_from_main: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction b1: +Removing instruction breturn: +Removing instruction breturn: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Updating BasicUpstart to call main directly +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin +Removing instruction bbegin: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@1 +(label) main::@return +(void()) testBytes() +(label) testBytes::@return +(byte*) testBytes::SCREEN +(const byte*) testBytes::SCREEN#0 SCREEN = ((byte*))(number) $400 +(byte) testBytes::idx +(void()) testSBytes() +(label) testSBytes::@return +(signed byte*) testSBytes::SCREEN +(const signed byte*) testSBytes::SCREEN#0 SCREEN = ((signed byte*))(number) $428 +(byte) testSBytes::idx + + + +FINAL ASSEMBLER +Score: 180 + +//SEG0 File Comments +// Tests the number type used for constant expressions +//SEG1 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG2 Global Constants & labels +//SEG3 @begin +//SEG4 [1] phi from @begin to @1 [phi:@begin->@1] +//SEG5 @1 +//SEG6 [2] call main +//SEG7 [4] phi from @1 to main [phi:@1->main] +//SEG8 [3] phi from @1 to @end [phi:@1->@end] +//SEG9 @end +//SEG10 main +main: { + //SEG11 [5] call testBytes + jsr testBytes + //SEG12 [6] phi from main to main::@1 [phi:main->main::@1] + //SEG13 main::@1 + //SEG14 [7] call testSBytes + jsr testSBytes + //SEG15 main::@return + //SEG16 [8] return + rts +} +//SEG17 testSBytes +testSBytes: { + // Constant values resolvable to signed bytes + .label SCREEN = $428 + //SEG18 [9] *((const signed byte*) testSBytes::SCREEN#0) ← ((signed byte))-(number) $c -- _deref_pbsc1=vbsc2 + lda #-$c + sta SCREEN + //SEG19 [10] *((const signed byte*) testSBytes::SCREEN#0+(number) 1) ← ((signed byte))-(number) 6-(number) 6 -- _deref_pbsc1=vbsc2 + lda #-6-6 + sta SCREEN+1 + //SEG20 [11] *((const signed byte*) testSBytes::SCREEN#0+(number) 2) ← ((signed byte))-(number) $12+(number) 6 -- _deref_pbsc1=vbsc2 + lda #-$12+6 + sta SCREEN+2 + //SEG21 [12] *((const signed byte*) testSBytes::SCREEN#0+(number) 3) ← ((signed byte))-(number) $714+(number) $708 -- _deref_pbsc1=vbsc2 + lda #-$714+$708 + sta SCREEN+3 + //SEG22 [13] *((const signed byte*) testSBytes::SCREEN#0+(number) 4) ← ((signed byte))-(number) 1-(number) 2-(number) 3-(number) 6 -- _deref_pbsc1=vbsc2 + lda #-1-2-3-6 + sta SCREEN+4 + //SEG23 [14] *((const signed byte*) testSBytes::SCREEN#0+(number) 5) ← ((signed byte))-(number) 2*(number) 6 -- _deref_pbsc1=vbsc2 + lda #-2*6 + sta SCREEN+5 + //SEG24 [15] *((const signed byte*) testSBytes::SCREEN#0+(number) 6) ← ((signed byte))-(number) 3<<(number) 2 -- _deref_pbsc1=vbsc2 + lda #-3<<2 + sta SCREEN+6 + //SEG25 [16] *((const signed byte*) testSBytes::SCREEN#0+(number) 7) ← ((signed byte))-(number) $18>>(number) 1 -- _deref_pbsc1=vbsc2 + lda #-$18>>1 + sta SCREEN+7 + //SEG26 [17] *((const signed byte*) testSBytes::SCREEN#0+(number) 8) ← ((signed byte))-(number) 4&-(number) 9 -- _deref_pbsc1=vbsc2 + lda #-4&-9 + sta SCREEN+8 + //SEG27 [18] *((const signed byte*) testSBytes::SCREEN#0+(number) 9) ← ((signed byte))-(number) $10|-(number) $fc -- _deref_pbsc1=vbsc2 + lda #-$10|-$fc + sta SCREEN+9 + //SEG28 [19] *((const signed byte*) testSBytes::SCREEN#0+(number) $a) ← ((signed byte))-(number) 2-(number) 2*(number) $f/(number) 5 -- _deref_pbsc1=vbsc2 + lda #(-2-2)*$f/5 + sta SCREEN+$a + //SEG29 [20] *((const signed byte*) testSBytes::SCREEN#0+(number) $b) ← ((signed byte))(number) $1000-(number) $c -- _deref_pbsc1=vbsc2 + lda #$ff&$1000-$c + sta SCREEN+$b + //SEG30 testSBytes::@return + //SEG31 [21] return + rts +} +//SEG32 testBytes +testBytes: { + // Constant values resolvable to bytes + .label SCREEN = $400 + //SEG33 [22] *((const byte*) testBytes::SCREEN#0) ← (byte) $c -- _deref_pbuc1=vbuc2 + lda #$c + sta SCREEN + //SEG34 [23] *((const byte*) testBytes::SCREEN#0+(number) 1) ← ((byte))(number) 6+(number) 6 -- _deref_pbuc1=vbuc2 + lda #6+6 + sta SCREEN+1 + //SEG35 [24] *((const byte*) testBytes::SCREEN#0+(number) 2) ← ((byte))(number) $12-(number) 6 -- _deref_pbuc1=vbuc2 + lda #$12-6 + sta SCREEN+2 + //SEG36 [25] *((const byte*) testBytes::SCREEN#0+(number) 3) ← ((byte))(number) $714-(number) $708 -- _deref_pbuc1=vbuc2 + lda #$714-$708 + sta SCREEN+3 + //SEG37 [26] *((const byte*) testBytes::SCREEN#0+(number) 4) ← ((byte))(number) 1+(number) 2+(number) 3+(number) 6 -- _deref_pbuc1=vbuc2 + lda #1+2+3+6 + sta SCREEN+4 + //SEG38 [27] *((const byte*) testBytes::SCREEN#0+(number) 5) ← ((byte))(number) 2*(number) 6 -- _deref_pbuc1=vbuc2 + lda #2*6 + sta SCREEN+5 + //SEG39 [28] *((const byte*) testBytes::SCREEN#0+(number) 6) ← ((byte))(number) 3<<(number) 2 -- _deref_pbuc1=vbuc2 + lda #3<<2 + sta SCREEN+6 + //SEG40 [29] *((const byte*) testBytes::SCREEN#0+(number) 7) ← ((byte))(number) $18>>(number) 1 -- _deref_pbuc1=vbuc2 + lda #$18>>1 + sta SCREEN+7 + //SEG41 [30] *((const byte*) testBytes::SCREEN#0+(number) 8) ← ((byte))(number) $f&(number) $1c -- _deref_pbuc1=vbuc2 + lda #$f&$1c + sta SCREEN+8 + //SEG42 [31] *((const byte*) testBytes::SCREEN#0+(number) 9) ← ((byte))(number) 4|(number) 8 -- _deref_pbuc1=vbuc2 + lda #4|8 + sta SCREEN+9 + //SEG43 [32] *((const byte*) testBytes::SCREEN#0+(number) $a) ← ((byte))(number) 5^(number) 9 -- _deref_pbuc1=vbuc2 + lda #5^9 + sta SCREEN+$a + //SEG44 [33] *((const byte*) testBytes::SCREEN#0+(number) $b) ← ((byte))(number) 2+(number) 2*(number) $f/(number) 5 -- _deref_pbuc1=vbuc2 + lda #(2+2)*$f/5 + sta SCREEN+$b + //SEG45 [34] *((const byte*) testBytes::SCREEN#0+(number) $c) ← ((byte))(number) $1000+(number) $c -- _deref_pbuc1=vbuc2 + lda #$ff&$1000+$c + sta SCREEN+$c + //SEG46 testBytes::@return + //SEG47 [35] return + rts +} + diff --git a/src/test/ref/number-type.sym b/src/test/ref/number-type.sym new file mode 100644 index 000000000..fa464be74 --- /dev/null +++ b/src/test/ref/number-type.sym @@ -0,0 +1,17 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@1 +(label) main::@return +(void()) testBytes() +(label) testBytes::@return +(byte*) testBytes::SCREEN +(const byte*) testBytes::SCREEN#0 SCREEN = ((byte*))(number) $400 +(byte) testBytes::idx +(void()) testSBytes() +(label) testSBytes::@return +(signed byte*) testSBytes::SCREEN +(const signed byte*) testSBytes::SCREEN#0 SCREEN = ((signed byte*))(number) $428 +(byte) testSBytes::idx + diff --git a/src/test/ref/operator-lohi-problem.asm b/src/test/ref/operator-lohi-problem.asm index 83e1032ff..332ca079f 100644 --- a/src/test/ref/operator-lohi-problem.asm +++ b/src/test/ref/operator-lohi-problem.asm @@ -9,11 +9,9 @@ .label SCREEN = $400 main: { .const dw = $2000 - .const w1 = dw&$ffff - .const w2 = w1 sta SCREEN+1 lda #msg1 - sta first.msg+1 + sta first.return+1 jsr first ldy #0 - lda (_1),y + lda (_0),y sta SCREEN lda #msg2 - sta first.msg+1 + sta first.return+1 jsr first ldy #0 - lda (_3),y + lda (_2),y sta SCREEN+1 rts } -// first(byte* zeropage(2) msg) first: { .label return = 2 - .label msg = 2 rts } msg1: .text "hello world!@" diff --git a/src/test/ref/pointer-pointer-3.asm b/src/test/ref/pointer-pointer-3.asm index 8d95438d3..079d897cf 100644 --- a/src/test/ref/pointer-pointer-3.asm +++ b/src/test/ref/pointer-pointer-3.asm @@ -4,7 +4,7 @@ .pc = $80d "Program" .label screen1 = $400 .label screen2 = $400+$28 - .label screen = 6 + .label screen = 4 bbegin: lda #<$400 sta screen @@ -13,10 +13,6 @@ bbegin: jsr main rts main: { - lda #screen - sta setscreen.screen+1 lda #screen1 @@ -25,10 +21,6 @@ main: { lda #'a' ldy #0 sta (screen),y - lda #screen - sta setscreen.screen+1 lda #screen2 @@ -39,15 +31,12 @@ main: { sta (screen),y rts } -// setscreen(byte** zeropage(4) screen, byte* zeropage(2) val) +// setscreen(byte* zeropage(2) val) setscreen: { .label val = 2 - .label screen = 4 - ldy #0 lda val - sta (screen),y - iny + sta screen lda val+1 - sta (screen),y + sta screen+1 rts } diff --git a/src/test/ref/ptr-complex.asm b/src/test/ref/ptr-complex.asm index 214144b95..e8ef78d97 100644 --- a/src/test/ref/ptr-complex.asm +++ b/src/test/ref/ptr-complex.asm @@ -7,7 +7,6 @@ main: { .label screen = $400 // Increment on a const named pointer .label BGCOL = $d020 - .label sc2 = screen+$51 ldx #0 // RValue pointer expression (variable) b1: @@ -17,7 +16,7 @@ main: { cpx #$b bne b1 lda screen+$79 - sta sc2 + sta screen+$51 // LValue pointer expression (constant - directly) lda screen+$7a sta screen+$52 diff --git a/src/test/ref/ptrptr-optimize-0.asm b/src/test/ref/ptrptr-optimize-0.asm new file mode 100644 index 000000000..bcfea43c8 --- /dev/null +++ b/src/test/ref/ptrptr-optimize-0.asm @@ -0,0 +1,23 @@ +// Tests optimization of constant pointers to pointers +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label pscreen = screen + .label screen = 2 + lda #<$400 + sta screen + lda #>$400 + sta screen+1 + lda #'a' + ldy #0 + sta (pscreen),y + inc pscreen + bne !+ + inc pscreen+1 + !: + lda #'b' + ldy #0 + sta (pscreen),y + rts +} diff --git a/src/test/ref/ptrptr-optimize-1.asm b/src/test/ref/ptrptr-optimize-1.asm new file mode 100644 index 000000000..5bb1ace96 --- /dev/null +++ b/src/test/ref/ptrptr-optimize-1.asm @@ -0,0 +1,27 @@ +// Tests optimization of constant pointers to pointers +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label pscreen = screen + .label screen = 2 + lda #<$400 + sta screen + lda #>$400 + sta screen+1 + lda #'a' + jsr sub + lda #'b' + jsr sub + rts +} +// sub(byte register(A) ch) +sub: { + ldy #0 + sta (main.pscreen),y + inc main.pscreen + bne !+ + inc main.pscreen+1 + !: + rts +} diff --git a/src/test/ref/ptrptr-optimize-2.asm b/src/test/ref/ptrptr-optimize-2.asm new file mode 100644 index 000000000..afc340a19 --- /dev/null +++ b/src/test/ref/ptrptr-optimize-2.asm @@ -0,0 +1,27 @@ +// Tests (non-)optimization of constant pointers to pointers +// The two examples of &screen is not detected as identical leading to ASM that could be optimized more +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = 2 + lda #<$400 + sta screen + lda #>$400 + sta screen+1 + lda #'a' + jsr sub + lda #'b' + jsr sub + rts +} +// sub(byte register(A) ch) +sub: { + ldy #0 + sta (main.screen),y + inc main.screen + bne !+ + inc main.screen+1 + !: + rts +} diff --git a/src/test/ref/roll-sprite-msb.asm b/src/test/ref/roll-sprite-msb.asm index 80b22ddde..e338a5605 100644 --- a/src/test/ref/roll-sprite-msb.asm +++ b/src/test/ref/roll-sprite-msb.asm @@ -37,9 +37,6 @@ position_sprite: { tay lda #y sta SPRITES_YPOS,y - lda spriteno - asl - tay lda x sta SPRITES_XPOS,y lda x+1 diff --git a/src/test/ref/sandbox-ternary-error.asm b/src/test/ref/sandbox-ternary-error.asm index cf9c393e2..a599c7f2c 100644 --- a/src/test/ref/sandbox-ternary-error.asm +++ b/src/test/ref/sandbox-ternary-error.asm @@ -7,15 +7,15 @@ main: { ldx #0 b1: cpx #0 - beq b4 - cpx #1 beq b2 + cpx #1 + beq b4 lda #'c' jmp b3 - b2: + b4: lda #'b' jmp b3 - b4: + b2: lda #'a' b3: sta SCREEN diff --git a/src/test/ref/sandbox.asm b/src/test/ref/sandbox.asm index 83029cccc..c3437f972 100644 --- a/src/test/ref/sandbox.asm +++ b/src/test/ref/sandbox.asm @@ -152,11 +152,10 @@ Print: { } // myprintf(byte* zeropage(8) str, word zeropage(2) w1, word zeropage(4) w2, word zeropage(6) w3) myprintf: { - .label _17 = $12 .label str = 8 .label bDigits = $11 .label bLen = $10 - .label digit = $a + .label b = $a .label bArg = $b .label return = $10 .label w1 = 2 @@ -203,9 +202,14 @@ myprintf: { rts b3: cpx #'1' - bcc !b37+ - jmp b37 - !b37: + bcc b4 + cpx #'9' + bcs !b23+ + jmp b23 + !b23: + bne !b23+ + jmp b23 + !b23: b4: cpx #'-' bne b5 @@ -228,19 +232,13 @@ myprintf: { sta bFormat jmp b27 b26: - lda w+1 - sta _17+1 lda w - sta _17 - ldy #4 - !: - lsr _17+1 - ror _17 - dey - bne !- - lda _17 - and #$f - tax + lsr + lsr + lsr + lsr + ldx #$f + axs #0 cpx #$a bcc b8 lda #$57 @@ -255,8 +253,8 @@ myprintf: { sta strTemp,y iny lda w - and #$f - tax + ldx #$f + axs #0 cpx #$a bcc b10 lda #$57 @@ -277,68 +275,68 @@ myprintf: { lda w+1 sta utoa.value+1 jsr utoa - ldx #1 + lda #1 + sta b b12: - lda buf6,x + ldy b + lda buf6,y cmp #0 bne b13 lda bTrailing cmp #0 - beq b39 + bne b15 + tya + cmp bDigits + bcc b16 b15: - lda #0 - sta digit + ldx #0 b19: - ldy digit - lda buf6,y + lda buf6,x ldy bLen sta strTemp,y inc bLen - inc digit - txa - cmp digit - beq !+ - bcs b19 - !: + inx + cpx b + bcc b19 lda bTrailing cmp #0 - bne b40 + bne !b22+ jmp b22 - b40: - cpx bDigits - bcc b21 + !b22: + lda b + cmp bDigits + bcc !b22+ jmp b22 + !b22: b21: lda #' ' ldy bLen sta strTemp,y inc bLen dec bDigits - cpx bDigits + lda b + cmp bDigits bcc b21 jmp b22 - b39: - cpx bDigits - bcc b16 - jmp b15 b16: lda bLeadZero cmp #0 - beq b14 + beq b17 lda #'0' jmp b18 - b14: + b17: lda #' ' b18: ldy bLen sta strTemp,y inc bLen dec bDigits - cpx bDigits + lda b + cmp bDigits bcc b16 jmp b15 b13: - inx + inc b jmp b12 b6: lda w @@ -347,11 +345,6 @@ myprintf: { sta strTemp,y inc bLen jmp b22 - b37: - cpx #'9' - bcc b23 - beq b23 - jmp b4 b23: txa axs #'0' @@ -364,15 +357,15 @@ myprintf: { //w = (bArg == 0) ? w1 : ((bArg == 1) ? w2 : w3); -- "?" is the normal way, but error "sequence does not contain all blocks" -- https://gitlab.com/camelot/kickc/issues/185 [FIXED] lda bArg cmp #0 - beq b42 + beq b29 lda #1 cmp bArg - beq b43 + beq b30 lda w3 sta w lda w3+1 sta w+1 - b29: + b31: inc bArg lda #0 sta bLeadZero @@ -383,36 +376,32 @@ myprintf: { lda #1 sta bFormat jmp b27 - b43: + b30: lda w2 sta w lda w2+1 sta w+1 - jmp b29 - b42: + jmp b31 + b29: lda w1 sta w lda w1+1 sta w+1 - jmp b29 + jmp b31 b28: cpx #$41 - bcs b41 - b30: + bcc b32 + cpx #$5a+1 + bcs b32 + txa + axs #-[$20] + b32: // swap 0x41 / 0x61 when in lower case mode ldy bLen txa sta strTemp,y inc bLen jmp b27 - b41: - cpx #$5a+1 - bcc b35 - jmp b30 - b35: - txa - axs #-[$20] - jmp b30 buf6: .fill 6, 0 } // utoa(word zeropage($12) value, byte* zeropage($14) dst) @@ -551,9 +540,9 @@ append: { bne !+ lda sub cmp value + beq b2 !: bcc b2 - beq b2 rts b2: ldy #0 diff --git a/src/test/ref/scan-desire-problem.asm b/src/test/ref/scan-desire-problem.asm index 248cffd38..2cd3d41b5 100644 --- a/src/test/ref/scan-desire-problem.asm +++ b/src/test/ref/scan-desire-problem.asm @@ -76,6 +76,7 @@ draw_block: { asl sta x1 lda #0 + rol sta x1+1 txa asl diff --git a/src/test/ref/semi-struct-1.asm b/src/test/ref/semi-struct-1.asm index 77e06cc4d..981c26588 100644 --- a/src/test/ref/semi-struct-1.asm +++ b/src/test/ref/semi-struct-1.asm @@ -22,7 +22,7 @@ main: { } // Print points print_points: { - .label pointXpos1__0 = 9 + .label point = 9 .label i = 2 jsr print_cls lda #<$400 @@ -42,15 +42,15 @@ print_points: { tya clc adc #points adc #0 - sta pointXpos1__0+1 + sta point+1 ldx points,y jsr print_byte jsr print_str ldy #1 - lda (pointXpos1__0),y + lda (point),y tax jsr print_byte jsr print_ln @@ -168,7 +168,7 @@ print_cls: { } // Initialize points init_points: { - .label pointXpos1__0 = 3 + .label getPoint1_return = 3 .label pos = 2 lda #$a sta pos @@ -180,17 +180,17 @@ init_points: { tya clc adc #points adc #0 - sta pointXpos1__0+1 + sta getPoint1_return+1 lda pos sta points,y lda #$a clc adc pos ldy #1 - sta (pointXpos1__0),y + sta (getPoint1_return),y clc adc #$a sta pos diff --git a/src/test/ref/semi-struct-2.asm b/src/test/ref/semi-struct-2.asm index 0429bcc2f..6d4e8534f 100644 --- a/src/test/ref/semi-struct-2.asm +++ b/src/test/ref/semi-struct-2.asm @@ -37,6 +37,8 @@ .label print_line_cursor = $a .label print_line_cursor_32 = 2 .label print_line_cursor_63 = 2 + .label print_line_cursor_157 = 2 + .label print_line_cursor_158 = 2 .label print_line_cursor_159 = 2 .label print_line_cursor_160 = 2 .label print_line_cursor_161 = 2 @@ -52,9 +54,7 @@ .label print_line_cursor_171 = 2 .label print_line_cursor_172 = 2 .label print_line_cursor_173 = 2 - .label print_line_cursor_174 = 2 .label print_line_cursor_175 = 2 - .label print_line_cursor_177 = 2 // Initialize 2 file entries and print them main: { .const fileEntry1_idx = 1 @@ -114,9 +114,9 @@ main: { sta print_line_cursor_63+1 jsr print_ln lda print_line_cursor - sta print_line_cursor_159 + sta print_line_cursor_157 lda print_line_cursor+1 - sta print_line_cursor_159+1 + sta print_line_cursor_157+1 lda print_line_cursor sta print_char_cursor lda print_line_cursor+1 @@ -124,9 +124,9 @@ main: { jsr print_ln jsr printEntry lda print_line_cursor - sta print_line_cursor_160 + sta print_line_cursor_158 lda print_line_cursor+1 - sta print_line_cursor_160+1 + sta print_line_cursor_158+1 lda print_line_cursor sta print_char_cursor lda print_line_cursor+1 @@ -161,9 +161,9 @@ main: { sta print_line_cursor_63+1 jsr print_ln lda print_line_cursor - sta print_line_cursor_161 + sta print_line_cursor_159 lda print_line_cursor+1 - sta print_line_cursor_161+1 + sta print_line_cursor_159+1 lda print_line_cursor sta print_char_cursor lda print_line_cursor+1 @@ -175,9 +175,9 @@ main: { sta printEntry.entry+1 jsr printEntry lda print_line_cursor - sta print_line_cursor_162 + sta print_line_cursor_160 lda print_line_cursor+1 - sta print_line_cursor_162+1 + sta print_line_cursor_160+1 lda print_line_cursor sta print_char_cursor lda print_line_cursor+1 @@ -292,16 +292,15 @@ print_ln: { rts b2: lda print_line_cursor - sta print_line_cursor_177 + sta print_line_cursor_175 lda print_line_cursor+1 - sta print_line_cursor_177+1 + sta print_line_cursor_175+1 jmp b1 } // Print the contents of a file entry // printEntry(byte* zeropage(4) entry) printEntry: { .label entry = 4 - .label entryBufDisk1__0 = 4 lda print_line_cursor sta print_char_cursor lda print_line_cursor+1 @@ -312,16 +311,16 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #0 - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w iny - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w+1 jsr print_word lda print_line_cursor - sta print_line_cursor_163 + sta print_line_cursor_161 lda print_line_cursor+1 - sta print_line_cursor_163+1 + sta print_line_cursor_161+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -333,16 +332,16 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #2 - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w iny - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w+1 jsr print_word lda print_line_cursor - sta print_line_cursor_164 + sta print_line_cursor_162 lda print_line_cursor+1 - sta print_line_cursor_164+1 + sta print_line_cursor_162+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -354,16 +353,16 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #4 - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w iny - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w+1 jsr print_word lda print_line_cursor - sta print_line_cursor_165 + sta print_line_cursor_163 lda print_line_cursor+1 - sta print_line_cursor_165+1 + sta print_line_cursor_163+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -375,16 +374,16 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #6 - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w iny - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w+1 jsr print_word lda print_line_cursor - sta print_line_cursor_166 + sta print_line_cursor_164 lda print_line_cursor+1 - sta print_line_cursor_166+1 + sta print_line_cursor_164+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -396,13 +395,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #8 - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_167 + sta print_line_cursor_165 lda print_line_cursor+1 - sta print_line_cursor_167+1 + sta print_line_cursor_165+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -414,13 +413,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #9 - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_168 + sta print_line_cursor_166 lda print_line_cursor+1 - sta print_line_cursor_168+1 + sta print_line_cursor_166+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -432,13 +431,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$a - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_169 + sta print_line_cursor_167 lda print_line_cursor+1 - sta print_line_cursor_169+1 + sta print_line_cursor_167+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -450,13 +449,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$b - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_170 + sta print_line_cursor_168 lda print_line_cursor+1 - sta print_line_cursor_170+1 + sta print_line_cursor_168+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -468,16 +467,16 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$c - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w iny - lda (entryBufDisk1__0),y + lda (entry),y sta print_word.w+1 jsr print_word lda print_line_cursor - sta print_line_cursor_171 + sta print_line_cursor_169 lda print_line_cursor+1 - sta print_line_cursor_171+1 + sta print_line_cursor_169+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -489,13 +488,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$e - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_172 + sta print_line_cursor_170 lda print_line_cursor+1 - sta print_line_cursor_172+1 + sta print_line_cursor_170+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -507,13 +506,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$f - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_173 + sta print_line_cursor_171 lda print_line_cursor+1 - sta print_line_cursor_173+1 + sta print_line_cursor_171+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -525,13 +524,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$10 - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_174 + sta print_line_cursor_172 lda print_line_cursor+1 - sta print_line_cursor_174+1 + sta print_line_cursor_172+1 jsr print_ln lda print_line_cursor sta print_char_cursor @@ -543,13 +542,13 @@ printEntry: { sta print_str.str+1 jsr print_str ldy #$11 - lda (entryBufDisk1__0),y + lda (entry),y tax jsr print_byte lda print_line_cursor - sta print_line_cursor_175 + sta print_line_cursor_173 lda print_line_cursor+1 - sta print_line_cursor_175+1 + sta print_line_cursor_173+1 jsr print_ln rts str: .text "bufdisk @" @@ -616,7 +615,6 @@ initEntry: { .label _7 = 6 .label _17 = 6 .label entry = 2 - .label entryBufDisk1__0 = 2 txa clc adc #<$1111 @@ -626,10 +624,10 @@ initEntry: { sta _1+1 ldy #0 lda _1 - sta (entryBufDisk1__0),y + sta (entry),y iny lda _1+1 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #<$2222 @@ -639,10 +637,10 @@ initEntry: { sta _3+1 ldy #2 lda _3 - sta (entryBufDisk1__0),y + sta (entry),y iny lda _3+1 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #<$3333 @@ -652,10 +650,10 @@ initEntry: { sta _5+1 ldy #4 lda _5 - sta (entryBufDisk1__0),y + sta (entry),y iny lda _5+1 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #<$4444 @@ -665,30 +663,30 @@ initEntry: { sta _7+1 ldy #6 lda _7 - sta (entryBufDisk1__0),y + sta (entry),y iny lda _7+1 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$55 ldy #8 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$66 ldy #9 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$77 ldy #$a - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$88 ldy #$b - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #<$9999 @@ -698,30 +696,30 @@ initEntry: { sta _17+1 ldy #$c lda _17 - sta (entryBufDisk1__0),y + sta (entry),y iny lda _17+1 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$aa ldy #$e - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$bb ldy #$f - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$cc ldy #$10 - sta (entryBufDisk1__0),y + sta (entry),y txa clc adc #$dd ldy #$11 - sta (entryBufDisk1__0),y + sta (entry),y rts } // Perform binary multiplication of two unsigned 8-bit bytes into a 16-bit unsigned word diff --git a/src/test/ref/signed-indexed-subtract.asm b/src/test/ref/signed-indexed-subtract.asm index e82d13764..8904aed68 100644 --- a/src/test/ref/signed-indexed-subtract.asm +++ b/src/test/ref/signed-indexed-subtract.asm @@ -92,11 +92,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(4) w) print_word: { - lda print_sword.w+1 + .label w = 4 + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts diff --git a/src/test/ref/signed-word-minus-byte-2.asm b/src/test/ref/signed-word-minus-byte-2.asm new file mode 100644 index 000000000..3dc3d631b --- /dev/null +++ b/src/test/ref/signed-word-minus-byte-2.asm @@ -0,0 +1,32 @@ +// Tests subtracting bytes from signed words +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label w1 = 2 + ldx #0 + lda #<$4d2 + sta w1 + lda #>$4d2 + sta w1+1 + b1: + lda w1 + sec + sbc #$29 + sta w1 + lda w1+1 + sbc #>$29 + sta w1+1 + txa + asl + tay + lda w1 + sta screen,y + lda w1+1 + sta screen+1,y + inx + cpx #$b + bne b1 + rts +} diff --git a/src/test/ref/signed-words.asm b/src/test/ref/signed-words.asm index e85a5777d..c339f7437 100644 --- a/src/test/ref/signed-words.asm +++ b/src/test/ref/signed-words.asm @@ -22,17 +22,18 @@ .label yvel_10 = 6 .label xvel = 2 .label yvel_12 = 6 - .label yvel_22 = 6 + .label yvel_20 = 6 main: { jsr init lda #$64 sta yvel_init lda #0 sta yvel_init+1 - lda #$c8 + lda #<$c8 sta xvel - lda #0 + lda #>$c8 sta xvel+1 + lda #0 sta ypos sta ypos+1 sta xpos @@ -64,13 +65,13 @@ anim: { eor #$ff adc #0 sta xvel+1 - sec lda yvel_init + sec sbc #$a sta yvel_init - bcs !+ - dec yvel_init+1 - !: + lda yvel_init+1 + sbc #>$a + sta yvel_init+1 lda yvel_init cmp #<-$c8 lda yvel_init+1 @@ -79,15 +80,15 @@ anim: { eor #$80 !: bpl b3 - lda #$c8 + lda #<$c8 sta yvel - lda #0 + lda #>$c8 sta yvel+1 b3: lda yvel - sta yvel_22 + sta yvel_20 lda yvel+1 - sta yvel_22+1 + sta yvel_20+1 lda #0 sta ypos sta ypos+1 @@ -182,7 +183,7 @@ init: { sta SPRITES_YPOS lda #WHITE sta SPRITES_COLS - lda #$ff&SPRITE/$40 + lda #SPRITE/$40 sta SPRITES_PTR lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 diff --git a/src/test/ref/sinusgen16b.asm b/src/test/ref/sinusgen16b.asm index c99639748..299b22494 100644 --- a/src/test/ref/sinusgen16b.asm +++ b/src/test/ref/sinusgen16b.asm @@ -129,11 +129,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(8) w) print_word: { - lda print_sword.w+1 + .label w = 8 + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts @@ -196,8 +198,8 @@ print_cls: { // wavelength - the number of sinus points in a total sinus wavelength (the size of the table) // sin16s_genb(signed word* zeropage(2) sintab) sin16s_genb: { - .label _2 = 8 - .label step = $1d + .label _2 = 6 + .label step = $1b .label sintab = 2 .label x = $d .label i = 4 @@ -266,17 +268,18 @@ sin16s_genb: { // result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff // sin16sb(word zeropage(6) x) sin16sb: { + .label _19 = 6 .label x = 6 - .label return = 8 + .label return = 6 .label x1 = 6 - .label x2 = $b - .label x3 = $b - .label x3_6 = $11 - .label usinx = 8 - .label x4 = $b - .label x5 = $11 - .label x5_128 = $11 - .label sinx = 8 + .label x2 = 8 + .label x3 = 8 + .label x3_6 = $b + .label usinx = $1f + .label x4 = 8 + .label x5 = $b + .label x5_128 = $b + .label sinx = 6 .label isUpper = $a lda x+1 cmp #>PI_u4f12 @@ -388,9 +391,17 @@ sin16sb: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _19 + lda usinx+1 + sta _19+1 sec lda sinx eor #$ff @@ -405,19 +416,19 @@ sin16sb: { } // Calculate val*val for two unsigned word values - the result is 16 selected bits of the 32-bit result. // The select parameter indicates how many of the highest bits of the 32-bit result to skip -// mulu16_sel(word zeropage($b) v1, word zeropage($11) v2, byte register(X) select) +// mulu16_sel(word zeropage(8) v1, word zeropage($b) v2, byte register(X) select) mulu16_sel: { - .label _0 = $15 - .label _1 = $15 - .label v1 = $b - .label v2 = $11 - .label return = $b - .label return_11 = $11 - .label return_14 = $11 - .label return_16 = $11 - .label return_17 = $11 - .label return_18 = $11 - .label return_20 = $11 + .label _0 = $13 + .label _1 = $13 + .label v1 = 8 + .label v2 = $b + .label return = 8 + .label return_11 = $b + .label return_14 = $b + .label return_16 = $b + .label return_17 = $b + .label return_18 = $b + .label return_20 = $b lda v1 sta mul16u.a lda v1+1 @@ -440,13 +451,13 @@ mulu16_sel: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage($13) a, word zeropage($11) b) +// mul16u(word zeropage($11) a, word zeropage($b) b) mul16u: { - .label mb = $19 - .label a = $13 - .label res = $15 - .label b = $11 - .label return = $15 + .label a = $11 + .label mb = $17 + .label res = $13 + .label b = $b + .label return = $13 lda b sta mb lda b+1 @@ -497,7 +508,7 @@ mul16u: { div32u16u: { .label quotient_hi = 8 .label quotient_lo = 6 - .label return = $1d + .label return = $1b lda #>$10 sta divr16u.dividend lda #>PI2_u4f28>>$10 @@ -585,7 +596,7 @@ divr16u: { // sin16s_gen(signed word* zeropage(2) sintab) sin16s_gen: { .label _1 = 6 - .label step = $1d + .label step = $1b .label sintab = 2 .label x = $d .label i = 4 @@ -656,19 +667,20 @@ sin16s_gen: { // Calculate signed word sinus sin(x) // x: unsigned dword input u[4.28] in the interval $00000000 - PI2_u4f28 // result: signed word sin(x) s[0.15] - using the full range -$7fff - $7fff -// sin16s(dword zeropage($15) x) +// sin16s(dword zeropage($13) x) sin16s: { - .label _4 = $15 - .label x = $15 + .label _4 = $13 + .label _20 = 6 + .label x = $13 .label return = 6 - .label x1 = 8 - .label x2 = $b - .label x3 = $b - .label x3_6 = $11 - .label usinx = 6 - .label x4 = $b - .label x5 = $11 - .label x5_128 = $11 + .label x1 = 6 + .label x2 = 8 + .label x3 = 8 + .label x3_6 = $b + .label usinx = $1f + .label x4 = 8 + .label x5 = $b + .label x5_128 = $b .label sinx = 6 .label isUpper = $a lda x+3 @@ -815,9 +827,17 @@ sin16s: { lda usinx+1 adc x5_128+1 sta usinx+1 + lda usinx + sta sinx + lda usinx+1 + sta sinx+1 lda isUpper cmp #0 beq b3 + lda usinx + sta _20 + lda usinx+1 + sta _20+1 sec lda sinx eor #$ff diff --git a/src/test/ref/sinusgen8.asm b/src/test/ref/sinusgen8.asm index 9c3cdd67e..5e117690a 100644 --- a/src/test/ref/sinusgen8.asm +++ b/src/test/ref/sinusgen8.asm @@ -11,6 +11,7 @@ .label print_char_cursor = 5 main: { .label wavelength = $c0 + .label _2 = 4 .label sb = 4 jsr sin8s_gen jsr print_cls @@ -20,9 +21,11 @@ main: { sta print_char_cursor+1 ldx #0 b1: + lda sintabref,x + sta _2 lda sintab2,x sec - sbc sintabref,x + sbc sb sta sb bmi b2 lda #points + adc #0 + sta point_i+1 + lda point_i + sta _1 + lda point_i+1 + sta _1+1 + txa + ldy #OFFS_X + sta (_1),y + txa + clc + adc #4 + // points[i].x = i; + ldy #OFFS_Y + sta (_3),y + inx + cpx #4 + bne b1 + ldx #0 + b2: + txa + asl + clc + adc #points + adc #0 + sta point_i1+1 + lda point_i1 + sta _8 + lda point_i1+1 + sta _8+1 + ldy #OFFS_X + lda (_8),y + sta SCREEN,x + // SCREEN[i] = points[i].x; + ldy #OFFS_Y + lda (_11),y + sta SCREEN+$28,x + inx + cpx #4 + bne b2 + rts +} + points: .fill 2*4, 0 diff --git a/src/test/ref/subexpr-optimize-0.asm b/src/test/ref/subexpr-optimize-0.asm new file mode 100644 index 000000000..dd03a4605 --- /dev/null +++ b/src/test/ref/subexpr-optimize-0.asm @@ -0,0 +1,35 @@ +// Tests (non-)optimization of identical sub-expressions +// The two examples of i+1 is not detected as identical leading to ASM that could be optimized more +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label _1 = 4 + .label screen = 2 + lda #<$400 + sta screen + lda #>$400 + sta screen+1 + ldx #0 + b1: + txa + asl + sta _1 + ldy #0 + sta (screen),y + inc screen + bne !+ + inc screen+1 + !: + lda _1 + ldy #0 + sta (screen),y + inc screen + bne !+ + inc screen+1 + !: + inx + cpx #3 + bne b1 + rts +} diff --git a/src/test/ref/subexpr-optimize-1.asm b/src/test/ref/subexpr-optimize-1.asm new file mode 100644 index 000000000..df54827e6 --- /dev/null +++ b/src/test/ref/subexpr-optimize-1.asm @@ -0,0 +1,21 @@ +// A sub-expression that should not be optimized (+1 to a pointer) +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + ldx #0 + b1: + lda SCREEN+1,x + sta SCREEN,x + lda SCREEN+$28+1,x + sta SCREEN+$28,x + lda SCREEN+$50+1,x + sta SCREEN+$50,x + lda SCREEN+$78+1,x + sta SCREEN+$78,x + inx + cpx #$27 + bne b1 + rts +} diff --git a/src/test/ref/ternary-inference.asm b/src/test/ref/ternary-inference.asm new file mode 100644 index 000000000..90df7b35e --- /dev/null +++ b/src/test/ref/ternary-inference.asm @@ -0,0 +1,24 @@ +// Type inference into the ternary operator +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + ldx #0 + b1: + cpx #5 + bcc b2 + lda #'0' + jmp b3 + b2: + lda #$57 + b3: + stx $ff + clc + adc $ff + sta screen,x + inx + cpx #$b + bne b1 + rts +} diff --git a/src/test/ref/test-comparisons-sword.asm b/src/test/ref/test-comparisons-sword.asm index 426dacc95..243347b6b 100644 --- a/src/test/ref/test-comparisons-sword.asm +++ b/src/test/ref/test-comparisons-sword.asm @@ -80,8 +80,9 @@ main: { inc i cmp i bne b1 - b8: - jmp b8 + b5: + // loop forever + jmp b5 } // Print a newline print_ln: { @@ -323,11 +324,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage($a) w) print_word: { - lda print_sword.w+1 + .label w = $a + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts diff --git a/src/test/ref/test-comparisons-word.asm b/src/test/ref/test-comparisons-word.asm index 05ed548ab..3b0d79f32 100644 --- a/src/test/ref/test-comparisons-word.asm +++ b/src/test/ref/test-comparisons-word.asm @@ -73,8 +73,9 @@ main: { inc i cmp i bne b1 - b8: - jmp b8 + b5: + // loop forever + jmp b5 } // Print a newline print_ln: { @@ -205,9 +206,9 @@ compare: { bne !+ lda w1 cmp w2 + beq b11 !: bcc b11 - beq b11 lda #TT sta r jmp b22 @@ -247,9 +248,9 @@ compare: { bne !+ lda w2 cmp w1 + beq b13 !: bcc b13 - beq b13 lda #TT sta r jmp b24 diff --git a/src/test/ref/test-division.asm b/src/test/ref/test-division.asm index 6f74de8b7..cd75806a1 100644 --- a/src/test/ref/test-division.asm +++ b/src/test/ref/test-division.asm @@ -4,8 +4,8 @@ .pc = $80d "Program" .label print_char_cursor = 8 .label print_line_cursor = 3 - .label rem16u = $a - .label rem16s = $a + .label rem16u = $e + .label rem16s = $e main: { jsr print_cls jsr test_8u @@ -17,24 +17,21 @@ main: { test_16s: { .label dividend = 5 .label divisor = $13 - .label res = $e + .label res = $c .label i = 2 lda #0 sta i b1: lda i asl - tay - lda dividends,y + tax + lda dividends,x sta dividend - lda dividends+1,y + lda dividends+1,x sta dividend+1 - lda i - asl - tay - lda divisors,y + lda divisors,x sta divisor - lda divisors+1,y + lda divisors+1,x sta divisor+1 jsr div16s lda print_line_cursor @@ -76,9 +73,7 @@ test_16s: { inc i lda #6 cmp i - beq !b1+ - jmp b1 - !b1: + bne b1 rts dividends: .word $7fff, $7fff, -$7fff, -$7fff, $7fff, -$7fff divisors: .word 5, -7, $b, -$d, -$11, $13 @@ -198,7 +193,7 @@ print_str: { // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 // div16s(signed word zeropage(5) dividend, signed word zeropage($13) divisor) div16s: { - .label return = $e + .label return = $c .label dividend = 5 .label divisor = $13 lda dividend @@ -217,25 +212,21 @@ div16s: { // Implemented using simple binary division // Follows the C99 standard by truncating toward zero on negative results. // See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5 -// divr16s(signed word zeropage(8) dividend, signed word zeropage($c) divisor) +// divr16s(signed word zeropage(8) dividend, signed word zeropage($a) divisor) divr16s: { - .const rem = 0 .label _8 = 8 - .label _13 = $c - .label resultu = $e - .label return = $e - .label dividend = 8 - .label divisor = $c + .label _13 = $a + .label _16 = $e + .label _18 = $c .label dividendu = 8 - .label divisoru = $c - .label remu = $a + .label divisoru = $a + .label resultu = $c + .label return = $c + .label dividend = 8 + .label divisor = $a lda dividend+1 bmi b1 - lda #rem - sta remu - lda #0 - sta remu+1 - tay + ldy #0 b2: lda divisor+1 bmi b3 @@ -287,10 +278,6 @@ divr16s: { eor #$ff adc #0 sta _8+1 - lda #-rem - sta remu - lda #0 - sta remu+1 ldy #1 jmp b2 } @@ -298,17 +285,19 @@ divr16s: { // Returns the quotient dividend/divisor. // The final remainder will be set into the global variable rem16u // Implemented using simple binary division -// divr16u(word zeropage(8) dividend, word zeropage($c) divisor, word zeropage($a) rem) +// divr16u(word zeropage(8) dividend, word zeropage($a) divisor, word zeropage($e) rem) divr16u: { - .label rem = $a + .label rem = $e .label dividend = 8 - .label quotient = $e - .label return = $e - .label divisor = $c + .label quotient = $c + .label return = $c + .label divisor = $a ldx #0 txa sta quotient sta quotient+1 + sta rem + sta rem+1 b1: asl rem rol rem+1 @@ -446,7 +435,7 @@ div8s: { tay lda neg cmp #0 - beq b9 + beq b5 txa eor #$ff clc @@ -457,7 +446,7 @@ div8s: { clc adc #1 rts - b9: + b5: tya rts b3: @@ -537,25 +526,22 @@ divr8u: { } test_16u: { .label dividend = 5 - .label divisor = $c - .label res = $e + .label divisor = $a + .label res = $c .label i = 2 lda #0 sta i b1: lda i asl - tay - lda dividends,y + tax + lda dividends,x sta dividend - lda dividends+1,y + lda dividends+1,x sta dividend+1 - lda i - asl - tay - lda divisors,y + lda divisors,x sta divisor - lda divisors+1,y + lda divisors+1,x sta divisor+1 jsr div16u lda print_line_cursor @@ -606,18 +592,15 @@ test_16u: { // Returns the quotient dividend/divisor. // The remainder will be set into the global variable rem16u // Implemented using simple binary division -// div16u(word zeropage(5) dividend, word zeropage($c) divisor) +// div16u(word zeropage(5) dividend, word zeropage($a) divisor) div16u: { - .label return = $e + .label return = $c .label dividend = 5 - .label divisor = $c + .label divisor = $a lda dividend sta divr16u.dividend lda dividend+1 sta divr16u.dividend+1 - lda #0 - sta divr16u.rem - sta divr16u.rem+1 jsr divr16u rts } diff --git a/src/test/ref/test-multiply-16bit.asm b/src/test/ref/test-multiply-16bit.asm index e5701b8c6..4b1b9e166 100644 --- a/src/test/ref/test-multiply-16bit.asm +++ b/src/test/ref/test-multiply-16bit.asm @@ -340,7 +340,9 @@ print_sword: { // mulf16s(signed word zeropage(3) a, signed word zeropage(5) b) mulf16s: { .label _9 = 9 + .label _10 = $15 .label _13 = 9 + .label _14 = $15 .label _16 = 9 .label _17 = 9 .label m = $11 @@ -362,12 +364,16 @@ mulf16s: { sta _9 lda m+3 sta _9+1 + lda b + sta _10 + lda b+1 + sta _10+1 lda _16 sec - sbc b + sbc _10 sta _16 lda _16+1 - sbc b+1 + sbc _10+1 sta _16+1 lda _16 sta m+2 @@ -380,12 +386,16 @@ mulf16s: { sta _13 lda m+3 sta _13+1 + lda a + sta _14 + lda a+1 + sta _14+1 lda _17 sec - sbc a + sbc _14 sta _17 lda _17+1 - sbc a+1 + sbc _14+1 sta _17+1 lda _17 sta m+2 @@ -519,21 +529,30 @@ mulf16u: { // mul16s(signed word zeropage(3) a, signed word zeropage(5) b) mul16s: { .label _9 = 9 + .label _10 = $15 .label _13 = 9 + .label _14 = $15 .label _16 = 9 .label _17 = 9 .label m = $19 .label return = $19 .label a = 3 .label b = 5 - lda b - sta mul16u.b - lda b+1 - sta mul16u.b+1 lda a sta mul16u.a lda a+1 sta mul16u.a+1 + lda b + sta mul16u.b + lda b+1 + sta mul16u.b+1 + lda mul16u.b + sta mul16u.mb + lda mul16u.b+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u lda a+1 bpl b1 @@ -541,12 +560,16 @@ mul16s: { sta _9 lda m+3 sta _9+1 + lda b + sta _10 + lda b+1 + sta _10+1 lda _16 sec - sbc b + sbc _10 sta _16 lda _16+1 - sbc b+1 + sbc _10+1 sta _16+1 lda _16 sta m+2 @@ -559,12 +582,16 @@ mul16s: { sta _13 lda m+3 sta _13+1 + lda a + sta _14 + lda a+1 + sta _14+1 lda _17 sec - sbc a + sbc _14 sta _17 lda _17+1 - sbc a+1 + sbc _14+1 sta _17+1 lda _17 sta m+2 @@ -574,20 +601,15 @@ mul16s: { rts } // Perform binary multiplication of two unsigned 16-bit words into a 32-bit unsigned double word -// mul16u(word zeropage(9) a, word zeropage($17) b) +// mul16u(word zeropage($1d) a, word zeropage(9) b) mul16u: { .label mb = $11 - .label a = 9 + .label a = $1d .label res = $19 + .label b = 9 .label return = $19 - .label b = $17 - lda b - sta mb - lda b+1 - sta mb+1 + .label b_1 = $17 lda #0 - sta mb+2 - sta mb+3 sta res sta res+1 sta res+2 @@ -774,6 +796,13 @@ mul16u_compare: { sta mul16u.a lda a+1 sta mul16u.a+1 + lda mul16u.b_1 + sta mul16u.mb + lda mul16u.b_1+1 + sta mul16u.mb+1 + lda #0 + sta mul16u.mb+2 + sta mul16u.mb+3 jsr mul16u jsr mulf16u lda ms @@ -822,7 +851,9 @@ mul16u_compare: { b5: iny cpy #$10 - bne b2 + beq !b2+ + jmp b2 + !b2: inc i lda #$10 cmp i diff --git a/src/test/ref/test-multiply-8bit.asm b/src/test/ref/test-multiply-8bit.asm index 92b5ae098..195dda466 100644 --- a/src/test/ref/test-multiply-8bit.asm +++ b/src/test/ref/test-multiply-8bit.asm @@ -267,26 +267,36 @@ print_sbyte: { // Fixes offsets introduced by using unsigned multiplication // mul8s(signed byte zeropage(2) a, signed byte register(Y) b) mul8s: { + .label _9 = $10 + .label _13 = $10 .label m = $c - .label a = 2 .label return = $c - tya + .label a = 2 ldx a + tya + sta mul8u.mb + lda #0 + sta mul8u.mb+1 jsr mul8u lda a cmp #0 bpl b1 lda m+1 - sty $ff + sta _9 + tya + eor #$ff sec - sbc $ff + adc _9 sta m+1 b1: cpy #0 bpl b2 lda m+1 + sta _13 + lda a + eor #$ff sec - sbc a + adc _13 sta m+1 b2: rts @@ -297,9 +307,7 @@ mul8u: { .label mb = 6 .label res = $c .label return = $c - sta mb lda #0 - sta mb+1 sta res sta res+1 b1: @@ -331,34 +339,42 @@ mul8u: { mulf8s: { .label return = $e jsr mulf8u_prepare - stx mulf8s_prepared.b + txa + tay jsr mulf8s_prepared rts } // Calculate fast multiply with a prepared unsigned byte to a word result // The prepared number is set by calling mulf8s_prepare(byte a) -// mulf8s_prepared(signed byte zeropage(3) b) +// mulf8s_prepared(signed byte register(Y) b) mulf8s_prepared: { .label memA = $fd + .label _8 = $10 + .label _12 = $10 .label m = $e - .label b = 3 .label return = $e - ldx b + tya + tax jsr mulf8u_prepared lda memA cmp #0 bpl b1 lda m+1 + sta _8 + tya + eor #$ff sec - sbc b + adc _8 sta m+1 b1: - lda b - cmp #0 + cpy #0 bpl b2 lda m+1 + sta _12 + lda memA + eor #$ff sec - sbc memA + adc _12 sta m+1 b2: rts @@ -411,8 +427,8 @@ muls8s: { bmi b6 cmp #1 bmi b5 - lda #0 - tay + ldy #0 + tya sta m sta m+1 b3: @@ -440,8 +456,8 @@ muls8s: { sta return+1 rts b6: - lda #0 - tay + ldy #0 + tya sta m sta m+1 b4: @@ -484,6 +500,9 @@ mul8u_compare: { jsr mulf8u ldx a lda b + sta mul8u.mb + lda #0 + sta mul8u.mb+1 jsr mul8u lda ms cmp mf diff --git a/src/test/ref/test-scroll-up.asm b/src/test/ref/test-scroll-up.asm index 15c85f776..7e9d7c1b9 100644 --- a/src/test/ref/test-scroll-up.asm +++ b/src/test/ref/test-scroll-up.asm @@ -14,8 +14,8 @@ scrollup3: { .label l2_1 = 4 .label line = 2 .label l2_2 = 4 - .label _4 = 7 - .label _5 = 9 + .label _5 = 7 + .label _6 = 9 .label l2_4 = 4 lda #0 sta l2 @@ -30,20 +30,20 @@ scrollup3: { lda l2_2 clc adc #screen+$28 - sta _4+1 + sta _5+1 lda l2_2 clc adc #screen - sta _5+1 + sta _6+1 ldy #0 - lda (_4),y - sta (_5),y + lda (_5),y + sta (_6),y inc l2_1 bne !+ inc l2_1+1 @@ -109,8 +109,8 @@ scrollup1: { .label _0 = 4 .label _2 = 7 .label line = 2 - .label _6 = 7 - .label _7 = 4 + .label _7 = 7 + .label _8 = 4 lda #0 sta line sta line+1 @@ -132,22 +132,22 @@ scrollup1: { adc line+1 sta _2+1 clc - lda _6 - adc #screen+$28 - sta _6+1 - clc lda _7 - adc #screen + adc #>screen+$28 sta _7+1 + clc + lda _8 + adc #screen + sta _8+1 ldy #0 - lda (_6),y - sta (_7),y + lda (_7),y + sta (_8),y inx cpx #$28 bcc b2 diff --git a/src/test/ref/test-signed-word-minus-byte.asm b/src/test/ref/test-signed-word-minus-byte.asm index 7323f8d14..809f17757 100644 --- a/src/test/ref/test-signed-word-minus-byte.asm +++ b/src/test/ref/test-signed-word-minus-byte.asm @@ -22,19 +22,19 @@ main: { lda #>$4d2 sta w1+1 b1: - sec lda w1 + sec sbc #$5b sta w2 lda w1+1 - sbc #0 + sbc #>$5b sta w2+1 - sec lda w2 + sec sbc #$29 sta w1 lda w2+1 - sbc #0 + sbc #>$29 sta w1+1 lda w1 sta print_sword.w @@ -102,11 +102,13 @@ print_sword: { rts } // Print a word as HEX +// print_word(word zeropage(6) w) print_word: { - lda print_sword.w+1 + .label w = 6 + lda w+1 sta print_byte.b jsr print_byte - lda print_sword.w + lda w sta print_byte.b jsr print_byte rts diff --git a/src/test/ref/test-word-size-arrays.asm b/src/test/ref/test-word-size-arrays.asm index 34f29fa59..93a40e061 100644 --- a/src/test/ref/test-word-size-arrays.asm +++ b/src/test/ref/test-word-size-arrays.asm @@ -7,9 +7,9 @@ main: { .label _2 = 6 .label _6 = 4 .label line = 2 - .label _8 = 6 - .label _9 = 4 + .label _9 = 6 .label _10 = 4 + .label _11 = 4 lda #0 sta line sta line+1 @@ -31,22 +31,22 @@ main: { adc line+1 sta _2+1 clc - lda _8 - adc #screen+$28 - sta _8+1 - clc lda _9 - adc #screen + adc #>screen+$28 sta _9+1 + clc + lda _10 + adc #screen + sta _10+1 ldy #0 - lda (_8),y - sta (_9),y + lda (_9),y + sta (_10),y inx cpx #$28 bcc b2 @@ -76,15 +76,15 @@ main: { adc line+1 sta _6+1 clc - lda _10 + lda _11 adc #screen - sta _10+1 + sta _11+1 lda #' ' ldy #0 - sta (_10),y + sta (_11),y inx cpx #$28 bcc b4 diff --git a/src/test/ref/tod018-problem.asm b/src/test/ref/tod018-problem.asm new file mode 100644 index 000000000..abe4cf7a9 --- /dev/null +++ b/src/test/ref/tod018-problem.asm @@ -0,0 +1,12 @@ +// Tests a problem with tod018 not calculating types correctly +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label D018 = $d018 + .label screen = $400 + .const d018val = >screen&$3fff + lda #d018val + sta D018 + rts +} diff --git a/src/test/ref/travis1.asm b/src/test/ref/travis1.asm index a73fc4f30..12531614c 100644 --- a/src/test/ref/travis1.asm +++ b/src/test/ref/travis1.asm @@ -22,6 +22,17 @@ main: { jsr game_ready cmp #0 bne b3 + jmp b2 + b3: + lda print_line_cursor + sta print_char_cursor + lda print_line_cursor+1 + sta print_char_cursor+1 + lda #str + sta print_str_ln.str+1 + jsr print_str_ln b2: inc i lda #6 @@ -34,17 +45,6 @@ main: { lda print_line_cursor+1 sta print_char_cursor+1 jmp b1 - b3: - lda print_line_cursor - sta print_char_cursor - lda print_line_cursor+1 - sta print_char_cursor+1 - lda #str - sta print_str_ln.str+1 - jsr print_str_ln - jmp b2 str: .text "ready!@" } // Print a zero-terminated string followed by a newline diff --git a/src/test/ref/true-inline-words.asm b/src/test/ref/true-inline-words.asm index 4dd088582..f8a2b1d7e 100644 --- a/src/test/ref/true-inline-words.asm +++ b/src/test/ref/true-inline-words.asm @@ -8,10 +8,12 @@ main: { .label pos = $501 .label bgcol = $d021 .const w = b*$100 - .const w2 = 1*$100+1+w+0 + .const w2 = 1*$100+1+w + // constant inline words inside expression + .label sc = w2 // implicit cast to (byte*) lda bs+1 - sta w2 + sta sc lda #'m' cmp pos beq b1 diff --git a/src/test/ref/type-inference.asm b/src/test/ref/type-inference.asm new file mode 100644 index 000000000..50476c017 --- /dev/null +++ b/src/test/ref/type-inference.asm @@ -0,0 +1,23 @@ +// Test inference of integer types in expressions +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .label b = 2 + lda #0 + sta b + b1: + lax b + axs #-[-$30] + lda b + asl + tay + txa + sta screen,y + inc b + lda #$15 + cmp b + bne b1 + rts +} diff --git a/src/test/ref/type-mix.asm b/src/test/ref/type-mix.asm index 8a32fe08f..e8c690cdc 100644 --- a/src/test/ref/type-mix.asm +++ b/src/test/ref/type-mix.asm @@ -10,13 +10,13 @@ main: { sta w sta w+1 b1: - sec lda w + sec sbc #$c sta w - bcs !+ - dec w+1 - !: + lda w+1 + sbc #>$c + sta w+1 lda w sta SCREEN,x inx diff --git a/src/test/ref/typeid-plus-byte-problem.asm b/src/test/ref/typeid-plus-byte-problem.asm new file mode 100644 index 000000000..d92b22c23 --- /dev/null +++ b/src/test/ref/typeid-plus-byte-problem.asm @@ -0,0 +1,12 @@ +// Test that byte+byte creates a byte - even when there is a value overflow +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 +main: { + .const ubc2 = $fa + .const ubc1 = $c+$d+$e + lda #ubc1+ubc2 + sta SCREEN + rts +} diff --git a/src/test/ref/typeid-plus-bytes.asm b/src/test/ref/typeid-plus-bytes.asm index 3678d2e5c..ad57b6c06 100644 --- a/src/test/ref/typeid-plus-bytes.asm +++ b/src/test/ref/typeid-plus-bytes.asm @@ -5,36 +5,125 @@ .const TYPEID_BYTE = 1 .const TYPEID_SIGNED_BYTE = 2 .label SCREEN = $400 + .label SSCREEN = $400 main: { jsr testUnsigned + jsr testUnsignedVals jsr testSigned + jsr testSignedVals + rts +} +testSignedVals: { + .const sbc1 = -$78 + .label sbv1 = 5 + lda #-$78 + sta sbv1 + sta SSCREEN+$28*3 + lda #sbc1 + sta SSCREEN+$28*3+1 + lda sbv1 + sta SSCREEN+$28*3+2 + lda #-$46+-$32 + sta SSCREEN+$28*3+3 + lda #sbc1+-$78 + sta SSCREEN+$28*3+4 + lda #-$78+sbc1 + sta SSCREEN+$28*3+5 + lda #-$78 + clc + adc sbv1 + sta SSCREEN+$28*3+6 + lda #-$78 + clc + adc sbv1 + sta SSCREEN+$28*3+7 + lda #sbc1 + clc + adc sbv1 + sta SSCREEN+$28*3+8 + lda #sbc1 + clc + adc sbv1 + sta SSCREEN+$28*3+9 + lda sbv1 + asl + sta SSCREEN+$28*3+$a rts } testSigned: { - .label sbv1 = 3 - lda #$13 + .label sbv1 = 4 + lda #-$78 sta sbv1 + lda #0 + sta SCREEN+$28*2 lda #TYPEID_SIGNED_BYTE + sta SCREEN+$28*2+1 + sta SCREEN+$28*2+2 + lda #0 + sta SCREEN+$28*2+3 + lda #TYPEID_SIGNED_BYTE + sta SCREEN+$28*2+4 + sta SCREEN+$28*2+5 + sta SCREEN+$28*2+6 + sta SCREEN+$28*2+7 + sta SCREEN+$28*2+8 + sta SCREEN+$28*2+9 + sta SCREEN+$28*2+$a + rts +} +testUnsignedVals: { + .const ubc1 = $fa + .label ubv1 = 3 + lda #$fa + sta ubv1 sta SCREEN+$28 + lda #ubc1 sta SCREEN+$29 + lda ubv1 sta SCREEN+$2a + lda #$78+$82 sta SCREEN+$2b + lda #ubc1+$fa sta SCREEN+$2c + lda #$fa+ubc1 sta SCREEN+$2d - sta SCREEN+$2e - sta SCREEN+$2f + lax ubv1 + axs #-[$fa] + stx SCREEN+$2e + lax ubv1 + axs #-[$fa] + stx SCREEN+$2f + lda #ubc1 + clc + adc ubv1 + sta SCREEN+$30 + lda #ubc1 + clc + adc ubv1 + sta SCREEN+$31 + lda ubv1 + asl + sta SCREEN+$32 rts } testUnsigned: { .label ubv1 = 2 - lda #$5b + lda #$fa sta ubv1 - lda #TYPEID_BYTE + lda #0 sta SCREEN + lda #TYPEID_BYTE sta SCREEN+1 sta SCREEN+2 + lda #0 sta SCREEN+3 + lda #TYPEID_BYTE sta SCREEN+4 sta SCREEN+5 + sta SCREEN+6 + sta SCREEN+7 + sta SCREEN+8 + sta SCREEN+9 + sta SCREEN+$a rts } diff --git a/src/test/ref/typemismatch.asm b/src/test/ref/typemismatch.asm new file mode 100644 index 000000000..29ae868a1 --- /dev/null +++ b/src/test/ref/typemismatch.asm @@ -0,0 +1,7 @@ +// Type mismatch - should fail gracefully +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + rts +} diff --git a/src/test/ref/uninitialized.asm b/src/test/ref/uninitialized.asm index dd22c0239..24dc22e36 100644 --- a/src/test/ref/uninitialized.asm +++ b/src/test/ref/uninitialized.asm @@ -3,19 +3,14 @@ :BasicUpstart(main) .pc = $80d "Program" .const b = 0 - .const w = 0 - .label ptr = 0 .label SCREEN = $400 main: { lda #b sta SCREEN - lda #w sta SCREEN+3 - lda #ptr sta SCREEN+5 rts } diff --git a/src/test/ref/unused-vars.asm b/src/test/ref/unused-vars.asm index 5acafc57f..e3a790fd7 100644 --- a/src/test/ref/unused-vars.asm +++ b/src/test/ref/unused-vars.asm @@ -12,7 +12,7 @@ main: { b1: lda #col sta COLS,x - lda #2/2+1+1 + lda #2/2+2 sta SCREEN,x inx cpx #$65 diff --git a/src/test/ref/valuelist-error.asm b/src/test/ref/valuelist-error.asm new file mode 100644 index 000000000..eb9744a46 --- /dev/null +++ b/src/test/ref/valuelist-error.asm @@ -0,0 +1,10 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label screen = $400 + .const w = -1*$100+-1 + lda #