diff --git a/src/main/fragment/pwsc1_derefidx_vbuxx=vwsc2.asm b/src/main/fragment/pwsc1_derefidx_vbuxx=vwsc2.asm new file mode 100644 index 000000000..c648fecbd --- /dev/null +++ b/src/main/fragment/pwsc1_derefidx_vbuxx=vwsc2.asm @@ -0,0 +1,4 @@ +lda #<{c2} +sta {c1},x +lda #>{c2} +sta {c1}+1,x \ No newline at end of file diff --git a/src/main/fragment/pwsc1_derefidx_vbuyy=vwsc2.asm b/src/main/fragment/pwsc1_derefidx_vbuyy=vwsc2.asm new file mode 100644 index 000000000..26c2c45cb --- /dev/null +++ b/src/main/fragment/pwsc1_derefidx_vbuyy=vwsc2.asm @@ -0,0 +1,4 @@ +lda #<{c2} +sta {c1},y +lda #>{c2} +sta {c1}+1,y \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplateSynthesisRule.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplateSynthesisRule.java index d0f4de3e7..ffc336a12 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplateSynthesisRule.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentTemplateSynthesisRule.java @@ -479,18 +479,30 @@ class AsmFragmentTemplateSynthesisRule { synths.add(new AsmFragmentTemplateSynthesisRule("(.*)vw(.)c1(.*)", null, null , "$1vd$2c1$3", null, null)); synths.add(new AsmFragmentTemplateSynthesisRule("(.*)vw(.)c2(.*)", null, null , "$1vd$2c2$3", null, null)); - /* - + /* Removed pending optimization! // Rewrite constant unsigned word values to constant signed dword values synths.add(new AsmFragmentTemplateSynthesisRule("(.*)vwuc1(.*)", null, null , "$1vdsc1$2", null, null)); synths.add(new AsmFragmentTemplateSynthesisRule("(.*)vwuc2(.*)", null, null , "$1vdsc2$2", null, null)); + */ + + /* // Rewrite any zeropage pointer as an unsigned word zeropage values synths.add(new AsmFragmentTemplateSynthesisRule("(.*)p..z(.)(.*)", null, null , "$1vwuz$2$3", null, null)); // Rewrite any constant pointer as an constant unsigned word synths.add(new AsmFragmentTemplateSynthesisRule("(.*)p..c(.)(.*)", null, null , "$1vwuc$2$3", null, null)); - */ + // Synthesize some constant pointers as constant words (remove when the above section can be included) + synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_(lt|gt|le|ge|eq|neq)_p..([cz].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)_(lt|gt|le|ge|eq|neq)_(.*)", null, null, "vwu$1_$2_$3", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([zc].)", null, null, "$1=vwu$2", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(plus|minus|bor|bxor)_p..([cz].)", null, null, "$1=$2_$3_vwu$4", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(plus|minus|bor|bxor)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwu$1=$2_$3_$4", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null)); + synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=_(inc|dec)_p..([cz].)", null, null, "vwu$1=_$2_vwu$3", null, null)); + + // Synthesize constants using AA/XX/YY synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbuc1(.*)", rvalAa+"|"+twoC1+"|"+ derefC1, "lda #{c1}", "$1=$2vbuaa$3", null, mapC)); synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)vbsc1(.*)", rvalAa+"|"+twoC1+"|"+ derefC1, "lda #{c1}", "$1=$2vbsaa$3", null, mapC)); @@ -572,15 +584,6 @@ class AsmFragmentTemplateSynthesisRule { synths.add(new AsmFragmentTemplateSynthesisRule("vb(.)aa=_dec_(.*)", null, null, "vb$1aa=$2_minus_1", null, null)); synths.add(new AsmFragmentTemplateSynthesisRule("vw(.)z1=_inc_vw(.z.)", null, null, "vw$1z1=vw$2_plus_1", null, null)); - // Synthesize some constant pointers as constant words - synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_(lt|gt|le|ge|eq|neq)_p..([cz].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)_(lt|gt|le|ge|eq|neq)_(.*)", null, null, "vwu$1_$2_$3", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([zc].)", null, null, "$1=vwu$2", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(plus|minus|bor|bxor)_p..([cz].)", null, null, "$1=$2_$3_vwu$4", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(plus|minus|bor|bxor)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwu$1=$2_$3_$4", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null)); - synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=_(inc|dec)_p..([cz].)", null, null, "vwu$1=_$2_vwu$3", null, null)); return synths; } diff --git a/src/test/java/dk/camelot64/kickc/test/TestFragments.java b/src/test/java/dk/camelot64/kickc/test/TestFragments.java index 225df2607..a67407a34 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestFragments.java +++ b/src/test/java/dk/camelot64/kickc/test/TestFragments.java @@ -10,9 +10,9 @@ import org.junit.BeforeClass; import org.junit.Test; import java.io.IOException; -import java.security.Signature; import java.util.*; +import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.fail; /** Test the ASM fragment sub-system by loading/synthesizing a lot of different fragments and comparing with reference fragments. */ @@ -135,6 +135,30 @@ public class TestFragments { testFragments("fragments-complex", signaturesComplex); } + @Test + public void testFragmentsExist() { + testFragmentExists("pwsc1_derefidx_vbuxx=vwsc2"); + testFragmentExists("pwsc1_derefidx_vbuyy=vwsc2"); + } + + /** + * Test that a specific fragment can be succesfully loaded/synthesized + * @param signature The fragment signature + */ + private void testFragmentExists(String signature) { + AsmFragmentTemplateSynthesizer.initialize("src/main/fragment/"); + CompileLog log = new CompileLog(); + log.setSysOut(true); + log.setVerboseFragmentLog(true); + List templates = + new ArrayList<>(AsmFragmentTemplateSynthesizer.getFragmentTemplates(signature, log)); + if(templates.size()==0) { + System.out.println(log.toString()); + } + assertTrue("Fragment cannot be synthesized "+signature, templates.size() > 0); + } + + private void testFragments(String fileName, Collection signatures) throws IOException { AsmFragmentTemplateSynthesizer.initialize("src/main/fragment/"); CompileLog log = new CompileLog(); @@ -144,14 +168,15 @@ public class TestFragments { for(int testStep = 0; testStep < 1000; testStep++) { // Calculate the index - int testIdx = (sigs.size() * testStep) / 1000; + int testIdx = (sigs.size() * testStep) / 1000; if(testIdx < testStep) testIdx = testStep; if(testStep > sigs.size() - 1) break; - if((testStep%100) ==0) - System.out.println("Testing "+testIdx + "/"+sigs.size()); + if((testStep % 100) == 0) + System.out.println("Testing " + testIdx + "/" + sigs.size()); String signature = sigs.get(testIdx); + List templates = new ArrayList<>(AsmFragmentTemplateSynthesizer.getFragmentTemplates(signature, log)); Collections.sort(templates, Comparator.comparing(AsmFragmentTemplate::getClobber)); @@ -168,7 +193,7 @@ public class TestFragments { System.gc(); Runtime rt = Runtime.getRuntime(); long usedMB = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024; - System.out.println("Synthesizer Graph Size: " + AsmFragmentTemplateSynthesizer.getSize()+" mem: " + usedMB); + System.out.println("Synthesizer Graph Size: " + AsmFragmentTemplateSynthesizer.getSize() + " mem: " + usedMB); ReferenceHelper helper = new ReferenceHelperFolder("src/test/ref/"); boolean success = helper.testOutput(fileName, ".log", log.toString());