diff --git a/src/main/java/dk/camelot64/kickc/TODO.txt b/src/main/java/dk/camelot64/kickc/TODO.txt index 3e6776d98..e0d37b022 100644 --- a/src/main/java/dk/camelot64/kickc/TODO.txt +++ b/src/main/java/dk/camelot64/kickc/TODO.txt @@ -10,7 +10,6 @@ TODO's for new Constant Solution + In loopnest.asm x&y are used in both loops - the outer x&y are clobbered by the inner loop. + In voronoi.asm in render() x is clobbered during call to findcol(). - Features - Move the main code into a main() function, and disallow code outside functions. The main function per default has no parameters and exits with RTS. - Improve locality of block sequence for if(cond) { stmt1; } else { stmt2; } to if(!cond) goto @else stmt1; jmp @end; @else: stmt2; @end: diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmConstant.java b/src/main/java/dk/camelot64/kickc/asm/AsmConstant.java new file mode 100644 index 000000000..42ca0bc0c --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/AsmConstant.java @@ -0,0 +1,39 @@ +package dk.camelot64.kickc.asm; + +/** ASM constant declaration */ +public class AsmConstant implements AsmLine { + private final String name; + private final String value; + private int index; + + + public AsmConstant(String name, String value) { + this.name = name; + this.value = value; + } + + @Override + public int getLineBytes() { + return 0; + } + + @Override + public double getLineCycles() { + return 0; + } + + @Override + public String getAsm() { + return ".const "+name+" = "+value; + } + + @Override + public int getIndex() { + return index; + } + + @Override + public void setIndex(int index) { + this.index = index; + } +} diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java b/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java index 352c9729f..cdbfd6b10 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java @@ -74,9 +74,17 @@ public class AsmProgram { public void addLabelDecl(String name, int address) { addLine(new AsmLabelDecl(name, address)); - } + /** + * Add a constant declararion to the ASM + * @param name The name of the constant + * @param value The value of the constant + */ + public void addConstant(String name, String value) { + addLine(new AsmConstant(name, value)); + } + /** diff --git a/src/main/java/dk/camelot64/kickc/icl/Scope.java b/src/main/java/dk/camelot64/kickc/icl/Scope.java index 41f2a6c6b..d7601a863 100644 --- a/src/main/java/dk/camelot64/kickc/icl/Scope.java +++ b/src/main/java/dk/camelot64/kickc/icl/Scope.java @@ -177,6 +177,22 @@ public abstract class Scope implements Symbol { return vars; } + public Collection getAllConstants(boolean includeSubScopes) { + Collection vars = new ArrayList<>(); + for (Symbol symbol : symbols.values()) { + if (symbol instanceof ConstantVar) { + vars.add((ConstantVar) symbol); + } + if (includeSubScopes && symbol instanceof Scope) { + Scope subScope = (Scope) symbol; + vars.addAll(subScope.getAllConstants(true)); + } + + } + return vars; + } + + /** * Get all scopes contained in the scope. This does not include this scope itself. * @param includeSubScopes Include sub-scopes og sub-scopes diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index ea27c0cfd..2e097440b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -30,6 +30,7 @@ public class Pass4CodeGeneration { // Generate global ZP labels asm.startSegment(null, "Global ZP labels"); + addConstants(asm, currentScope); addZpLabels(asm, currentScope); for (ControlFlowBlock block : getGraph().getAllBlocks()) { if (!block.getScope().equals(currentScope)) { @@ -40,6 +41,7 @@ public class Pass4CodeGeneration { asm.startSegment(null, block.getLabel().getFullName()); asm.addScopeBegin(block.getLabel().getFullName().replace('@', 'b').replace(':', '_')); // Add all ZP labels for the scope + addConstants(asm, currentScope); addZpLabels(asm, currentScope); } // Generate entry points (if needed) @@ -76,6 +78,24 @@ public class Pass4CodeGeneration { program.setAsm(asm); } + /** + * Add constant declarations for all scope constants + * + * @param asm The ASM program + * @param scope The scope + */ + private void addConstants(AsmProgram asm, ScopeRef currentScope) { + Collection scopeConstants = program.getScope().getScope(currentScope).getAllConstants(false); + Set added = new LinkedHashSet<>(); + for (ConstantVar scopeConstant : scopeConstants) { + String asmName = scopeConstant.getLocalName(); // scopeConstant.getAsmName() + if (asmName != null && !added.contains(asmName)) { + asm.addConstant(asmName.replace("#","_").replace("$","_"), scopeConstant.getValue().toString(program)); + added.add(asmName); + } + } + } + /** * Add label declarations for all scope variables assigned to ZP registers *