mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-10-11 12:23:45 +00:00
Added another 2 word fragments. Added compiler commandline option to show fragment -fragment <signature>. Closes #145
This commit is contained in:
parent
ea98c9e2eb
commit
ad6a1910c8
@ -0,0 +1,8 @@
|
|||||||
|
sta $ff
|
||||||
|
sec
|
||||||
|
lda {c1},y
|
||||||
|
sbc $ff
|
||||||
|
sta {c1},y
|
||||||
|
lda {c1}+1,y
|
||||||
|
sbc #0
|
||||||
|
sta {c1},y
|
@ -0,0 +1,8 @@
|
|||||||
|
stx $ff
|
||||||
|
sec
|
||||||
|
lda {c1},y
|
||||||
|
sbc $ff
|
||||||
|
sta {c1},y
|
||||||
|
lda {c1}+1,y
|
||||||
|
sbc #0
|
||||||
|
sta {c1},y
|
@ -1,6 +1,8 @@
|
|||||||
package dk.camelot64.kickc;
|
package dk.camelot64.kickc;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
||||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||||
|
import dk.camelot64.kickc.fragment.AsmFragmentTemplateUsages;
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import kickass.KickAssembler;
|
import kickass.KickAssembler;
|
||||||
@ -8,6 +10,7 @@ import picocli.CommandLine;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
@ -27,7 +30,7 @@ import java.util.concurrent.Callable;
|
|||||||
)
|
)
|
||||||
public class KickC implements Callable<Void> {
|
public class KickC implements Callable<Void> {
|
||||||
|
|
||||||
@CommandLine.Parameters(index = "0", description = "The KickC source file to compile.")
|
@CommandLine.Parameters(index = "0", arity="0..1", description = "The KickC source file to compile.")
|
||||||
private Path kcFile = null;
|
private Path kcFile = null;
|
||||||
|
|
||||||
@CommandLine.Option(names = {"-I", "-libdir" }, description = "Path to a library folder, where the compiler looks for included files. This option can be repeated to add multiple library folders.")
|
@CommandLine.Option(names = {"-I", "-libdir" }, description = "Path to a library folder, where the compiler looks for included files. This option can be repeated to add multiple library folders.")
|
||||||
@ -87,6 +90,9 @@ public class KickC implements Callable<Void> {
|
|||||||
@CommandLine.Option(names = {"-vasmoptimize" }, description = "Verbosity Option. Assembler optimization.")
|
@CommandLine.Option(names = {"-vasmoptimize" }, description = "Verbosity Option. Assembler optimization.")
|
||||||
private boolean verboseAsmOptimize = false;
|
private boolean verboseAsmOptimize = false;
|
||||||
|
|
||||||
|
@CommandLine.Option(names = {"-fragment" }, description = "Print the ASM code for a named fragment. The fragment is loaded/synthesized and the ASM variations are written to the output.")
|
||||||
|
private String fragment = null;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
CommandLine.call(new KickC(), args);
|
CommandLine.call(new KickC(), args);
|
||||||
}
|
}
|
||||||
@ -111,121 +117,134 @@ public class KickC implements Callable<Void> {
|
|||||||
AsmFragmentTemplateSynthesizer.initialize("fragment/");
|
AsmFragmentTemplateSynthesizer.initialize("fragment/");
|
||||||
}
|
}
|
||||||
|
|
||||||
String fileBaseName = getFileBaseName(kcFile);
|
if(fragment!=null) {
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
Path kcFileDir = kcFile.getParent();
|
Collection<AsmFragmentTemplate> fragmentTemplates = AsmFragmentTemplateSynthesizer.getFragmentTemplates(fragment, compiler.getLog());
|
||||||
if(kcFileDir==null) {
|
for(AsmFragmentTemplate fragmentTemplate : fragmentTemplates) {
|
||||||
kcFileDir = FileSystems.getDefault().getPath(".");
|
AsmFragmentTemplateUsages.logTemplate(compiler.getLog(), fragmentTemplate, "");
|
||||||
|
}
|
||||||
|
compiler.getLog().setSysOut(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(outputDir==null) {
|
if(kcFile!=null) {
|
||||||
outputDir = kcFileDir;
|
|
||||||
}
|
|
||||||
if(!Files.exists(outputDir)) {
|
|
||||||
Files.createDirectory(outputDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(asmFileName == null) {
|
String fileBaseName = getFileBaseName(kcFile);
|
||||||
asmFileName = fileBaseName + ".asm";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(optimizeUpliftCombinations!=null) {
|
Path kcFileDir = kcFile.getParent();
|
||||||
compiler.setUpliftCombinations(optimizeUpliftCombinations);
|
if(kcFileDir == null) {
|
||||||
}
|
kcFileDir = FileSystems.getDefault().getPath(".");
|
||||||
|
}
|
||||||
|
|
||||||
if(verbose) {
|
if(outputDir == null) {
|
||||||
compiler.getLog().setSysOut(true);
|
outputDir = kcFileDir;
|
||||||
}
|
}
|
||||||
|
if(!Files.exists(outputDir)) {
|
||||||
|
Files.createDirectory(outputDir);
|
||||||
|
}
|
||||||
|
|
||||||
if(verboseParse) {
|
if(asmFileName == null) {
|
||||||
compiler.getLog().setVerboseParse(true);
|
asmFileName = fileBaseName + ".asm";
|
||||||
compiler.getLog().setSysOut(true);
|
}
|
||||||
}
|
|
||||||
if(verboseCreateSsa) {
|
|
||||||
compiler.getLog().setVerboseCreateSsa(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseSSAOptimize) {
|
|
||||||
compiler.getLog().setVerboseSSAOptimize(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseNonOptimization) {
|
|
||||||
compiler.getLog().setVerboseNonOptimization(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseSequencePlan) {
|
|
||||||
compiler.getLog().setVerboseSequencePlan(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseLoopAnalysis) {
|
|
||||||
compiler.getLog().setVerboseLoopAnalysis(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseLoopUnroll) {
|
|
||||||
compiler.getLog().setVerboseLoopUnroll(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseLiveRanges) {
|
|
||||||
compiler.getLog().setVerboseLiveRanges(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseUplift) {
|
|
||||||
compiler.getLog().setVerboseUplift(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseFragments) {
|
|
||||||
compiler.getLog().setVerboseFragmentLog(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
if(verboseAsmOptimize) {
|
|
||||||
compiler.getLog().setVerboseAsmOptimize(true);
|
|
||||||
compiler.getLog().setSysOut(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Compiling " + kcFile);
|
if(optimizeUpliftCombinations != null) {
|
||||||
Program program = compiler.compile(kcFile.toString());
|
compiler.setUpliftCombinations(optimizeUpliftCombinations);
|
||||||
|
}
|
||||||
|
|
||||||
Path asmPath = outputDir.resolve(asmFileName);
|
if(verbose) {
|
||||||
System.out.println("Writing asm file " + asmPath);
|
compiler.getLog().setSysOut(true);
|
||||||
FileOutputStream asmOutputStream = new FileOutputStream(asmPath.toFile());
|
}
|
||||||
OutputStreamWriter asmWriter = new OutputStreamWriter(asmOutputStream);
|
|
||||||
String asmCodeString = program.getAsm().toString(false);
|
|
||||||
asmWriter.write(asmCodeString);
|
|
||||||
asmWriter.close();
|
|
||||||
asmOutputStream.close();
|
|
||||||
|
|
||||||
// Copy Resource Files (if out-dir is different from in-dir)
|
if(verboseParse) {
|
||||||
if(!kcFileDir.toAbsolutePath().equals(outputDir.toAbsolutePath())) {
|
compiler.getLog().setVerboseParse(true);
|
||||||
for(Path resourcePath : program.getAsmResourceFiles()) {
|
compiler.getLog().setSysOut(true);
|
||||||
Path outResourcePath = outputDir.resolve(resourcePath.getFileName().toString());
|
}
|
||||||
System.out.println("Copying resource " + outResourcePath);
|
if(verboseCreateSsa) {
|
||||||
try {
|
compiler.getLog().setVerboseCreateSsa(true);
|
||||||
Files.copy(resourcePath, outResourcePath);
|
compiler.getLog().setSysOut(true);
|
||||||
} catch(FileAlreadyExistsException e) {
|
}
|
||||||
// Ignore this
|
if(verboseSSAOptimize) {
|
||||||
|
compiler.getLog().setVerboseSSAOptimize(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseNonOptimization) {
|
||||||
|
compiler.getLog().setVerboseNonOptimization(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseSequencePlan) {
|
||||||
|
compiler.getLog().setVerboseSequencePlan(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseLoopAnalysis) {
|
||||||
|
compiler.getLog().setVerboseLoopAnalysis(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseLoopUnroll) {
|
||||||
|
compiler.getLog().setVerboseLoopUnroll(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseLiveRanges) {
|
||||||
|
compiler.getLog().setVerboseLiveRanges(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseUplift) {
|
||||||
|
compiler.getLog().setVerboseUplift(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseFragments) {
|
||||||
|
compiler.getLog().setVerboseFragmentLog(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
if(verboseAsmOptimize) {
|
||||||
|
compiler.getLog().setVerboseAsmOptimize(true);
|
||||||
|
compiler.getLog().setSysOut(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Compiling " + kcFile);
|
||||||
|
Program program = compiler.compile(kcFile.toString());
|
||||||
|
|
||||||
|
Path asmPath = outputDir.resolve(asmFileName);
|
||||||
|
System.out.println("Writing asm file " + asmPath);
|
||||||
|
FileOutputStream asmOutputStream = new FileOutputStream(asmPath.toFile());
|
||||||
|
OutputStreamWriter asmWriter = new OutputStreamWriter(asmOutputStream);
|
||||||
|
String asmCodeString = program.getAsm().toString(false);
|
||||||
|
asmWriter.write(asmCodeString);
|
||||||
|
asmWriter.close();
|
||||||
|
asmOutputStream.close();
|
||||||
|
|
||||||
|
// Copy Resource Files (if out-dir is different from in-dir)
|
||||||
|
if(!kcFileDir.toAbsolutePath().equals(outputDir.toAbsolutePath())) {
|
||||||
|
for(Path resourcePath : program.getAsmResourceFiles()) {
|
||||||
|
Path outResourcePath = outputDir.resolve(resourcePath.getFileName().toString());
|
||||||
|
System.out.println("Copying resource " + outResourcePath);
|
||||||
|
try {
|
||||||
|
Files.copy(resourcePath, outResourcePath);
|
||||||
|
} catch(FileAlreadyExistsException e) {
|
||||||
|
// Ignore this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Assemble the asm-file if instructed
|
// Assemble the asm-file if instructed
|
||||||
Path prgPath = outputDir.resolve(fileBaseName + ".prg");
|
Path prgPath = outputDir.resolve(fileBaseName + ".prg");
|
||||||
if(assemble || execute) {
|
if(assemble || execute) {
|
||||||
Path kasmLogPath = outputDir.resolve(fileBaseName+".klog");
|
Path kasmLogPath = outputDir.resolve(fileBaseName + ".klog");
|
||||||
System.out.println("Assembling to " + prgPath.toString());
|
System.out.println("Assembling to " + prgPath.toString());
|
||||||
ByteArrayOutputStream kasmLogOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream kasmLogOutputStream = new ByteArrayOutputStream();
|
||||||
System.setOut(new PrintStream(kasmLogOutputStream));
|
System.setOut(new PrintStream(kasmLogOutputStream));
|
||||||
int kasmResult = KickAssembler.main2(new String[]{asmPath.toString(), "-log", kasmLogPath.toString(), "-o", prgPath.toString(), "-vicesymbols", "-showmem"});
|
int kasmResult = KickAssembler.main2(new String[]{asmPath.toString(), "-log", kasmLogPath.toString(), "-o", prgPath.toString(), "-vicesymbols", "-showmem"});
|
||||||
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
|
System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
|
||||||
if(kasmResult != 0) {
|
if(kasmResult != 0) {
|
||||||
throw new CompileError("KickAssembling file failed! " + kasmLogOutputStream.toString());
|
throw new CompileError("KickAssembling file failed! " + kasmLogOutputStream.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the prg-file if instructed
|
||||||
|
if(execute) {
|
||||||
|
System.out.println("Executing " + prgPath);
|
||||||
|
Process process = Runtime.getRuntime().exec("x64 " + prgPath.toString());
|
||||||
|
process.waitFor();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the prg-file if instructed
|
|
||||||
if(execute) {
|
|
||||||
System.out.println("Executing " + prgPath);
|
|
||||||
Process process = Runtime.getRuntime().exec("x64 " + prgPath.toString() );
|
|
||||||
process.waitFor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -179,13 +179,17 @@ public class AsmFragmentTemplateUsages {
|
|||||||
log.append(String.format("%8d", usage) + " " + template.getSignature()+" - templates: " + bestTemplates.size());
|
log.append(String.format("%8d", usage) + " " + template.getSignature()+" - templates: " + bestTemplates.size());
|
||||||
if(logBody) {
|
if(logBody) {
|
||||||
for(AsmFragmentTemplate bestTemplate : bestTemplates) {
|
for(AsmFragmentTemplate bestTemplate : bestTemplates) {
|
||||||
log.append(" " + (bestTemplate.isFile() ? "*" : "") + bestTemplate.getName() + " - clobber:" + bestTemplate.getClobber().toString() + " cycles:" + bestTemplate.getCycles());
|
logTemplate(log, bestTemplate, " ");
|
||||||
log.append(" " + bestTemplate.getBody().replace("\n", "\n "));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void logTemplate(CompileLog log, AsmFragmentTemplate template, String indent) {
|
||||||
|
log.append(indent + (template.isFile() ? "*" : "") + template.getName() + " - clobber:" + template.getClobber().toString() + " cycles:" + template.getCycles());
|
||||||
|
log.append(indent+ " " + template.getBody().replace("\n", "\n"+indent+" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,7 @@ public class TestFragments {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that a specific fragment can be succesfully loaded/synthesized
|
* Test that a specific fragment can be succesfully loaded/synthesized
|
||||||
|
*
|
||||||
* @param signature The fragment signature
|
* @param signature The fragment signature
|
||||||
*/
|
*/
|
||||||
private void testFragmentExists(String signature) {
|
private void testFragmentExists(String signature) {
|
||||||
@ -156,10 +157,14 @@ public class TestFragments {
|
|||||||
log.setVerboseFragmentLog(true);
|
log.setVerboseFragmentLog(true);
|
||||||
List<AsmFragmentTemplate> templates =
|
List<AsmFragmentTemplate> templates =
|
||||||
new ArrayList<>(AsmFragmentTemplateSynthesizer.getFragmentTemplates(signature, log));
|
new ArrayList<>(AsmFragmentTemplateSynthesizer.getFragmentTemplates(signature, log));
|
||||||
if(templates.size()==0) {
|
if(templates.size() > 0) {
|
||||||
System.out.println(log.toString());
|
log.append("");
|
||||||
|
for(AsmFragmentTemplate template : templates) {
|
||||||
|
AsmFragmentTemplateUsages.logTemplate(log, template, "");
|
||||||
|
}
|
||||||
|
log.append("");
|
||||||
}
|
}
|
||||||
assertTrue("Fragment cannot be synthesized "+signature, templates.size() > 0);
|
assertTrue("Fragment cannot be synthesized " + signature, templates.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user