1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added command line support for var_model().

This commit is contained in:
jespergravgaard 2020-02-25 22:15:39 +01:00
parent b05a321d85
commit 946144135a
7 changed files with 77 additions and 40 deletions

View File

@ -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));

View File

@ -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 {

View File

@ -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";

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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