mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 00:29:10 +00:00
Upgraded ANTLR. Improved clobber handling in inline kickasm.
This commit is contained in:
parent
ae21d82383
commit
f962948ef8
13
.idea/libraries/Maven__org_antlr_antlr4_4_9.xml
generated
13
.idea/libraries/Maven__org_antlr_antlr4_4_9.xml
generated
@ -1,13 +0,0 @@
|
|||||||
<component name="libraryTable">
|
|
||||||
<library name="Maven: org.antlr:antlr4:4.9">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9/antlr4-4.9.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9/antlr4-4.9-javadoc.jar!/" />
|
|
||||||
</JAVADOC>
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9/antlr4-4.9-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
13
.idea/libraries/Maven__org_antlr_antlr4_4_9_2.xml
generated
Normal file
13
.idea/libraries/Maven__org_antlr_antlr4_4_9_2.xml
generated
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.antlr:antlr4:4.9.2">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9.2/antlr4-4.9.2.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9.2/antlr4-4.9.2-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4/4.9.2/antlr4-4.9.2-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
@ -1,13 +1,13 @@
|
|||||||
<component name="libraryTable">
|
<component name="libraryTable">
|
||||||
<library name="Maven: org.antlr:antlr4-runtime:4.9">
|
<library name="Maven: org.antlr:antlr4-runtime:4.9.2">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9/antlr4-runtime-4.9.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9.2/antlr4-runtime-4.9.2.jar!/" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC>
|
<JAVADOC>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9/antlr4-runtime-4.9-javadoc.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9.2/antlr4-runtime-4.9.2-javadoc.jar!/" />
|
||||||
</JAVADOC>
|
</JAVADOC>
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9/antlr4-runtime-4.9-sources.jar!/" />
|
<root url="jar://$MAVEN_REPOSITORY$/org/antlr/antlr4-runtime/4.9.2/antlr4-runtime-4.9.2-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
@ -11,12 +11,12 @@
|
|||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:antlr4:4.9" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:antlr4:4.9.2" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:antlr-runtime:3.5.2" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:antlr-runtime:3.5.2" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:ST4:4.3" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.antlr:ST4:4.3" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.abego.treelayout:org.abego.treelayout.core:1.0.3" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.abego.treelayout:org.abego.treelayout.core:1.0.3" level="project" />
|
||||||
<orderEntry type="library" scope="PROVIDED" name="Maven: com.ibm.icu:icu4j:61.1" level="project" />
|
<orderEntry type="library" scope="PROVIDED" name="Maven: com.ibm.icu:icu4j:61.1" level="project" />
|
||||||
<orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.9" level="project" />
|
<orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.9.2" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.2" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.6.2" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.0" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.2" level="project" />
|
<orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.6.2" level="project" />
|
||||||
|
4
pom.xml
4
pom.xml
@ -27,13 +27,13 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4</artifactId>
|
<artifactId>antlr4</artifactId>
|
||||||
<version>4.9</version>
|
<version>4.9.2</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-runtime</artifactId>
|
<artifactId>antlr4-runtime</artifactId>
|
||||||
<version>4.9</version>
|
<version>4.9.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE db0ab6caa db0ab911c
|
//KICKC FRAGMENT CACHE d8c3d291d d8c3d4dd4
|
||||||
//FRAGMENT vbuzz=vbuc1
|
//FRAGMENT vbuzz=vbuc1
|
||||||
ldz #{c1}
|
ldz #{c1}
|
||||||
//FRAGMENT vbuzz_lt_vbuc1_then_la1
|
//FRAGMENT vbuzz_lt_vbuc1_then_la1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE db0ab6caa db0ab911c
|
//KICKC FRAGMENT CACHE d8c3d291d d8c3d4dd4
|
||||||
//FRAGMENT _deref_pbuc1=vbuc2
|
//FRAGMENT _deref_pbuc1=vbuc2
|
||||||
ldz #{c2}
|
ldz #{c2}
|
||||||
stz {c1}
|
stz {c1}
|
||||||
@ -1652,110 +1652,11 @@ tza
|
|||||||
sta {c1}
|
sta {c1}
|
||||||
lda #0
|
lda #0
|
||||||
sta {c1}+1
|
sta {c1}+1
|
||||||
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
|
|
||||||
inc {c1}
|
|
||||||
//FRAGMENT vwuz1=vbuc1
|
//FRAGMENT vwuz1=vbuc1
|
||||||
lda #<{c1}
|
lda #<{c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
lda #>{c1}
|
lda #>{c1}
|
||||||
sta {z1}+1
|
sta {z1}+1
|
||||||
//FRAGMENT _deref_pbuc1_eq_vbuz1_then_la1
|
|
||||||
lda {c1}
|
|
||||||
cmp {z1}
|
|
||||||
beq {la1}
|
|
||||||
//FRAGMENT _deref_pbuc1=_dec__deref_pbuc1
|
|
||||||
dec {c1}
|
|
||||||
//FRAGMENT pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
|
||||||
ldx {z1}
|
|
||||||
inc {c1},x
|
|
||||||
//FRAGMENT vbuz1=_byte0_vwuz2
|
|
||||||
lda {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=_byte1_vwuz2
|
|
||||||
lda {z2}+1
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuz2_bor_vbuz3
|
|
||||||
lda {z2}
|
|
||||||
ora {z3}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT _deref_pbuc1_eq_vbuaa_then_la1
|
|
||||||
cmp {c1}
|
|
||||||
beq {la1}
|
|
||||||
//FRAGMENT pbuc1_derefidx_vbuaa=_inc_pbuc1_derefidx_vbuaa
|
|
||||||
tax
|
|
||||||
inc {c1},x
|
|
||||||
//FRAGMENT pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx
|
|
||||||
inc {c1},x
|
|
||||||
//FRAGMENT vbuaa=_byte1_vwuz1
|
|
||||||
lda {z1}+1
|
|
||||||
//FRAGMENT vbuxx=_byte1_vwuz1
|
|
||||||
ldx {z1}+1
|
|
||||||
//FRAGMENT vbuz1=vbuxx_bor_vbuz2
|
|
||||||
txa
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuyy_bor_vbuz2
|
|
||||||
tya
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuzz_bor_vbuz2
|
|
||||||
tza
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuz2_bor_vbuaa
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuxx_bor_vbuaa
|
|
||||||
stx $ff
|
|
||||||
ora $ff
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuyy_bor_vbuaa
|
|
||||||
sty $ff
|
|
||||||
ora $ff
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuzz_bor_vbuaa
|
|
||||||
tay
|
|
||||||
tza
|
|
||||||
sty $ff
|
|
||||||
ora $ff
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuz2_bor_vbuxx
|
|
||||||
txa
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuxx_bor_vbuxx
|
|
||||||
stx {z1}
|
|
||||||
//FRAGMENT vbuyy=_byte1_vwuz1
|
|
||||||
ldy {z1}+1
|
|
||||||
//FRAGMENT vbuzz=_byte1_vwuz1
|
|
||||||
lda {z1}+1
|
|
||||||
taz
|
|
||||||
//FRAGMENT vbuz1=vbuz2_bor_vbuyy
|
|
||||||
tya
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT vbuz1=vbuz2_bor_vbuzz
|
|
||||||
tza
|
|
||||||
ora {z2}
|
|
||||||
sta {z1}
|
|
||||||
//FRAGMENT pbuc1_derefidx_vbuyy=_inc_pbuc1_derefidx_vbuyy
|
|
||||||
lda {c1},y
|
|
||||||
inc
|
|
||||||
sta {c1},y
|
|
||||||
//FRAGMENT pbuc1_derefidx_vbuzz=_inc_pbuc1_derefidx_vbuzz
|
|
||||||
tza
|
|
||||||
tax
|
|
||||||
inc {c1},x
|
|
||||||
//FRAGMENT _deref_pbuc1_eq_vbuxx_then_la1
|
|
||||||
cpx {c1}
|
|
||||||
beq {la1}
|
|
||||||
//FRAGMENT _deref_pbuc1_eq_vbuyy_then_la1
|
|
||||||
tya
|
|
||||||
cmp {c1}
|
|
||||||
beq {la1}
|
|
||||||
//FRAGMENT _deref_pbuc1_eq_vbuzz_then_la1
|
|
||||||
cpz {c1}
|
|
||||||
beq {la1}
|
|
||||||
//FRAGMENT vduz1=vduc1
|
//FRAGMENT vduz1=vduc1
|
||||||
lda #<{c1}
|
lda #<{c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
@ -1809,6 +1710,16 @@ lda {z2}
|
|||||||
sta {z1}
|
sta {z1}
|
||||||
lda {z2}+1
|
lda {z2}+1
|
||||||
sta {z1}+1
|
sta {z1}+1
|
||||||
|
//FRAGMENT vbuz1=_byte0_vwuz2
|
||||||
|
lda {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=_byte1_vwuz2
|
||||||
|
lda {z2}+1
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuz3
|
||||||
|
lda {z2}
|
||||||
|
ora {z3}
|
||||||
|
sta {z1}
|
||||||
//FRAGMENT vduz1=vduz2_ror_4
|
//FRAGMENT vduz1=vduz2_ror_4
|
||||||
lda {z2}+3
|
lda {z2}+3
|
||||||
lsr
|
lsr
|
||||||
@ -2396,10 +2307,62 @@ dey
|
|||||||
bne !-
|
bne !-
|
||||||
!e:
|
!e:
|
||||||
taz
|
taz
|
||||||
|
//FRAGMENT vbuaa=_byte1_vwuz1
|
||||||
|
lda {z1}+1
|
||||||
|
//FRAGMENT vbuxx=_byte1_vwuz1
|
||||||
|
ldx {z1}+1
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuz2
|
||||||
|
txa
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuyy_bor_vbuz2
|
||||||
|
tya
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuzz_bor_vbuz2
|
||||||
|
tza
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuaa
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuaa
|
||||||
|
stx $ff
|
||||||
|
ora $ff
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuyy_bor_vbuaa
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuzz_bor_vbuaa
|
||||||
|
tay
|
||||||
|
tza
|
||||||
|
sty $ff
|
||||||
|
ora $ff
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuxx
|
||||||
|
txa
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuxx_bor_vbuxx
|
||||||
|
stx {z1}
|
||||||
//FRAGMENT vbuaa=_byte1_vduz1
|
//FRAGMENT vbuaa=_byte1_vduz1
|
||||||
lda {z1}+1
|
lda {z1}+1
|
||||||
//FRAGMENT vbuxx=_byte1_vduz1
|
//FRAGMENT vbuxx=_byte1_vduz1
|
||||||
ldx {z1}+1
|
ldx {z1}+1
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuyy
|
||||||
|
tya
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuz1=vbuz2_bor_vbuzz
|
||||||
|
tza
|
||||||
|
ora {z2}
|
||||||
|
sta {z1}
|
||||||
|
//FRAGMENT vbuyy=_byte1_vwuz1
|
||||||
|
ldy {z1}+1
|
||||||
|
//FRAGMENT vbuzz=_byte1_vwuz1
|
||||||
|
lda {z1}+1
|
||||||
|
taz
|
||||||
//FRAGMENT vbuyy=_byte1_vduz1
|
//FRAGMENT vbuyy=_byte1_vduz1
|
||||||
ldy {z1}+1
|
ldy {z1}+1
|
||||||
//FRAGMENT vbuzz=_byte1_vduz1
|
//FRAGMENT vbuzz=_byte1_vduz1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE db0ab6caa db0ab911c
|
//KICKC FRAGMENT CACHE d8c3d291d d8c3d4dd4
|
||||||
//FRAGMENT vbuz1=vbuc1
|
//FRAGMENT vbuz1=vbuc1
|
||||||
lda #{c1}
|
lda #{c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE db0ab6caa db0ab911c
|
//KICKC FRAGMENT CACHE d8c3d291d d8c3d4dd4
|
||||||
//FRAGMENT vbuz1=vbuc1
|
//FRAGMENT vbuz1=vbuc1
|
||||||
lda #{c1}
|
lda #{c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE db0ab6caa db0ab911c
|
//KICKC FRAGMENT CACHE d8c3d291d d8c3d4dd4
|
||||||
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
|
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
|
||||||
inc {c1}
|
inc {c1}
|
||||||
//FRAGMENT isr_hardware_all_entry
|
//FRAGMENT isr_hardware_all_entry
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//KICKC FRAGMENT CACHE db0ab6caa db0ab911c
|
//KICKC FRAGMENT CACHE d8c3d291d d8c3d4dd4
|
||||||
//FRAGMENT vbuz1=_deref_pbuc1
|
//FRAGMENT vbuz1=_deref_pbuc1
|
||||||
lda {c1}
|
lda {c1}
|
||||||
sta {z1}
|
sta {z1}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package dk.camelot64.kickc.asm;
|
package dk.camelot64.kickc.asm;
|
||||||
|
|
||||||
|
import dk.camelot64.cpufamily6502.CpuClobber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inlined KickAssembler code.
|
* Inlined KickAssembler code.
|
||||||
* If no cycles/byte size is specified it defaults to 256/256.
|
* If no cycles/byte size is specified it defaults to 256/256.
|
||||||
@ -12,7 +14,9 @@ public class AsmInlineKickAsm extends AsmLine {
|
|||||||
|
|
||||||
private double cycles;
|
private double cycles;
|
||||||
|
|
||||||
public AsmInlineKickAsm(String kickAsmCode, Long bytes, Long cycles) {
|
private CpuClobber clobber;
|
||||||
|
|
||||||
|
public AsmInlineKickAsm(String kickAsmCode, Long bytes, Long cycles, CpuClobber clobber) {
|
||||||
this.kickAsmCode = kickAsmCode;
|
this.kickAsmCode = kickAsmCode;
|
||||||
if(bytes != null) {
|
if(bytes != null) {
|
||||||
this.bytes = bytes.intValue();
|
this.bytes = bytes.intValue();
|
||||||
@ -24,16 +28,21 @@ public class AsmInlineKickAsm extends AsmLine {
|
|||||||
} else {
|
} else {
|
||||||
this.cycles = 256;
|
this.cycles = 256;
|
||||||
}
|
}
|
||||||
|
if(clobber==null) {
|
||||||
|
this.clobber = CpuClobber.CLOBBER_ALL;
|
||||||
|
} else {
|
||||||
|
this.clobber = clobber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CpuClobber getClobber() {
|
||||||
|
return clobber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKickAsmCode() {
|
public String getKickAsmCode() {
|
||||||
return kickAsmCode;
|
return kickAsmCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKickAsmCode(String kickAsmCode) {
|
|
||||||
this.kickAsmCode = kickAsmCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of source lines in the inline assembler code (for line indexing)
|
* Get the number of source lines in the inline assembler code (for line indexing)
|
||||||
*
|
*
|
||||||
|
@ -213,8 +213,8 @@ public class AsmProgram {
|
|||||||
*
|
*
|
||||||
* @param kickAsmCode The kickassembler code
|
* @param kickAsmCode The kickassembler code
|
||||||
*/
|
*/
|
||||||
public void addInlinedKickAsm(String kickAsmCode, Long bytes, Long cycles) {
|
public void addInlinedKickAsm(String kickAsmCode, Long bytes, Long cycles, CpuClobber cpuClobber) {
|
||||||
addLine(new AsmInlineKickAsm(kickAsmCode, bytes, cycles));
|
addLine(new AsmInlineKickAsm(kickAsmCode, bytes, cycles, cpuClobber));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,6 +83,10 @@ public class AsmProgramStaticRegisterValues {
|
|||||||
current = new AsmRegisterValues();
|
current = new AsmRegisterValues();
|
||||||
} else if(line instanceof AsmScopeEnd) {
|
} else if(line instanceof AsmScopeEnd) {
|
||||||
current = new AsmRegisterValues();
|
current = new AsmRegisterValues();
|
||||||
|
} else if(line instanceof AsmInlineKickAsm) {
|
||||||
|
current = new AsmRegisterValues(current);
|
||||||
|
final CpuClobber cpuClobber = ((AsmInlineKickAsm) line).getClobber();
|
||||||
|
handleClobber(current, cpuClobber);
|
||||||
} else if(line instanceof AsmInstruction) {
|
} else if(line instanceof AsmInstruction) {
|
||||||
AsmInstruction instruction = (AsmInstruction) line;
|
AsmInstruction instruction = (AsmInstruction) line;
|
||||||
values.put(instruction, current);
|
values.put(instruction, current);
|
||||||
@ -92,34 +96,7 @@ public class AsmProgramStaticRegisterValues {
|
|||||||
if(instruction.getCpuOpcode().getMnemonic().equals("jsr")) {
|
if(instruction.getCpuOpcode().getMnemonic().equals("jsr")) {
|
||||||
cpuClobber = CpuClobber.CLOBBER_ALL;
|
cpuClobber = CpuClobber.CLOBBER_ALL;
|
||||||
}
|
}
|
||||||
if(cpuClobber.isRegisterA()) {
|
handleClobber(current, cpuClobber);
|
||||||
current.setA(null);
|
|
||||||
current.setaMem(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isRegisterX()) {
|
|
||||||
current.setX(null);
|
|
||||||
current.setxMem(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isRegisterY()) {
|
|
||||||
current.setY(null);
|
|
||||||
current.setyMem(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isRegisterZ()) {
|
|
||||||
current.setZ(null);
|
|
||||||
current.setzMem(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isFlagC()) {
|
|
||||||
current.setFlagC(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isFlagN()) {
|
|
||||||
current.setFlagN(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isFlagV()) {
|
|
||||||
current.setFlagV(null);
|
|
||||||
}
|
|
||||||
if(cpuClobber.isFlagZ()) {
|
|
||||||
current.setFlagZ(null);
|
|
||||||
}
|
|
||||||
String mnemnonic = cpuOpcode.getMnemonic();
|
String mnemnonic = cpuOpcode.getMnemonic();
|
||||||
CpuAddressingMode addressingMode = cpuOpcode.getAddressingMode();
|
CpuAddressingMode addressingMode = cpuOpcode.getAddressingMode();
|
||||||
if((mnemnonic.equals("inc") || mnemnonic.equals("dec") || mnemnonic.equals("ror") || mnemnonic.equals("rol") || mnemnonic.equals("lsr") || mnemnonic.equals("asl")) && (addressingMode.equals(CpuAddressingMode.ZP) || addressingMode.equals(CpuAddressingMode.ABS))) {
|
if((mnemnonic.equals("inc") || mnemnonic.equals("dec") || mnemnonic.equals("ror") || mnemnonic.equals("rol") || mnemnonic.equals("lsr") || mnemnonic.equals("asl")) && (addressingMode.equals(CpuAddressingMode.ZP) || addressingMode.equals(CpuAddressingMode.ABS))) {
|
||||||
@ -245,6 +222,37 @@ public class AsmProgramStaticRegisterValues {
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleClobber(AsmRegisterValues current, CpuClobber cpuClobber) {
|
||||||
|
if(cpuClobber.isRegisterA()) {
|
||||||
|
current.setA(null);
|
||||||
|
current.setaMem(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isRegisterX()) {
|
||||||
|
current.setX(null);
|
||||||
|
current.setxMem(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isRegisterY()) {
|
||||||
|
current.setY(null);
|
||||||
|
current.setyMem(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isRegisterZ()) {
|
||||||
|
current.setZ(null);
|
||||||
|
current.setzMem(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isFlagC()) {
|
||||||
|
current.setFlagC(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isFlagN()) {
|
||||||
|
current.setFlagN(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isFlagV()) {
|
||||||
|
current.setFlagV(null);
|
||||||
|
}
|
||||||
|
if(cpuClobber.isFlagZ()) {
|
||||||
|
current.setFlagZ(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Known values of registers/flags at an instruction. null where value is unknown.
|
* Known values of registers/flags at an instruction. null where value is unknown.
|
||||||
*/
|
*/
|
||||||
|
@ -98,7 +98,7 @@ public class Pass4CodeGeneration {
|
|||||||
Number startAddress = program.getTargetPlatform().getStartAddress();
|
Number startAddress = program.getTargetPlatform().getStartAddress();
|
||||||
if(startAddress != null)
|
if(startAddress != null)
|
||||||
linkScriptBody = linkScriptBody.replace("%P", AsmFormat.getAsmNumber(startAddress));
|
linkScriptBody = linkScriptBody.replace("%P", AsmFormat.getAsmNumber(startAddress));
|
||||||
asm.addLine(new AsmInlineKickAsm(linkScriptBody, 0L, 0L));
|
asm.addLine(new AsmInlineKickAsm(linkScriptBody, 0L, 0L, CpuClobber.CLOBBER_ALL));
|
||||||
|
|
||||||
// Generate global ZP labels
|
// Generate global ZP labels
|
||||||
asm.startChunk(currentScope, null, "Global Constants & labels");
|
asm.startChunk(currentScope, null, "Global Constants & labels");
|
||||||
@ -815,7 +815,7 @@ public class Pass4CodeGeneration {
|
|||||||
if(statementSource != null)
|
if(statementSource != null)
|
||||||
stmtFormat = statementSource.format();
|
stmtFormat = statementSource.format();
|
||||||
program.getLog().append("Warning! Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature() + "\n" + stmtFormat);
|
program.getLog().append("Warning! Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature() + "\n" + stmtFormat);
|
||||||
asm.addLine(new AsmInlineKickAsm(".assert \"Missing ASM fragment " + e.getFragmentSignature() + "\", 0, 1", 0L, 0L));
|
asm.addLine(new AsmInlineKickAsm(".assert \"Missing ASM fragment " + e.getFragmentSignature() + "\", 0, 1", 0L, 0L, CpuClobber.CLOBBER_NONE));
|
||||||
} else {
|
} else {
|
||||||
throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statementSource);
|
throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statementSource);
|
||||||
}
|
}
|
||||||
@ -1061,7 +1061,7 @@ public class Pass4CodeGeneration {
|
|||||||
ConstantLiteral kasmCyclesLiteral = kasmCycles.calculateLiteral(getScope());
|
ConstantLiteral kasmCyclesLiteral = kasmCycles.calculateLiteral(getScope());
|
||||||
asmCycles = ((ConstantInteger) kasmCyclesLiteral).getInteger();
|
asmCycles = ((ConstantInteger) kasmCyclesLiteral).getInteger();
|
||||||
}
|
}
|
||||||
asm.addInlinedKickAsm(statementKasm.getKickAsmCode(), asmBytes, asmCycles);
|
asm.addInlinedKickAsm(statementKasm.getKickAsmCode(), asmBytes, asmCycles, statementKasm.getDeclaredClobber());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3598,6 +3598,11 @@ public class TestProgramsFast extends TestPrograms {
|
|||||||
compileAndCompare("inline-kasm-clobber.c");
|
compileAndCompare("inline-kasm-clobber.c");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInlineKickAsmClobberMem() throws IOException {
|
||||||
|
compileAndCompare("inline-kasm-clobbermem.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInlineAsmClobberNone() throws IOException {
|
public void testInlineAsmClobberNone() throws IOException {
|
||||||
|
16
src/test/kc/inline-kasm-clobbermem.c
Normal file
16
src/test/kc/inline-kasm-clobbermem.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Demonstrate problem with inline kasm clobbering memory
|
||||||
|
// And the ASM peephole optimizer not realizing this
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
__ma char tile = 0;
|
||||||
|
char * const SCREEN = (char*)0x0400;
|
||||||
|
for(char i=0;i<10;i++) {
|
||||||
|
kickasm(uses tile, clobbers "A") {{
|
||||||
|
lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}}
|
||||||
|
SCREEN[i] = tile;
|
||||||
|
}
|
||||||
|
}
|
@ -332,9 +332,9 @@ memoryRemap: {
|
|||||||
}
|
}
|
||||||
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
||||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||||
// - dest_bank The 64KB bank for the destination (0-63)
|
// - dest_bank The 64KB bank for the destination (0-127)
|
||||||
// - dest The destination address (within the MB and bank)
|
// - dest The destination address (within the MB and bank)
|
||||||
// - src_bank The 64KB bank for the source (0-63)
|
// - src_bank The 64KB bank for the source (0-127)
|
||||||
// - src The source address (within the MB and bank)
|
// - src The source address (within the MB and bank)
|
||||||
// - num The number of bytes to copy
|
// - num The number of bytes to copy
|
||||||
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
||||||
|
@ -1484,9 +1484,9 @@ memoryRemap: {
|
|||||||
// memcpy_dma4
|
// memcpy_dma4
|
||||||
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
||||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||||
// - dest_bank The 64KB bank for the destination (0-63)
|
// - dest_bank The 64KB bank for the destination (0-127)
|
||||||
// - dest The destination address (within the MB and bank)
|
// - dest The destination address (within the MB and bank)
|
||||||
// - src_bank The 64KB bank for the source (0-63)
|
// - src_bank The 64KB bank for the source (0-127)
|
||||||
// - src The source address (within the MB and bank)
|
// - src The source address (within the MB and bank)
|
||||||
// - num The number of bytes to copy
|
// - num The number of bytes to copy
|
||||||
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
||||||
@ -2185,9 +2185,9 @@ memoryRemap: {
|
|||||||
// memcpy_dma4
|
// memcpy_dma4
|
||||||
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
||||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||||
// - dest_bank The 64KB bank for the destination (0-63)
|
// - dest_bank The 64KB bank for the destination (0-127)
|
||||||
// - dest The destination address (within the MB and bank)
|
// - dest The destination address (within the MB and bank)
|
||||||
// - src_bank The 64KB bank for the source (0-63)
|
// - src_bank The 64KB bank for the source (0-127)
|
||||||
// - src The source address (within the MB and bank)
|
// - src The source address (within the MB and bank)
|
||||||
// - num The number of bytes to copy
|
// - num The number of bytes to copy
|
||||||
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
||||||
|
@ -100,9 +100,9 @@ memoryRemap: {
|
|||||||
}
|
}
|
||||||
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
||||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||||
// - dest_bank The 64KB bank for the destination (0-63)
|
// - dest_bank The 64KB bank for the destination (0-127)
|
||||||
// - dest The destination address (within the MB and bank)
|
// - dest The destination address (within the MB and bank)
|
||||||
// - src_bank The 64KB bank for the source (0-63)
|
// - src_bank The 64KB bank for the source (0-127)
|
||||||
// - src The source address (within the MB and bank)
|
// - src The source address (within the MB and bank)
|
||||||
// - num The number of bytes to copy
|
// - num The number of bytes to copy
|
||||||
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
||||||
|
@ -627,9 +627,9 @@ memoryRemap: {
|
|||||||
// memcpy_dma4
|
// memcpy_dma4
|
||||||
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
||||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||||
// - dest_bank The 64KB bank for the destination (0-63)
|
// - dest_bank The 64KB bank for the destination (0-127)
|
||||||
// - dest The destination address (within the MB and bank)
|
// - dest The destination address (within the MB and bank)
|
||||||
// - src_bank The 64KB bank for the source (0-63)
|
// - src_bank The 64KB bank for the source (0-127)
|
||||||
// - src The source address (within the MB and bank)
|
// - src The source address (within the MB and bank)
|
||||||
// - num The number of bytes to copy
|
// - num The number of bytes to copy
|
||||||
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
||||||
@ -890,9 +890,9 @@ memoryRemap: {
|
|||||||
// memcpy_dma4
|
// memcpy_dma4
|
||||||
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
|
||||||
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
|
||||||
// - dest_bank The 64KB bank for the destination (0-63)
|
// - dest_bank The 64KB bank for the destination (0-127)
|
||||||
// - dest The destination address (within the MB and bank)
|
// - dest The destination address (within the MB and bank)
|
||||||
// - src_bank The 64KB bank for the source (0-63)
|
// - src_bank The 64KB bank for the source (0-127)
|
||||||
// - src The source address (within the MB and bank)
|
// - src The source address (within the MB and bank)
|
||||||
// - num The number of bytes to copy
|
// - num The number of bytes to copy
|
||||||
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
// void memcpy_dma4(char dest_bank, void *dest, char src_bank, void *src, unsigned int num)
|
||||||
|
38
src/test/ref/inline-kasm-clobbermem.asm
Normal file
38
src/test/ref/inline-kasm-clobbermem.asm
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Demonstrate problem with inline kasm clobbering memory
|
||||||
|
// And the ASM peephole optimizer not realizing this
|
||||||
|
// Commodore 64 PRG executable file
|
||||||
|
.file [name="inline-kasm-clobbermem.prg", type="prg", segments="Program"]
|
||||||
|
.segmentdef Program [segments="Basic, Code, Data"]
|
||||||
|
.segmentdef Basic [start=$0801]
|
||||||
|
.segmentdef Code [start=$80d]
|
||||||
|
.segmentdef Data [startAfter="Code"]
|
||||||
|
.segment Basic
|
||||||
|
:BasicUpstart(main)
|
||||||
|
.segment Code
|
||||||
|
main: {
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label tile = 2
|
||||||
|
// __ma char tile = 0
|
||||||
|
lda #0
|
||||||
|
sta.z tile
|
||||||
|
tax
|
||||||
|
__b1:
|
||||||
|
// for(char i=0;i<10;i++)
|
||||||
|
cpx #$a
|
||||||
|
bcc __b2
|
||||||
|
// }
|
||||||
|
rts
|
||||||
|
__b2:
|
||||||
|
// kickasm
|
||||||
|
lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
|
||||||
|
// SCREEN[i] = tile
|
||||||
|
lda.z tile
|
||||||
|
sta SCREEN,x
|
||||||
|
// for(char i=0;i<10;i++)
|
||||||
|
inx
|
||||||
|
jmp __b1
|
||||||
|
}
|
21
src/test/ref/inline-kasm-clobbermem.cfg
Normal file
21
src/test/ref/inline-kasm-clobbermem.cfg
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from
|
||||||
|
[0] main::tile = 0
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
[1] main::i#2 = phi( main/0, main::@2/main::i#1 )
|
||||||
|
[2] if(main::i#2<$a) goto main::@2
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[3] return
|
||||||
|
to:@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
kickasm( uses main::tile) {{ lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}}
|
||||||
|
[5] main::SCREEN[main::i#2] = main::tile
|
||||||
|
[6] main::i#1 = ++ main::i#2
|
||||||
|
to:main::@1
|
288
src/test/ref/inline-kasm-clobbermem.log
Normal file
288
src/test/ref/inline-kasm-clobbermem.log
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
Setting inferred volatile on symbol affected by address-of: main::tile in kickasm( uses main::tile) {{ lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}}
|
||||||
|
|
||||||
|
CONTROL FLOW GRAPH SSA
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from __start
|
||||||
|
main::tile = 0
|
||||||
|
main::i#0 = 0
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
main::i#2 = phi( main/main::i#0, main::@2/main::i#1 )
|
||||||
|
main::$0 = main::i#2 < $a
|
||||||
|
if(main::$0) goto main::@2
|
||||||
|
to:main::@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
main::i#3 = phi( main::@1/main::i#2 )
|
||||||
|
kickasm( uses main::tile) {{ lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}}
|
||||||
|
main::SCREEN[main::i#3] = main::tile
|
||||||
|
main::i#1 = ++ main::i#3
|
||||||
|
to:main::@1
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
void __start()
|
||||||
|
__start: scope:[__start] from
|
||||||
|
call main
|
||||||
|
to:__start::@1
|
||||||
|
__start::@1: scope:[__start] from __start
|
||||||
|
to:__start::@return
|
||||||
|
__start::@return: scope:[__start] from __start::@1
|
||||||
|
return
|
||||||
|
to:@return
|
||||||
|
|
||||||
|
SYMBOL TABLE SSA
|
||||||
|
void __start()
|
||||||
|
void main()
|
||||||
|
bool main::$0
|
||||||
|
__constant char * const main::SCREEN = (char *)$400
|
||||||
|
char main::i
|
||||||
|
char main::i#0
|
||||||
|
char main::i#1
|
||||||
|
char main::i#2
|
||||||
|
char main::i#3
|
||||||
|
__loadstore volatile char main::tile
|
||||||
|
|
||||||
|
Adding number conversion cast (unumber) $a in main::$0 = main::i#2 < $a
|
||||||
|
Successful SSA optimization PassNAddNumberTypeConversions
|
||||||
|
Simplifying constant pointer cast (char *) 1024
|
||||||
|
Simplifying constant integer cast $a
|
||||||
|
Successful SSA optimization PassNCastSimplification
|
||||||
|
Finalized unsigned number type (char) $a
|
||||||
|
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||||
|
Alias main::i#2 = main::i#3
|
||||||
|
Successful SSA optimization Pass2AliasElimination
|
||||||
|
Simple Condition main::$0 [4] if(main::i#2<$a) goto main::@2
|
||||||
|
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||||
|
Constant main::i#0 = 0
|
||||||
|
Successful SSA optimization Pass2ConstantIdentification
|
||||||
|
Removing unused procedure __start
|
||||||
|
Removing unused procedure block __start
|
||||||
|
Removing unused procedure block __start::@1
|
||||||
|
Removing unused procedure block __start::@return
|
||||||
|
Successful SSA optimization PassNEliminateEmptyStart
|
||||||
|
Inlining constant with var siblings main::i#0
|
||||||
|
Constant inlined main::i#0 = 0
|
||||||
|
Successful SSA optimization Pass2ConstantInlining
|
||||||
|
CALL GRAPH
|
||||||
|
|
||||||
|
Created 1 initial phi equivalence classes
|
||||||
|
Coalesced [7] main::i#4 = main::i#1
|
||||||
|
Coalesced down to 1 phi equivalence classes
|
||||||
|
|
||||||
|
FINAL CONTROL FLOW GRAPH
|
||||||
|
|
||||||
|
void main()
|
||||||
|
main: scope:[main] from
|
||||||
|
[0] main::tile = 0
|
||||||
|
to:main::@1
|
||||||
|
main::@1: scope:[main] from main main::@2
|
||||||
|
[1] main::i#2 = phi( main/0, main::@2/main::i#1 )
|
||||||
|
[2] if(main::i#2<$a) goto main::@2
|
||||||
|
to:main::@return
|
||||||
|
main::@return: scope:[main] from main::@1
|
||||||
|
[3] return
|
||||||
|
to:@return
|
||||||
|
main::@2: scope:[main] from main::@1
|
||||||
|
kickasm( uses main::tile) {{ lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}}
|
||||||
|
[5] main::SCREEN[main::i#2] = main::tile
|
||||||
|
[6] main::i#1 = ++ main::i#2
|
||||||
|
to:main::@1
|
||||||
|
|
||||||
|
|
||||||
|
VARIABLE REGISTER WEIGHTS
|
||||||
|
void main()
|
||||||
|
char main::i
|
||||||
|
char main::i#1 // 22.0
|
||||||
|
char main::i#2 // 11.0
|
||||||
|
__loadstore volatile char main::tile // 2.1666666666666665
|
||||||
|
|
||||||
|
Initial phi equivalence classes
|
||||||
|
[ main::i#2 main::i#1 ]
|
||||||
|
Added variable main::tile to live range equivalence class [ main::tile ]
|
||||||
|
Complete equivalence classes
|
||||||
|
[ main::i#2 main::i#1 ]
|
||||||
|
[ main::tile ]
|
||||||
|
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Allocated zp[1]:3 [ main::tile ]
|
||||||
|
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||||
|
Statement [0] main::tile = 0 [ main::tile ] ( [ main::tile ] { } ) always clobbers reg byte a
|
||||||
|
Statement kickasm( uses main::tile) {{ lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}} always clobbers reg byte a
|
||||||
|
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
|
||||||
|
Statement [5] main::SCREEN[main::i#2] = main::tile [ main::tile main::i#2 ] ( [ main::tile main::i#2 ] { } ) always clobbers reg byte a
|
||||||
|
Statement [0] main::tile = 0 [ main::tile ] ( [ main::tile ] { } ) always clobbers reg byte a
|
||||||
|
Statement kickasm( uses main::tile) {{ lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
}} always clobbers reg byte a
|
||||||
|
Statement [5] main::SCREEN[main::i#2] = main::tile [ main::tile main::i#2 ] ( [ main::tile main::i#2 ] { } ) always clobbers reg byte a
|
||||||
|
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
|
||||||
|
Potential registers zp[1]:3 [ main::tile ] : zp[1]:3 ,
|
||||||
|
|
||||||
|
REGISTER UPLIFT SCOPES
|
||||||
|
Uplift Scope [main] 33: zp[1]:2 [ main::i#2 main::i#1 ] 2.17: zp[1]:3 [ main::tile ]
|
||||||
|
Uplift Scope []
|
||||||
|
|
||||||
|
Uplifting [main] best 2826 combination reg byte x [ main::i#2 main::i#1 ] zp[1]:3 [ main::tile ]
|
||||||
|
Uplifting [] best 2826 combination
|
||||||
|
Attempting to uplift remaining variables inzp[1]:3 [ main::tile ]
|
||||||
|
Uplifting [main] best 2826 combination zp[1]:3 [ main::tile ]
|
||||||
|
Allocated (was zp[1]:3) zp[1]:2 [ main::tile ]
|
||||||
|
|
||||||
|
ASSEMBLER BEFORE OPTIMIZATION
|
||||||
|
// File Comments
|
||||||
|
// Demonstrate problem with inline kasm clobbering memory
|
||||||
|
// And the ASM peephole optimizer not realizing this
|
||||||
|
// Upstart
|
||||||
|
// Commodore 64 PRG executable file
|
||||||
|
.file [name="inline-kasm-clobbermem.prg", type="prg", segments="Program"]
|
||||||
|
.segmentdef Program [segments="Basic, Code, Data"]
|
||||||
|
.segmentdef Basic [start=$0801]
|
||||||
|
.segmentdef Code [start=$80d]
|
||||||
|
.segmentdef Data [startAfter="Code"]
|
||||||
|
.segment Basic
|
||||||
|
:BasicUpstart(main)
|
||||||
|
// Global Constants & labels
|
||||||
|
.segment Code
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label tile = 2
|
||||||
|
// [0] main::tile = 0 -- vbuz1=vbuc1
|
||||||
|
lda #0
|
||||||
|
sta.z tile
|
||||||
|
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
__b1_from_main:
|
||||||
|
// [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||||
|
ldx #0
|
||||||
|
jmp __b1
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// [2] if(main::i#2<$a) goto main::@2 -- vbuxx_lt_vbuc1_then_la1
|
||||||
|
cpx #$a
|
||||||
|
bcc __b2
|
||||||
|
jmp __breturn
|
||||||
|
// main::@return
|
||||||
|
__breturn:
|
||||||
|
// [3] return
|
||||||
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// kickasm( uses main::tile) {{ lda #4 sta tile lda #2 sta $02 }}
|
||||||
|
lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
|
||||||
|
// [5] main::SCREEN[main::i#2] = main::tile -- pbuc1_derefidx_vbuxx=vbuz1
|
||||||
|
lda.z tile
|
||||||
|
sta SCREEN,x
|
||||||
|
// [6] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx
|
||||||
|
inx
|
||||||
|
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
__b1_from___b2:
|
||||||
|
// [1] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
jmp __b1
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
||||||
|
ASSEMBLER OPTIMIZATIONS
|
||||||
|
Removing instruction jmp __b1
|
||||||
|
Removing instruction jmp __breturn
|
||||||
|
Succesful ASM optimization Pass5NextJumpElimination
|
||||||
|
Removing instruction __b1_from_main:
|
||||||
|
Removing instruction __breturn:
|
||||||
|
Removing instruction __b1_from___b2:
|
||||||
|
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||||
|
Replacing instruction ldx #0 with TAX
|
||||||
|
|
||||||
|
FINAL SYMBOL TABLE
|
||||||
|
void main()
|
||||||
|
__constant char * const main::SCREEN = (char *) 1024
|
||||||
|
char main::i
|
||||||
|
char main::i#1 // reg byte x 22.0
|
||||||
|
char main::i#2 // reg byte x 11.0
|
||||||
|
__loadstore volatile char main::tile // zp[1]:2 2.1666666666666665
|
||||||
|
|
||||||
|
reg byte x [ main::i#2 main::i#1 ]
|
||||||
|
zp[1]:2 [ main::tile ]
|
||||||
|
|
||||||
|
|
||||||
|
FINAL ASSEMBLER
|
||||||
|
Score: 2766
|
||||||
|
|
||||||
|
// File Comments
|
||||||
|
// Demonstrate problem with inline kasm clobbering memory
|
||||||
|
// And the ASM peephole optimizer not realizing this
|
||||||
|
// Upstart
|
||||||
|
// Commodore 64 PRG executable file
|
||||||
|
.file [name="inline-kasm-clobbermem.prg", type="prg", segments="Program"]
|
||||||
|
.segmentdef Program [segments="Basic, Code, Data"]
|
||||||
|
.segmentdef Basic [start=$0801]
|
||||||
|
.segmentdef Code [start=$80d]
|
||||||
|
.segmentdef Data [startAfter="Code"]
|
||||||
|
.segment Basic
|
||||||
|
:BasicUpstart(main)
|
||||||
|
// Global Constants & labels
|
||||||
|
.segment Code
|
||||||
|
// main
|
||||||
|
main: {
|
||||||
|
.label SCREEN = $400
|
||||||
|
.label tile = 2
|
||||||
|
// __ma char tile = 0
|
||||||
|
// [0] main::tile = 0 -- vbuz1=vbuc1
|
||||||
|
lda #0
|
||||||
|
sta.z tile
|
||||||
|
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||||
|
// [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||||
|
tax
|
||||||
|
// main::@1
|
||||||
|
__b1:
|
||||||
|
// for(char i=0;i<10;i++)
|
||||||
|
// [2] if(main::i#2<$a) goto main::@2 -- vbuxx_lt_vbuc1_then_la1
|
||||||
|
cpx #$a
|
||||||
|
bcc __b2
|
||||||
|
// main::@return
|
||||||
|
// }
|
||||||
|
// [3] return
|
||||||
|
rts
|
||||||
|
// main::@2
|
||||||
|
__b2:
|
||||||
|
// kickasm
|
||||||
|
// kickasm( uses main::tile) {{ lda #4 sta tile lda #2 sta $02 }}
|
||||||
|
lda #4
|
||||||
|
sta tile
|
||||||
|
lda #2
|
||||||
|
sta $02
|
||||||
|
|
||||||
|
// SCREEN[i] = tile
|
||||||
|
// [5] main::SCREEN[main::i#2] = main::tile -- pbuc1_derefidx_vbuxx=vbuz1
|
||||||
|
lda.z tile
|
||||||
|
sta SCREEN,x
|
||||||
|
// for(char i=0;i<10;i++)
|
||||||
|
// [6] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx
|
||||||
|
inx
|
||||||
|
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
|
||||||
|
// [1] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy
|
||||||
|
jmp __b1
|
||||||
|
}
|
||||||
|
// File Data
|
||||||
|
|
9
src/test/ref/inline-kasm-clobbermem.sym
Normal file
9
src/test/ref/inline-kasm-clobbermem.sym
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
void main()
|
||||||
|
__constant char * const main::SCREEN = (char *) 1024
|
||||||
|
char main::i
|
||||||
|
char main::i#1 // reg byte x 22.0
|
||||||
|
char main::i#2 // reg byte x 11.0
|
||||||
|
__loadstore volatile char main::tile // zp[1]:2 2.1666666666666665
|
||||||
|
|
||||||
|
reg byte x [ main::i#2 main::i#1 ]
|
||||||
|
zp[1]:2 [ main::tile ]
|
Loading…
x
Reference in New Issue
Block a user