mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-26 12:49:21 +00:00
Added command line support for var_model().
This commit is contained in:
parent
b05a321d85
commit
946144135a
@ -42,6 +42,9 @@ public class Compiler {
|
||||
/** File name of link script to use (from command line parameter). */
|
||||
private String linkScriptFileName;
|
||||
|
||||
/** Variable optimization/memory area configuration to use (from command line parameter). */
|
||||
private VariableBuilderConfig variableBuilderConfig;
|
||||
|
||||
public Compiler() {
|
||||
this.program = new Program();
|
||||
}
|
||||
@ -55,7 +58,11 @@ public class Compiler {
|
||||
}
|
||||
|
||||
public void setLinkScriptFileName(String linkScript) {
|
||||
linkScriptFileName = linkScript;
|
||||
this.linkScriptFileName = linkScript;
|
||||
}
|
||||
|
||||
public void setVariableBuilderConfig(VariableBuilderConfig variableBuilderConfig) {
|
||||
this.variableBuilderConfig = variableBuilderConfig;
|
||||
}
|
||||
|
||||
public void setUpliftCombinations(int upliftCombinations) {
|
||||
@ -128,7 +135,16 @@ public class Compiler {
|
||||
program.setStatementSequence(new StatementSequence());
|
||||
CParser cParser = new CParser(program);
|
||||
KickCParser.FileContext cFileContext = cParser.loadAndParseCFile(fileName, currentPath);
|
||||
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(cParser, cFileContext, program);
|
||||
|
||||
if(variableBuilderConfig == null) {
|
||||
VariableBuilderConfig config = new VariableBuilderConfig();
|
||||
VariableBuilderConfig.defaultPreConfig(config, program.getLog());
|
||||
VariableBuilderConfig.defaultPostConfig(config, program.getLog());
|
||||
this.variableBuilderConfig = config;
|
||||
}
|
||||
|
||||
Pass0GenerateStatementSequence pass0GenerateStatementSequence = new Pass0GenerateStatementSequence(cParser, cFileContext, program, variableBuilderConfig);
|
||||
|
||||
pass0GenerateStatementSequence.generate();
|
||||
|
||||
StatementSequence sequence = program.getStatementSequence();
|
||||
@ -298,8 +314,8 @@ public class Compiler {
|
||||
optimizations.add(new Pass2AliasElimination(program));
|
||||
optimizations.add(new Pass2IdenticalPhiElimination(program));
|
||||
optimizations.add(new Pass2DuplicateRValueIdentification(program));
|
||||
optimizations.add(() -> { program.clearStatementIndices(); return false; });
|
||||
optimizations.add(() -> { program.clearVariableReferenceInfos(); return false; });
|
||||
optimizations.add(() -> { program.clearStatementIndices(); return false; });
|
||||
optimizations.add(() -> { program.clearVariableReferenceInfos();return false; });
|
||||
optimizations.add(() -> { program.clearStatementInfos(); return false; });
|
||||
optimizations.add(new PassNStatementIndices(program));
|
||||
optimizations.add(new Pass2ConditionalJumpSimplification(program));
|
||||
|
@ -3,10 +3,8 @@ package dk.camelot64.kickc;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplate;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateUsages;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.TargetCpu;
|
||||
import dk.camelot64.kickc.model.TargetPlatform;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||
import kickass.KickAssembler;
|
||||
import kickass.nonasm.c64.CharToPetsciiConverter;
|
||||
import picocli.CommandLine;
|
||||
@ -16,9 +14,11 @@ import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** KickC Commandline */
|
||||
@CommandLine.Command(
|
||||
@ -132,15 +132,18 @@ public class KickC implements Callable<Void> {
|
||||
@CommandLine.Option(names = {"-Si"}, description = "Interleave comments with intermediate language code and ASM fragment names in the generated ASM.")
|
||||
private boolean interleaveIclFile = false;
|
||||
|
||||
@CommandLine.Option(names = {"-t", "-target"}, description = "The target system. Default is C64 with BASIC upstart. ")
|
||||
@CommandLine.Option(names = {"-t", "-target"}, description = "The target system. Default is C64 with BASIC upstart. See #pragma target()")
|
||||
private String target = TargetPlatform.C64BASIC.getName();
|
||||
|
||||
@CommandLine.Option(names = {"-cpu"}, description = "The target CPU. Default is 6502 with illegal opcodes. ")
|
||||
@CommandLine.Option(names = {"-cpu"}, description = "The target CPU. Default is 6502 with illegal opcodes. See #pragma cpu()")
|
||||
private String cpu = TargetCpu.MOS6502X.getName();
|
||||
|
||||
@CommandLine.Option(names = {"-T", "-link"}, description = "Link using a linker script in KickAss segment format.")
|
||||
@CommandLine.Option(names = {"-T", "-link"}, description = "Link using a linker script in KickAss segment format. See #pragma link()")
|
||||
private String linkScript = null;
|
||||
|
||||
@CommandLine.Option(names = {"-var_model"}, description = "Configure variable optimization/memory area. Default is ssa_zp. See #pragma var_model()")
|
||||
private String varModel = null;
|
||||
|
||||
/** Program Exit Code signaling a compile error. */
|
||||
public static final int COMPILE_ERROR = 1;
|
||||
|
||||
@ -268,6 +271,13 @@ public class KickC implements Callable<Void> {
|
||||
compiler.setLinkScriptFileName(linkScript);
|
||||
}
|
||||
|
||||
if(varModel!=null) {
|
||||
List<String> settings = Arrays.asList(varModel.split(","));
|
||||
settings = settings.stream().map(String::trim).collect(Collectors.toList());
|
||||
final VariableBuilderConfig config = VariableBuilderConfig.fromSettings(settings, StatementSource.NONE, compiler.getLog());
|
||||
compiler.setVariableBuilderConfig(config);
|
||||
}
|
||||
|
||||
System.out.println("Compiling " + kcFile);
|
||||
Program program = null;
|
||||
try {
|
||||
|
@ -40,6 +40,32 @@ import java.util.*;
|
||||
*/
|
||||
public class VariableBuilderConfig {
|
||||
|
||||
/**
|
||||
* Create variable builder configuration from a number of settings.
|
||||
* @param settings The settings.
|
||||
* @param statementSource The statement source (used for error messages)
|
||||
* @param program The program log (used for error messages)
|
||||
* @return A variable builder configuration
|
||||
*/
|
||||
public static VariableBuilderConfig fromSettings(List<String> settings, StatementSource statementSource, CompileLog log) {
|
||||
// Detect if the first setting is "full"
|
||||
boolean full = false;
|
||||
if(settings.size() > 0 && settings.get(0).equals(SETTING_FULL)) {
|
||||
full = true;
|
||||
settings = settings.subList(1, settings.size());
|
||||
}
|
||||
VariableBuilderConfig config = new VariableBuilderConfig();
|
||||
if(!full)
|
||||
defaultPreConfig(config, log);
|
||||
// Apply all settings
|
||||
for(String setting : settings) {
|
||||
config.addSetting(setting, log, statementSource);
|
||||
}
|
||||
if(!full)
|
||||
defaultPostConfig(config, log);
|
||||
return config;
|
||||
}
|
||||
|
||||
/** Setting specifying that the Variable Builder config is "full" and the default pre/post should not be applied. */
|
||||
public static final String SETTING_FULL = "full";
|
||||
|
||||
|
@ -28,6 +28,7 @@ import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Generates program SSA form by visiting the ANTLR4 parse tree
|
||||
@ -51,17 +52,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
/** Configuration for the variable builder. */
|
||||
private VariableBuilderConfig variableBuilderConfig;
|
||||
|
||||
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program) {
|
||||
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, VariableBuilderConfig variableBuilderConfig) {
|
||||
this.cParser = cParser;
|
||||
this.fileCtx = fileCtx;
|
||||
this.program = program;
|
||||
this.sequence = program.getStatementSequence();
|
||||
this.scopeStack = new Stack<>();
|
||||
this.defaultMemoryArea = Variable.MemoryArea.ZEROPAGE_MEMORY;
|
||||
VariableBuilderConfig config = new VariableBuilderConfig();
|
||||
VariableBuilderConfig.defaultPreConfig(config, program.getLog());
|
||||
VariableBuilderConfig.defaultPostConfig(config, program.getLog());
|
||||
this.variableBuilderConfig = config;
|
||||
this.variableBuilderConfig = variableBuilderConfig;
|
||||
scopeStack.push(program.getScope());
|
||||
}
|
||||
|
||||
@ -107,22 +105,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) {
|
||||
List<TerminalNode> settings = new ArrayList<>(ctx.NAME());
|
||||
// Detect if the first setting is "full"
|
||||
boolean full = false;
|
||||
if(settings.size() > 0 && settings.get(0).getText().equals(VariableBuilderConfig.SETTING_FULL)) {
|
||||
full = true;
|
||||
settings = settings.subList(1, settings.size());
|
||||
}
|
||||
VariableBuilderConfig config = new VariableBuilderConfig();
|
||||
if(!full)
|
||||
VariableBuilderConfig.defaultPreConfig(config, program.getLog());
|
||||
for(TerminalNode varModel : settings) {
|
||||
config.addSetting(varModel.getText(), program.getLog(), new StatementSource(ctx));
|
||||
}
|
||||
if(!full)
|
||||
VariableBuilderConfig.defaultPostConfig(config, program.getLog());
|
||||
this.variableBuilderConfig = config;
|
||||
List<TerminalNode> settingNodes = new ArrayList<>(ctx.NAME());
|
||||
List<String> settings = settingNodes.stream().map(ParseTree::getText).collect(Collectors.toList());
|
||||
this.variableBuilderConfig = VariableBuilderConfig.fromSettings(settings, new StatementSource(ctx), program.getLog());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
// Screen Sprite pointers on screen 2
|
||||
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
|
||||
// Address of the sprites covering the playfield
|
||||
.label PLAYFIELD_SPRITES = $2000
|
||||
.label PLAYFIELD_SPRITES = $3000
|
||||
// Address of the charset
|
||||
.label PLAYFIELD_CHARSET = $2800
|
||||
// The Y-position of the first sprite row
|
||||
|
@ -427,7 +427,7 @@ SYMBOL TABLE SSA
|
||||
(const byte*) PLAYFIELD_CHARSET = (byte*)(number) $2800
|
||||
(const byte*) PLAYFIELD_SCREEN_1 = (byte*)(number) $400
|
||||
(const byte*) PLAYFIELD_SCREEN_2 = (byte*)(number) $2c00
|
||||
(const byte*) PLAYFIELD_SPRITES = (byte*)(number) $2000
|
||||
(const byte*) PLAYFIELD_SPRITES = (byte*)(number) $3000
|
||||
(const byte*) PLAYFIELD_SPRITE_PTRS_1 = (const byte*) PLAYFIELD_SCREEN_1+(const word) SPRITE_PTRS
|
||||
(const byte*) PLAYFIELD_SPRITE_PTRS_2 = (const byte*) PLAYFIELD_SCREEN_2+(const word) SPRITE_PTRS
|
||||
(const byte*) PROCPORT = (byte*)(number) 1
|
||||
@ -779,7 +779,7 @@ Simplifying constant pointer cast (byte*) 56578
|
||||
Simplifying constant pointer cast (void()**) 65534
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant pointer cast (byte*) 11264
|
||||
Simplifying constant pointer cast (byte*) 8192
|
||||
Simplifying constant pointer cast (byte*) 12288
|
||||
Simplifying constant pointer cast (byte*) 10240
|
||||
Simplifying constant integer cast $13
|
||||
Simplifying constant pointer cast (byte*) 10240
|
||||
@ -1631,7 +1631,7 @@ Target platform is c64basic / MOS6502X
|
||||
// Screen Sprite pointers on screen 2
|
||||
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
|
||||
// Address of the sprites covering the playfield
|
||||
.label PLAYFIELD_SPRITES = $2000
|
||||
.label PLAYFIELD_SPRITES = $3000
|
||||
// Address of the charset
|
||||
.label PLAYFIELD_CHARSET = $2800
|
||||
// The Y-position of the first sprite row
|
||||
@ -2501,7 +2501,7 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
// Screen Sprite pointers on screen 2
|
||||
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
|
||||
// Address of the sprites covering the playfield
|
||||
.label PLAYFIELD_SPRITES = $2000
|
||||
.label PLAYFIELD_SPRITES = $3000
|
||||
// Address of the charset
|
||||
.label PLAYFIELD_CHARSET = $2800
|
||||
// The Y-position of the first sprite row
|
||||
@ -3186,7 +3186,7 @@ FINAL SYMBOL TABLE
|
||||
(const byte*) PLAYFIELD_CHARSET = (byte*) 10240
|
||||
(const byte*) PLAYFIELD_SCREEN_1 = (byte*) 1024
|
||||
(const byte*) PLAYFIELD_SCREEN_2 = (byte*) 11264
|
||||
(const byte*) PLAYFIELD_SPRITES = (byte*) 8192
|
||||
(const byte*) PLAYFIELD_SPRITES = (byte*) 12288
|
||||
(const byte*) PLAYFIELD_SPRITE_PTRS_1 = (const byte*) PLAYFIELD_SCREEN_1+(const word) SPRITE_PTRS
|
||||
(const byte*) PLAYFIELD_SPRITE_PTRS_2 = (const byte*) PLAYFIELD_SCREEN_2+(const word) SPRITE_PTRS
|
||||
(const byte*) PROCPORT = (byte*) 1
|
||||
@ -3393,7 +3393,7 @@ Score: 11662
|
||||
// Screen Sprite pointers on screen 2
|
||||
.label PLAYFIELD_SPRITE_PTRS_2 = PLAYFIELD_SCREEN_2+SPRITE_PTRS
|
||||
// Address of the sprites covering the playfield
|
||||
.label PLAYFIELD_SPRITES = $2000
|
||||
.label PLAYFIELD_SPRITES = $3000
|
||||
// Address of the charset
|
||||
.label PLAYFIELD_CHARSET = $2800
|
||||
// The Y-position of the first sprite row
|
||||
|
@ -19,7 +19,7 @@
|
||||
(const byte*) PLAYFIELD_CHARSET = (byte*) 10240
|
||||
(const byte*) PLAYFIELD_SCREEN_1 = (byte*) 1024
|
||||
(const byte*) PLAYFIELD_SCREEN_2 = (byte*) 11264
|
||||
(const byte*) PLAYFIELD_SPRITES = (byte*) 8192
|
||||
(const byte*) PLAYFIELD_SPRITES = (byte*) 12288
|
||||
(const byte*) PLAYFIELD_SPRITE_PTRS_1 = (const byte*) PLAYFIELD_SCREEN_1+(const word) SPRITE_PTRS
|
||||
(const byte*) PLAYFIELD_SPRITE_PTRS_2 = (const byte*) PLAYFIELD_SCREEN_2+(const word) SPRITE_PTRS
|
||||
(const byte*) PROCPORT = (byte*) 1
|
||||
|
Loading…
Reference in New Issue
Block a user