mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-22 21:29:50 +00:00
Added full compile log to test
This commit is contained in:
parent
8e59603418
commit
0116c9e21d
25
src/dk/camelot64/kickc/CompileLog.java
Normal file
25
src/dk/camelot64/kickc/CompileLog.java
Normal file
@ -0,0 +1,25 @@
|
||||
package dk.camelot64.kickc;
|
||||
|
||||
/** Log of actions & results during compile*/
|
||||
public class CompileLog {
|
||||
|
||||
StringBuilder log;
|
||||
|
||||
public CompileLog() {
|
||||
this.log = new StringBuilder();
|
||||
}
|
||||
|
||||
public void append(String msg) {
|
||||
log.append(msg);
|
||||
log.append("\n");
|
||||
}
|
||||
|
||||
public StringBuilder getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return log.toString();
|
||||
}
|
||||
}
|
@ -17,11 +17,13 @@ public class Compiler {
|
||||
private AsmProgram asmProgram;
|
||||
private ControlFlowGraph graph;
|
||||
private Scope symbols;
|
||||
private CompileLog log;
|
||||
|
||||
public CompilationResult(AsmProgram asmProgram, ControlFlowGraph graph, Scope symbols) {
|
||||
public CompilationResult(AsmProgram asmProgram, ControlFlowGraph graph, Scope symbols, CompileLog log) {
|
||||
this.asmProgram = asmProgram;
|
||||
this.graph = graph;
|
||||
this.symbols = symbols;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public AsmProgram getAsmProgram() {
|
||||
@ -35,10 +37,15 @@ public class Compiler {
|
||||
public Scope getSymbols() {
|
||||
return symbols;
|
||||
}
|
||||
|
||||
public CompileLog getLog() {
|
||||
return log;
|
||||
}
|
||||
}
|
||||
|
||||
public CompilationResult compile(final CharStream input) throws IOException {
|
||||
System.out.println(input.toString());
|
||||
CompileLog log = new CompileLog();
|
||||
log.append(input.toString());
|
||||
KickCLexer lexer = new KickCLexer(input);
|
||||
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
||||
parser.setBuildParseTree(true);
|
||||
@ -49,50 +56,50 @@ public class Compiler {
|
||||
}
|
||||
});
|
||||
KickCParser.FileContext file = parser.file();
|
||||
Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence();
|
||||
Pass1GenerateStatementSequence pass1GenerateStatementSequence = new Pass1GenerateStatementSequence(log);
|
||||
pass1GenerateStatementSequence.generate(file);
|
||||
StatementSequence statementSequence = pass1GenerateStatementSequence.getSequence();
|
||||
Scope programScope = pass1GenerateStatementSequence.getProgramScope();
|
||||
Pass1TypeInference pass1TypeInference = new Pass1TypeInference();
|
||||
pass1TypeInference.inferTypes(statementSequence, programScope);
|
||||
|
||||
System.out.println("PROGRAM");
|
||||
System.out.println(statementSequence.toString());
|
||||
System.out.println("SYMBOLS");
|
||||
System.out.println(programScope.getSymbolTableContents());
|
||||
log.append("PROGRAM");
|
||||
log.append(statementSequence.toString());
|
||||
log.append("SYMBOLS");
|
||||
log.append(programScope.getSymbolTableContents());
|
||||
|
||||
Pass1GenerateControlFlowGraph pass1GenerateControlFlowGraph = new Pass1GenerateControlFlowGraph(programScope);
|
||||
ControlFlowGraph controlFlowGraph = pass1GenerateControlFlowGraph.generate(statementSequence);
|
||||
System.out.println("INITIAL CONTROL FLOW GRAPH");
|
||||
System.out.println(controlFlowGraph.toString());
|
||||
log.append("INITIAL CONTROL FLOW GRAPH");
|
||||
log.append(controlFlowGraph.toString());
|
||||
|
||||
Pass1ProcedureCallParameters pass1ProcedureCallParameters =
|
||||
new Pass1ProcedureCallParameters(programScope, controlFlowGraph);
|
||||
controlFlowGraph = pass1ProcedureCallParameters.generate();
|
||||
System.out.println("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL");
|
||||
System.out.println(controlFlowGraph.toString());
|
||||
log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL");
|
||||
log.append(controlFlowGraph.toString());
|
||||
|
||||
Pass1GenerateSingleStaticAssignmentForm pass1GenerateSingleStaticAssignmentForm =
|
||||
new Pass1GenerateSingleStaticAssignmentForm(programScope, controlFlowGraph);
|
||||
new Pass1GenerateSingleStaticAssignmentForm(log, programScope, controlFlowGraph);
|
||||
pass1GenerateSingleStaticAssignmentForm.generate();
|
||||
|
||||
System.out.println("CONTROL FLOW GRAPH SSA");
|
||||
System.out.println(controlFlowGraph.toString());
|
||||
log.append("CONTROL FLOW GRAPH SSA");
|
||||
log.append(controlFlowGraph.toString());
|
||||
|
||||
Pass1ProcedureCallsReturnValue pass1ProcedureCallsReturnValue =
|
||||
new Pass1ProcedureCallsReturnValue(programScope, controlFlowGraph);
|
||||
controlFlowGraph = pass1ProcedureCallsReturnValue.generate();
|
||||
System.out.println("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN");
|
||||
System.out.println(controlFlowGraph.toString());
|
||||
log.append("CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN");
|
||||
log.append(controlFlowGraph.toString());
|
||||
|
||||
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
|
||||
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2AliasElimination(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, programScope));
|
||||
optimizations.add(new Pass2CullEmptyBlocks(controlFlowGraph, programScope, log));
|
||||
optimizations.add(new Pass2ConstantPropagation(controlFlowGraph, programScope, log));
|
||||
optimizations.add(new Pass2ConstantAdditionElimination(controlFlowGraph, programScope, log));
|
||||
optimizations.add(new Pass2AliasElimination(controlFlowGraph, programScope, log));
|
||||
optimizations.add(new Pass2RedundantPhiElimination(controlFlowGraph, programScope, log));
|
||||
optimizations.add(new Pass2SelfPhiElimination(controlFlowGraph, programScope, log));
|
||||
optimizations.add(new Pass2ConditionalJumpSimplification(controlFlowGraph, programScope, log));
|
||||
|
||||
List<Pass2SsaAssertion> assertions = new ArrayList<>();
|
||||
assertions.add(new Pass2AssertSymbols(controlFlowGraph, programScope));
|
||||
@ -107,10 +114,10 @@ public class Compiler {
|
||||
for (Pass2SsaOptimization optimization : optimizations) {
|
||||
boolean stepOptimized = optimization.optimize();
|
||||
if (stepOptimized) {
|
||||
System.out.println("Succesful SSA optimization "+optimization);
|
||||
log.append("Succesful SSA optimization "+optimization+"");
|
||||
ssaOptimized = true;
|
||||
System.out.println("CONTROL FLOW GRAPH");
|
||||
System.out.println(controlFlowGraph.toString());
|
||||
log.append("CONTROL FLOW GRAPH");
|
||||
log.append(controlFlowGraph.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,27 +129,27 @@ public class Compiler {
|
||||
Pass3CodeGeneration pass3CodeGeneration = new Pass3CodeGeneration(controlFlowGraph, programScope);
|
||||
AsmProgram asmProgram = pass3CodeGeneration.generate();
|
||||
|
||||
System.out.println("INITIAL ASM");
|
||||
System.out.println(asmProgram.toString());
|
||||
log.append("INITIAL ASM");
|
||||
log.append(asmProgram.toString());
|
||||
|
||||
List<Pass4AsmOptimization> pass4Optimizations = new ArrayList<>();
|
||||
pass4Optimizations.add(new Pass4NextJumpElimination(asmProgram));
|
||||
pass4Optimizations.add(new Pass4UnnecesaryLoadElimination(asmProgram));
|
||||
pass4Optimizations.add(new Pass4NextJumpElimination(asmProgram, log));
|
||||
pass4Optimizations.add(new Pass4UnnecesaryLoadElimination(asmProgram, log));
|
||||
boolean asmOptimized = true;
|
||||
while(asmOptimized) {
|
||||
asmOptimized = false;
|
||||
for (Pass4AsmOptimization optimization : pass4Optimizations) {
|
||||
boolean stepOtimized = optimization.optimize();
|
||||
if(stepOtimized) {
|
||||
System.out.println("Succesful ASM optimization "+optimization);
|
||||
log.append("Succesful ASM optimization "+optimization);
|
||||
asmOptimized = true;
|
||||
System.out.println("ASSEMBLER");
|
||||
System.out.println(asmProgram.toString());
|
||||
log.append("ASSEMBLER");
|
||||
log.append(asmProgram.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new CompilationResult(asmProgram, controlFlowGraph, programScope);
|
||||
return new CompilationResult(asmProgram, controlFlowGraph, programScope, log);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -33,26 +34,26 @@ public class AsmFragment {
|
||||
private String signature;
|
||||
|
||||
public AsmFragment(StatementConditionalJump conditionalJump, ControlFlowBlock block, Scope symbols, ControlFlowGraph graph) {
|
||||
this.bindings = new HashMap<>();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.symbols = symbols;
|
||||
String conditionalJumpSignature = conditionalJumpSignature(conditionalJump, block, graph);
|
||||
setSignature(conditionalJumpSignature);
|
||||
}
|
||||
|
||||
public AsmFragment(StatementAssignment assignment, Scope symbols) {
|
||||
this.bindings = new HashMap<>();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.symbols = symbols;
|
||||
setSignature(assignmentSignature(assignment.getLValue(), assignment.getRValue1(), assignment.getOperator(), assignment.getRValue2()));
|
||||
}
|
||||
|
||||
public AsmFragment(LValue lValue, RValue rValue, Scope symbols) {
|
||||
this.bindings = new HashMap<>();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.symbols = symbols;
|
||||
setSignature(assignmentSignature(lValue, null, null, rValue));
|
||||
}
|
||||
|
||||
public AsmFragment(StatementAssignment assignment, StatementAssignment assignmentAlu, Scope symbols) {
|
||||
this.bindings = new HashMap<>();
|
||||
this.bindings = new LinkedHashMap<>();
|
||||
this.symbols = symbols;
|
||||
setSignature(assignmentWithAluSignature(assignment, assignmentAlu));
|
||||
|
||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.asm.parser;
|
||||
import dk.camelot64.kickc.asm.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -16,7 +17,7 @@ public class AsmProgramStaticRegisterValues {
|
||||
|
||||
public AsmProgramStaticRegisterValues(AsmProgram program) {
|
||||
this.program = program;
|
||||
this.values = new HashMap<>();
|
||||
this.values = new LinkedHashMap<>();
|
||||
initValues();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -10,10 +12,12 @@ import java.util.Map;
|
||||
*/
|
||||
public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
|
||||
private CompileLog log;
|
||||
private Scope symbols;
|
||||
private ControlFlowGraph controlFlowGraph;
|
||||
|
||||
public Pass1GenerateSingleStaticAssignmentForm(Scope symbols, ControlFlowGraph controlFlowGraph) {
|
||||
public Pass1GenerateSingleStaticAssignmentForm(CompileLog log, Scope symbols, ControlFlowGraph controlFlowGraph) {
|
||||
this.log = log;
|
||||
this.symbols = symbols;
|
||||
this.controlFlowGraph = controlFlowGraph;
|
||||
}
|
||||
@ -23,7 +27,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
versionAllUses();
|
||||
boolean done;
|
||||
do {
|
||||
System.out.println("Completing Phi functions...");
|
||||
log.append("Completing Phi functions...");
|
||||
done = completePhiFunctions();
|
||||
} while (!done);
|
||||
}
|
||||
@ -63,9 +67,9 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
private void versionAllUses() {
|
||||
for (ControlFlowBlock block : controlFlowGraph.getAllBlocks()) {
|
||||
// Newest version of variables in the block.
|
||||
Map<VariableUnversioned, VariableVersion> blockVersions = new HashMap<>();
|
||||
Map<VariableUnversioned, VariableVersion> blockVersions = new LinkedHashMap<>();
|
||||
// New phi functions introduced in the block to create versions of variables.
|
||||
Map<VariableUnversioned, VariableVersion> blockNewPhis = new HashMap<>();
|
||||
Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>();
|
||||
for (Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementReturn) {
|
||||
StatementReturn statementReturn = (StatementReturn) statement;
|
||||
@ -163,7 +167,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
* false if new phis were added, meaning another iteration is needed.
|
||||
*/
|
||||
private boolean completePhiFunctions() {
|
||||
Map<Label, Map<VariableUnversioned, VariableVersion>> newPhis = new HashMap<>();
|
||||
Map<Label, Map<VariableUnversioned, VariableVersion>> newPhis = new LinkedHashMap<>();
|
||||
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = buildSymbolMap();
|
||||
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
@ -183,7 +187,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
// No previous symbol found in predecessor block. Look in new phi functions.
|
||||
Map<VariableUnversioned, VariableVersion> predecessorNewPhis = newPhis.get(predecessorLabel);
|
||||
if (predecessorNewPhis == null) {
|
||||
predecessorNewPhis = new HashMap<>();
|
||||
predecessorNewPhis = new LinkedHashMap<>();
|
||||
newPhis.put(predecessorLabel, predecessorNewPhis);
|
||||
}
|
||||
previousSymbol = predecessorNewPhis.get(unversioned);
|
||||
@ -216,7 +220,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
* Maps Control Flow Block Label -> ( Unversioned Symbol -> Versioned Symbol) for all relevant symbols.
|
||||
*/
|
||||
private Map<Label, Map<VariableUnversioned, VariableVersion>> buildSymbolMap() {
|
||||
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = new HashMap<>();
|
||||
Map<Label, Map<VariableUnversioned, VariableVersion>> symbolMap = new LinkedHashMap<>();
|
||||
for (ControlFlowBlock block : this.controlFlowGraph.getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
if (statement instanceof StatementAssignment) {
|
||||
@ -228,7 +232,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
VariableUnversioned unversioned = versioned.getVersionOf();
|
||||
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
|
||||
if (blockMap == null) {
|
||||
blockMap = new HashMap<>();
|
||||
blockMap = new LinkedHashMap<>();
|
||||
symbolMap.put(label, blockMap);
|
||||
}
|
||||
blockMap.put(unversioned, versioned);
|
||||
@ -240,7 +244,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
Label label = block.getLabel();
|
||||
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
|
||||
if (blockMap == null) {
|
||||
blockMap = new HashMap<>();
|
||||
blockMap = new LinkedHashMap<>();
|
||||
symbolMap.put(label, blockMap);
|
||||
}
|
||||
blockMap.put(unversioned, versioned);
|
||||
@ -253,7 +257,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
||||
VariableUnversioned unversioned = versioned.getVersionOf();
|
||||
Map<VariableUnversioned, VariableVersion> blockMap = symbolMap.get(label);
|
||||
if (blockMap == null) {
|
||||
blockMap = new HashMap<>();
|
||||
blockMap = new LinkedHashMap<>();
|
||||
symbolMap.put(label, blockMap);
|
||||
}
|
||||
blockMap.put(unversioned, versioned);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.parser.KickCBaseVisitor;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
@ -14,11 +15,13 @@ import java.util.Stack;
|
||||
*/
|
||||
public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
|
||||
private CompileLog log;
|
||||
private Scope programScope;
|
||||
private Stack<Scope> scopeStack;
|
||||
private StatementSequence sequence;
|
||||
|
||||
public Pass1GenerateStatementSequence() {
|
||||
public Pass1GenerateStatementSequence(CompileLog log) {
|
||||
this.log = log;
|
||||
this.programScope = new Scope();
|
||||
this.scopeStack = new Stack<>();
|
||||
scopeStack.push(programScope);
|
||||
@ -214,7 +217,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
@Override
|
||||
public Void visitStmtDeclaration(KickCParser.StmtDeclarationContext ctx) {
|
||||
if (ctx.getChild(0).getText().equals("const")) {
|
||||
System.out.println("Const!" + ctx.getText());
|
||||
log.append("Const!" + ctx.getText());
|
||||
}
|
||||
SymbolType type = (SymbolType) visit(ctx.typeDecl());
|
||||
VariableUnversioned lValue = getCurrentSymbols().addVariable(ctx.NAME().getText(), type);
|
||||
@ -300,7 +303,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
|
||||
@Override
|
||||
public RValue visitExprCast(KickCParser.ExprCastContext ctx) {
|
||||
System.out.println("Cast type ignored!");
|
||||
log.append("Cast type ignored!");
|
||||
return (RValue) visit(ctx.expr());
|
||||
}
|
||||
|
||||
@ -449,7 +452,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
||||
for (PrePostModifier mod : modifiers) {
|
||||
Statement stmt = new StatementAssignment((LValue) mod.child, mod.operator, mod.child);
|
||||
parser.sequence.addStatement(stmt);
|
||||
System.out.println("Adding pre/post-modifier "+stmt);
|
||||
parser.log.append("Adding pre/post-modifier "+stmt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -7,8 +9,8 @@ import java.util.*;
|
||||
*/
|
||||
public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +30,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
for (Variable var : aliasSet.getEliminateVars()) {
|
||||
str.append(var + " ");
|
||||
}
|
||||
System.out.println("Alias " + str);
|
||||
log.append("Alias " + str);
|
||||
}
|
||||
return (aliases.size() > 0);
|
||||
}
|
||||
@ -81,7 +83,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
public Map<Variable, Variable> getReplacements() {
|
||||
HashMap<Variable, Variable> replacements = new HashMap<>();
|
||||
HashMap<Variable, Variable> replacements = new LinkedHashMap<>();
|
||||
for (AliasSet aliasSet : aliases) {
|
||||
Variable keepVar = aliasSet.getKeepVar();
|
||||
for (Variable var : aliasSet.getEliminateVars()) {
|
||||
@ -232,7 +234,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
|
||||
RValue phiRValue = previousSymbol.getRValue();
|
||||
if (aliasSet.contains(phiRValue)) {
|
||||
System.out.println("Alias candidate removed " + phiRValue);
|
||||
log.append("Alias candidate removed " + phiRValue);
|
||||
aliasSet.remove(phiRValue);
|
||||
break;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -11,8 +13,8 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
|
||||
|
||||
private Map<Variable, List<Statement>> allUsages;
|
||||
|
||||
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2ConditionalJumpSimplification(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,7 +57,7 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
|
||||
conditionalJump.setOperator(conditionAssignment.getOperator());
|
||||
conditionalJump.setRValue2(conditionAssignment.getRValue2());
|
||||
simpleConditionVars.add(conditionVar);
|
||||
System.out.println("Simple Condition " + conditionVar + " " + conditionalJump);
|
||||
log.append("Simple Condition " + conditionVar + " " + conditionalJump);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -17,8 +19,8 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
|
||||
private Map<Variable, Integer> usages;
|
||||
|
||||
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2ConstantAdditionElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +66,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantInteger idxConstant = (ConstantInteger) pointerDereferenceIndexed.getIndex();
|
||||
int newPtr = ptrConstant.getNumber() + idxConstant.getNumber();
|
||||
assignment.setLValue(new PointerDereferenceSimple(new ConstantInteger(newPtr)));
|
||||
System.out.println("Consolidated assigned array index constant in assignment " + assignment.getLValue());
|
||||
log.append("Consolidated assigned array index constant in assignment " + assignment.getLValue());
|
||||
return true;
|
||||
}
|
||||
if(pointerDereferenceIndexed.getPointer() instanceof ConstantInteger && pointerDereferenceIndexed.getIndex() instanceof Variable) {
|
||||
@ -74,7 +76,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantInteger ptrConstant = (ConstantInteger) pointerDereferenceIndexed.getPointer();
|
||||
int newPtr = ptrConstant.getNumber() + consolidated.getNumber();
|
||||
pointerDereferenceIndexed.setPointer(new ConstantInteger(newPtr));
|
||||
System.out.println("Consolidated assigned array index constant in assignment " + assignment.getLValue());
|
||||
log.append("Consolidated assigned array index constant in assignment " + assignment.getLValue());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -89,7 +91,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
assignment.setRValue1(null);
|
||||
assignment.setOperator(new Operator("*"));
|
||||
assignment.setRValue2(new ConstantInteger(newPtr));
|
||||
System.out.println("Consolidated referenced array index constant in assignment " + assignment.getLValue());
|
||||
log.append("Consolidated referenced array index constant in assignment " + assignment.getLValue());
|
||||
return true;
|
||||
}
|
||||
if (assignment.getRValue1() instanceof ConstantInteger && assignment.getRValue2() instanceof Variable) {
|
||||
@ -99,7 +101,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
ConstantInteger ptrConstant = (ConstantInteger) assignment.getRValue1();
|
||||
int newPtr = ptrConstant.getNumber() + consolidated.getNumber();
|
||||
assignment.setRValue1(new ConstantInteger(newPtr));
|
||||
System.out.println("Consolidated referenced array index constant in assignment " + assignment.getLValue());
|
||||
log.append("Consolidated referenced array index constant in assignment " + assignment.getLValue());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -113,7 +115,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
if (consolidated != null) {
|
||||
ConstantInteger const1 = (ConstantInteger) assignment.getRValue1();
|
||||
assignment.setRValue1(new ConstantInteger(const1.getNumber() + consolidated.getNumber()));
|
||||
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
|
||||
log.append("Consolidated constant in assignment " + assignment.getLValue());
|
||||
return true;
|
||||
}
|
||||
} else if (assignment.getRValue1() instanceof Variable && assignment.getRValue2() instanceof ConstantInteger) {
|
||||
@ -128,7 +130,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
} else {
|
||||
assignment.setRValue2(new ConstantInteger(newNumber));
|
||||
}
|
||||
System.out.println("Consolidated constant in assignment " + assignment.getLValue());
|
||||
log.append("Consolidated constant in assignment " + assignment.getLValue());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -143,7 +145,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
*/
|
||||
private ConstantInteger consolidateSubConstants(Variable variable) {
|
||||
if(getUsages(variable) >1) {
|
||||
System.out.println("Multiple usages for variable. Not optimizing sub-constant "+variable);
|
||||
log.append("Multiple usages for variable. Not optimizing sub-constant "+variable);
|
||||
return null;
|
||||
}
|
||||
StatementAssignment assignment = getGraph().getAssignment(variable);
|
||||
|
@ -1,13 +1,16 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Compiler Pass propagating constants in expressions eliminating constant variables */
|
||||
public class Pass2ConstantPropagation extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2ConstantPropagation(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2ConstantPropagation(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -19,7 +22,7 @@ public class Pass2ConstantPropagation extends Pass2SsaOptimization {
|
||||
final Map<Variable, Constant> constants = findConstantVariables();
|
||||
for (Variable constantVar : constants.keySet()) {
|
||||
Constant constantValue = constants.get(constantVar);
|
||||
System.out.println("Constant " + constantVar + " " + constantValue);
|
||||
log.append("Constant " + constantVar + " " + constantValue);
|
||||
}
|
||||
removeAssignments(constants.keySet());
|
||||
deleteSymbols(constants.keySet());
|
||||
@ -32,7 +35,7 @@ public class Pass2ConstantPropagation extends Pass2SsaOptimization {
|
||||
* @return Map from Variable to the Constant value
|
||||
*/
|
||||
private Map<Variable, Constant> findConstantVariables() {
|
||||
final Map<Variable, Constant> constants = new HashMap<>();
|
||||
final Map<Variable, Constant> constants = new LinkedHashMap<>();
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitAssignment(StatementAssignment assignment) {
|
||||
|
@ -1,12 +1,14 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** Pass that culls empty control flow blocks from the program */
|
||||
public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2CullEmptyBlocks(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2CullEmptyBlocks(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -23,7 +25,7 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
|
||||
// Replace all jumps (default/conditional/call) to @removeBlock with a jump to the default successor
|
||||
final List<ControlFlowBlock> predecessors = getGraph().getPredecessors(removeBlock);
|
||||
for (ControlFlowBlock predecessor : predecessors) {
|
||||
Map<Label, Label> replace = new HashMap<>();
|
||||
Map<Label, Label> replace = new LinkedHashMap<>();
|
||||
replace.put(removeBlock.getLabel(), successor.getLabel());
|
||||
if (removeBlock.getLabel().equals(predecessor.getDefaultSuccessor())) {
|
||||
predecessor.setDefaultSuccessor(successor.getLabel());
|
||||
@ -61,7 +63,7 @@ public class Pass2CullEmptyBlocks extends Pass2SsaOptimization {
|
||||
phiFixVisitor.visitBlock(successor);
|
||||
getGraph().getAllBlocks().remove(removeBlock);
|
||||
getSymbols().remove(removeBlock.getLabel());
|
||||
System.out.println("Culled Empty Block " + removeBlock.getLabel());
|
||||
log.append("Culled Empty Block " + removeBlock.getLabel());
|
||||
}
|
||||
return remove.size()>0;
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Compiler Pass eliminating redundant phi functions */
|
||||
public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2RedundantPhiElimination(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2RedundantPhiElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -21,7 +24,7 @@ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
|
||||
replaceVariables(aliases);
|
||||
for (Variable var : aliases.keySet()) {
|
||||
RValue alias = aliases.get(var);
|
||||
System.out.println("Redundant Phi " + var + " " + alias);
|
||||
log.append("Redundant Phi " + var + " " + alias);
|
||||
}
|
||||
return aliases.size()>0;
|
||||
}
|
||||
@ -31,7 +34,7 @@ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
|
||||
* @return Map from (phi) Variable to the previous value
|
||||
*/
|
||||
private Map<Variable, RValue> findRedundantPhis() {
|
||||
final Map<Variable, RValue> aliases = new HashMap<>();
|
||||
final Map<Variable, RValue> aliases = new LinkedHashMap<>();
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitPhi(StatementPhi phi) {
|
||||
|
@ -1,12 +1,14 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/** Compiler Pass eliminating phi self assignments */
|
||||
public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
|
||||
|
||||
public Pass2SelfPhiElimination(ControlFlowGraph graph, Scope scope) {
|
||||
super(graph, scope);
|
||||
public Pass2SelfPhiElimination(ControlFlowGraph graph, Scope scope, CompileLog log) {
|
||||
super(graph, scope, log);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,7 +25,7 @@ public class Pass2SelfPhiElimination extends Pass2SsaOptimization {
|
||||
if (previousSymbol.getRValue().equals(phi.getLValue())) {
|
||||
iterator.remove();
|
||||
optimized[0] = Boolean.TRUE;
|
||||
System.out.println("Self Phi Eliminated "+phi.getLValue());
|
||||
log.append("Self Phi Eliminated "+phi.getLValue());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -8,14 +10,20 @@ import java.util.*;
|
||||
*/
|
||||
public abstract class Pass2SsaOptimization {
|
||||
|
||||
protected CompileLog log;
|
||||
private ControlFlowGraph graph;
|
||||
private Scope scope;
|
||||
|
||||
public Pass2SsaOptimization(ControlFlowGraph graph, Scope scope) {
|
||||
public Pass2SsaOptimization(ControlFlowGraph graph, Scope scope,CompileLog log) {
|
||||
this.log = log;
|
||||
this.graph = graph;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public CompileLog getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
public ControlFlowGraph getGraph() {
|
||||
return graph;
|
||||
}
|
||||
@ -270,7 +278,7 @@ public abstract class Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
public Map<LValue, StatementAssignment> getAllAssignments() {
|
||||
final HashMap<LValue, StatementAssignment> assignments = new HashMap<>();
|
||||
final HashMap<LValue, StatementAssignment> assignments = new LinkedHashMap<>();
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitAssignment(StatementAssignment assignment) {
|
||||
@ -283,7 +291,7 @@ public abstract class Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
public Map<RValue, List<Statement>> getAllUsages() {
|
||||
final HashMap<RValue, List<Statement>> usages = new HashMap<>();
|
||||
final HashMap<RValue, List<Statement>> usages = new LinkedHashMap<>();
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitAssignment(StatementAssignment assignment) {
|
||||
@ -326,7 +334,7 @@ public abstract class Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
protected Map<Variable, Integer> countVarUsages() {
|
||||
final HashMap<Variable, Integer> usages = new HashMap<>();
|
||||
final HashMap<Variable, Integer> usages = new LinkedHashMap<>();
|
||||
ControlFlowGraphBaseVisitor usageVisitor = new ControlFlowGraphBaseVisitor() {
|
||||
private void addUsage(RValue rVal) {
|
||||
if(rVal instanceof Variable) {
|
||||
|
@ -90,7 +90,14 @@ public class Pass3CodeGeneration {
|
||||
|
||||
private void genBlockEntryPoints(AsmProgram asm, ControlFlowBlock block) {
|
||||
if (block.hasPhiStatements()) {
|
||||
for (ControlFlowBlock predecessor : graph.getPredecessors(block)) {
|
||||
List<ControlFlowBlock> predecessors = new ArrayList<>(graph.getPredecessors(block));
|
||||
Collections.sort(predecessors, new Comparator<ControlFlowBlock>() {
|
||||
@Override
|
||||
public int compare(ControlFlowBlock o1, ControlFlowBlock o2) {
|
||||
return o1.getLabel().getFullName().compareTo(o2.getLabel().getFullName());
|
||||
}
|
||||
});
|
||||
for (ControlFlowBlock predecessor : predecessors) {
|
||||
if (block.getLabel().equals(predecessor.getConditionalSuccessor())) {
|
||||
genBlockPhiTransition(asm, predecessor, block);
|
||||
asm.addInstruction("JMP", AsmAddressingMode.ABS, block.getLabel().getFullName().replace('@', 'B').replace(':','_'));
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.asm.AsmLine;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
|
||||
@ -11,10 +12,12 @@ import java.util.List;
|
||||
**/
|
||||
public abstract class Pass4AsmOptimization {
|
||||
|
||||
protected CompileLog log;
|
||||
private AsmProgram program;
|
||||
|
||||
public Pass4AsmOptimization(AsmProgram program) {
|
||||
public Pass4AsmOptimization(AsmProgram program, CompileLog log) {
|
||||
this.program = program;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,11 +31,15 @@ public abstract class Pass4AsmOptimization {
|
||||
return program;
|
||||
}
|
||||
|
||||
public CompileLog getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
public void remove(List<AsmLine> remove) {
|
||||
for (Iterator<AsmLine> iterator = program.getLines().iterator(); iterator.hasNext(); ) {
|
||||
AsmLine line = iterator.next();
|
||||
if (remove.contains(line)) {
|
||||
System.out.println("Removing instruction "+line.getAsm());
|
||||
log.append("Removing instruction "+line.getAsm());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.asm.AsmInstruction;
|
||||
import dk.camelot64.kickc.asm.AsmLabel;
|
||||
import dk.camelot64.kickc.asm.AsmLine;
|
||||
@ -11,8 +12,8 @@ import java.util.List;
|
||||
/** Optimize assembler code by removing jumps to labels immediately following the jump */
|
||||
public class Pass4NextJumpElimination extends Pass4AsmOptimization {
|
||||
|
||||
public Pass4NextJumpElimination(AsmProgram program) {
|
||||
super(program);
|
||||
public Pass4NextJumpElimination(AsmProgram program, CompileLog log) {
|
||||
super(program, log);
|
||||
}
|
||||
|
||||
public boolean optimize() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.icl;
|
||||
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.asm.*;
|
||||
import dk.camelot64.kickc.asm.parser.AsmProgramStaticRegisterValues;
|
||||
|
||||
@ -9,8 +10,8 @@ import java.util.List;
|
||||
/** Maps out register values entering all instructions. Removes unnecessary loads / clears / sets */
|
||||
public class Pass4UnnecesaryLoadElimination extends Pass4AsmOptimization {
|
||||
|
||||
public Pass4UnnecesaryLoadElimination(AsmProgram program) {
|
||||
super(program);
|
||||
public Pass4UnnecesaryLoadElimination(AsmProgram program, CompileLog log) {
|
||||
super(program, log);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,6 +2,7 @@ package dk.camelot64.kickc.icl;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Register Allocation for Variable Symbols */
|
||||
@ -10,7 +11,7 @@ public class RegisterAllocation {
|
||||
private Map<Variable, Register> allocation;
|
||||
|
||||
public RegisterAllocation() {
|
||||
this.allocation = new HashMap<>();
|
||||
this.allocation = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,7 @@
|
||||
package dk.camelot64.kickc.test;
|
||||
|
||||
import com.sun.org.apache.xpath.internal.SourceTree;
|
||||
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
|
||||
import dk.camelot64.kickc.Compiler;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
@ -34,13 +36,15 @@ public class TestCompilationOutput {
|
||||
}
|
||||
|
||||
private void testFile(String fileName) throws IOException, URISyntaxException {
|
||||
String InputPath = testPath + fileName + ".kc";
|
||||
CharStream input = CharStreams.fromFileName(InputPath);
|
||||
String inputPath = testPath + fileName + ".kc";
|
||||
System.out.println("Testing output for "+inputPath);
|
||||
CharStream input = CharStreams.fromFileName(inputPath);
|
||||
Compiler compiler = new Compiler();
|
||||
Compiler.CompilationResult output = compiler.compile(input);
|
||||
assertOutput(fileName, ".asm", output.getAsmProgram().toString());
|
||||
assertOutput(fileName, ".sym", output.getSymbols().getSymbolTableContents());
|
||||
assertOutput(fileName, ".cfg", output.getGraph().toString());
|
||||
assertOutput(fileName, ".asm", output.getAsmProgram().toString());
|
||||
assertOutput(fileName, ".log", output.getLog().toString());
|
||||
}
|
||||
|
||||
private void assertOutput(
|
||||
@ -48,7 +52,14 @@ public class TestCompilationOutput {
|
||||
String extension,
|
||||
String outputString) throws IOException, URISyntaxException {
|
||||
// Read reference file
|
||||
List<String> refLines = loadReferenceLines(fileName, extension);
|
||||
List<String> refLines = null;
|
||||
try {
|
||||
refLines = loadReferenceLines(fileName, extension);
|
||||
} catch (Exception e) {
|
||||
writeOutputFile(fileName, extension, outputString);
|
||||
System.out.println("Error loading reference."+e.getMessage());
|
||||
return;
|
||||
}
|
||||
// Split output into outLines
|
||||
List<String> outLines = getOutLines(outputString);
|
||||
for (int i = 0; i < outLines.size(); i++) {
|
||||
|
@ -41,39 +41,39 @@ plot__B1_from_plot:
|
||||
// (byte) plot::y#2 = (byte) 16 // zpby1=coby1
|
||||
lda #16
|
||||
sta 100
|
||||
// (byte) plot::i#3 = (byte) 0 // xby=coby1
|
||||
ldx #0
|
||||
// (byte*) plot::line#2 = (word) 1236 // zpptrby1=cowo1
|
||||
lda #<1236
|
||||
sta 101
|
||||
lda #>1236
|
||||
sta 101+1
|
||||
// (byte) plot::i#3 = (byte) 0 // xby=coby1
|
||||
ldx #0
|
||||
plot__B1_from_B15:
|
||||
// (byte) plot::y#2 = (byte) plot::y#0 // register copy
|
||||
// (byte*) plot::line#2 = (byte*) plot::line#0 // register copy
|
||||
// (byte) plot::i#3 = (byte) plot::i#0 // register copy
|
||||
// (byte) plot::y#2 = (byte) plot::y#1 // register copy
|
||||
// (byte) plot::i#3 = (byte) plot::i#1 // register copy
|
||||
// (byte*) plot::line#2 = (byte*) plot::line#1 // register copy
|
||||
plot__B1:
|
||||
plot__B2_from_B1:
|
||||
// (byte) plot::x#2 = (byte) 0 // yby=coby1
|
||||
ldy #0
|
||||
// (byte) plot::i#2 = (byte) plot::i#3 // register copy
|
||||
plot__B2_from_B2:
|
||||
// (byte) plot::x#2 = (byte) plot::x#0 // register copy
|
||||
// (byte) plot::i#2 = (byte) plot::i#0 // register copy
|
||||
// (byte) plot::x#2 = (byte) plot::x#1 // register copy
|
||||
// (byte) plot::i#2 = (byte) plot::i#1 // register copy
|
||||
plot__B2:
|
||||
// (byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2 // aby=cowo1_staridx_xby
|
||||
lda 4096,x
|
||||
// *((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3 // ptr_zpptrby1_yby=aby
|
||||
sta (101),y
|
||||
// (byte) plot::i#0 ← ++ (byte) plot::i#2 // xby=_inc_xby
|
||||
// (byte) plot::i#1 ← ++ (byte) plot::i#2 // xby=_inc_xby
|
||||
inx
|
||||
// (byte) plot::x#0 ← ++ (byte) plot::x#2 // yby=_inc_yby
|
||||
// (byte) plot::x#1 ← ++ (byte) plot::x#2 // yby=_inc_yby
|
||||
iny
|
||||
// if((byte) plot::x#0<(byte) 16) goto plot::@2 // yby_lt_coby1_then_la1
|
||||
// if((byte) plot::x#1<(byte) 16) goto plot::@2 // yby_lt_coby1_then_la1
|
||||
cpy #16
|
||||
bcc plot__B2_from_B2
|
||||
B15:
|
||||
// (byte*) plot::line#0 ← (byte*) plot::line#2 + (byte) 40 // zpptrby1=zpptrby1_plus_coby1
|
||||
// (byte*) plot::line#1 ← (byte*) plot::line#2 + (byte) 40 // zpptrby1=zpptrby1_plus_coby1
|
||||
lda 101
|
||||
clc
|
||||
adc #40
|
||||
@ -81,9 +81,9 @@ B15:
|
||||
bcc !+
|
||||
inc 101+1
|
||||
!:
|
||||
// (byte) plot::y#0 ← -- (byte) plot::y#2 // zpby1=_dec_zpby1
|
||||
// (byte) plot::y#1 ← -- (byte) plot::y#2 // zpby1=_dec_zpby1
|
||||
dec 100
|
||||
// if((byte) plot::y#0!=(byte) 0) goto plot::@1 // zpby1_neq_0_then_la1
|
||||
// if((byte) plot::y#1!=(byte) 0) goto plot::@1 // zpby1_neq_0_then_la1
|
||||
lda 100
|
||||
bne plot__B1_from_B15
|
||||
plot__Breturn:
|
||||
@ -93,48 +93,48 @@ flip__B1_from_flip:
|
||||
// (byte) flip::r#2 = (byte) 16 // zpby1=coby1
|
||||
lda #16
|
||||
sta 104
|
||||
// (byte) flip::dstIdx#5 = (byte) 15 // yby=coby1
|
||||
ldy #15
|
||||
// (byte) flip::srcIdx#3 = (byte) 0 // xby=coby1
|
||||
ldx #0
|
||||
// (byte) flip::dstIdx#5 = (byte) 15 // yby=coby1
|
||||
ldy #15
|
||||
flip__B1_from_B11:
|
||||
// (byte) flip::r#2 = (byte) flip::r#0 // register copy
|
||||
// (byte) flip::dstIdx#5 = (byte) flip::dstIdx#1 // register copy
|
||||
// (byte) flip::srcIdx#3 = (byte) flip::srcIdx#0 // register copy
|
||||
// (byte) flip::r#2 = (byte) flip::r#1 // register copy
|
||||
// (byte) flip::srcIdx#3 = (byte) flip::srcIdx#1 // register copy
|
||||
// (byte) flip::dstIdx#5 = (byte) flip::dstIdx#2 // register copy
|
||||
flip__B1:
|
||||
flip__B2_from_B1:
|
||||
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#5 // register copy
|
||||
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#3 // register copy
|
||||
// (byte) flip::c#2 = (byte) 16 // zpby1=coby1
|
||||
lda #16
|
||||
sta 103
|
||||
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#5 // register copy
|
||||
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#3 // register copy
|
||||
flip__B2_from_B2:
|
||||
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#0 // register copy
|
||||
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#0 // register copy
|
||||
// (byte) flip::c#2 = (byte) flip::c#0 // register copy
|
||||
// (byte) flip::c#2 = (byte) flip::c#1 // register copy
|
||||
// (byte) flip::dstIdx#3 = (byte) flip::dstIdx#1 // register copy
|
||||
// (byte) flip::srcIdx#2 = (byte) flip::srcIdx#1 // register copy
|
||||
flip__B2:
|
||||
// (byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2 // aby=cowo1_staridx_xby
|
||||
lda 4096,x
|
||||
// *((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0 // ptr_cowo1_yby=aby
|
||||
sta 4352,y
|
||||
// (byte) flip::srcIdx#0 ← ++ (byte) flip::srcIdx#2 // xby=_inc_xby
|
||||
// (byte) flip::srcIdx#1 ← ++ (byte) flip::srcIdx#2 // xby=_inc_xby
|
||||
inx
|
||||
// (byte) flip::dstIdx#0 ← (byte) flip::dstIdx#3 + (byte) 16 // yby=yby_plus_coby1
|
||||
// (byte) flip::dstIdx#1 ← (byte) flip::dstIdx#3 + (byte) 16 // yby=yby_plus_coby1
|
||||
tya
|
||||
clc
|
||||
adc #16
|
||||
tay
|
||||
// (byte) flip::c#0 ← -- (byte) flip::c#2 // zpby1=_dec_zpby1
|
||||
// (byte) flip::c#1 ← -- (byte) flip::c#2 // zpby1=_dec_zpby1
|
||||
dec 103
|
||||
// if((byte) flip::c#0!=(byte) 0) goto flip::@2 // zpby1_neq_0_then_la1
|
||||
// if((byte) flip::c#1!=(byte) 0) goto flip::@2 // zpby1_neq_0_then_la1
|
||||
lda 103
|
||||
bne flip__B2_from_B2
|
||||
B11:
|
||||
// (byte) flip::dstIdx#1 ← -- (byte) flip::dstIdx#0 // yby=_dec_yby
|
||||
// (byte) flip::dstIdx#2 ← -- (byte) flip::dstIdx#1 // yby=_dec_yby
|
||||
dey
|
||||
// (byte) flip::r#0 ← -- (byte) flip::r#2 // zpby1=_dec_zpby1
|
||||
// (byte) flip::r#1 ← -- (byte) flip::r#2 // zpby1=_dec_zpby1
|
||||
dec 104
|
||||
// if((byte) flip::r#0!=(byte) 0) goto flip::@1 // zpby1_neq_0_then_la1
|
||||
// if((byte) flip::r#1!=(byte) 0) goto flip::@1 // zpby1_neq_0_then_la1
|
||||
lda 104
|
||||
bne flip__B1_from_B11
|
||||
flip__B3_from_B11:
|
||||
@ -159,14 +159,14 @@ prepare__B1_from_prepare:
|
||||
// (byte) prepare::i#2 = (byte) 0 // xby=coby1
|
||||
ldx #0
|
||||
prepare__B1_from_B1:
|
||||
// (byte) prepare::i#2 = (byte) prepare::i#0 // register copy
|
||||
// (byte) prepare::i#2 = (byte) prepare::i#1 // register copy
|
||||
prepare__B1:
|
||||
// *((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2 // ptr_cowo1_xby=xby
|
||||
txa
|
||||
sta 4096,x
|
||||
// (byte) prepare::i#0 ← ++ (byte) prepare::i#2 // xby=_inc_xby
|
||||
// (byte) prepare::i#1 ← ++ (byte) prepare::i#2 // xby=_inc_xby
|
||||
inx
|
||||
// if((byte) prepare::i#0!=(byte) 0) goto prepare::@1 // xby_neq_0_then_la1
|
||||
// if((byte) prepare::i#1!=(byte) 0) goto prepare::@1 // xby_neq_0_then_la1
|
||||
cpx #0
|
||||
bne prepare__B1_from_B1
|
||||
prepare__Breturn:
|
||||
|
@ -1,79 +1,64 @@
|
||||
@2: from @20 @6 @BEGIN
|
||||
(byte) c#2 ← phi( @20/(byte) 25 @6/(byte) c#1 @BEGIN/(byte) 25 )
|
||||
to:@3
|
||||
@BEGIN: from
|
||||
call prepare param-assignment
|
||||
to:@2
|
||||
@20: from @19
|
||||
if(true) goto @2
|
||||
to:@END
|
||||
prepare::@1: from prepare prepare::@1
|
||||
(byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@1/(byte) prepare::i#0 )
|
||||
*((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2
|
||||
(byte) prepare::i#0 ← ++ (byte) prepare::i#2
|
||||
if((byte) prepare::i#0!=(byte) 0) goto prepare::@1
|
||||
to:prepare::@return
|
||||
flip::@2: from flip::@1 flip::@2
|
||||
(byte) flip::dstIdx#3 ← phi( flip::@1/(byte) flip::dstIdx#5 flip::@2/(byte) flip::dstIdx#0 )
|
||||
(byte) flip::srcIdx#2 ← phi( flip::@1/(byte) flip::srcIdx#3 flip::@2/(byte) flip::srcIdx#0 )
|
||||
(byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@2/(byte) flip::c#0 )
|
||||
(byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2
|
||||
*((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0
|
||||
(byte) flip::srcIdx#0 ← ++ (byte) flip::srcIdx#2
|
||||
(byte) flip::dstIdx#0 ← (byte) flip::dstIdx#3 + (byte) 16
|
||||
(byte) flip::c#0 ← -- (byte) flip::c#2
|
||||
if((byte) flip::c#0!=(byte) 0) goto flip::@2
|
||||
to:@11
|
||||
@2: from @20 @6 @BEGIN
|
||||
(byte) c#2 ← phi( @20/(byte) 25 @6/(byte) c#1 @BEGIN/(byte) 25 )
|
||||
to:@3
|
||||
@3: from @2 @3
|
||||
(byte~) $1 ← * (word) 53266
|
||||
if((byte~) $1!=(byte) 254) goto @3
|
||||
to:@4
|
||||
@4: from @3 @4
|
||||
(byte~) $3 ← * (word) 53266
|
||||
if((byte~) $3!=(byte) 255) goto @4
|
||||
to:@6
|
||||
@11: from flip::@2
|
||||
(byte) flip::dstIdx#1 ← -- (byte) flip::dstIdx#0
|
||||
(byte) flip::r#0 ← -- (byte) flip::r#2
|
||||
if((byte) flip::r#0!=(byte) 0) goto flip::@1
|
||||
to:flip::@3
|
||||
plot::@return: from @15
|
||||
return
|
||||
to:@RETURN
|
||||
plot::@2: from plot::@1 plot::@2
|
||||
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@2/(byte) plot::x#0 )
|
||||
(byte) plot::i#2 ← phi( plot::@1/(byte) plot::i#3 plot::@2/(byte) plot::i#0 )
|
||||
(byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2
|
||||
*((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3
|
||||
(byte) plot::i#0 ← ++ (byte) plot::i#2
|
||||
(byte) plot::x#0 ← ++ (byte) plot::x#2
|
||||
if((byte) plot::x#0<(byte) 16) goto plot::@2
|
||||
to:@15
|
||||
@6: from @4
|
||||
(byte) c#1 ← -- (byte) c#2
|
||||
if((byte) c#1!=(byte) 0) goto @2
|
||||
to:@7
|
||||
plot::@1: from @15 plot
|
||||
(byte) plot::y#2 ← phi( @15/(byte) plot::y#0 plot/(byte) 16 )
|
||||
(byte*) plot::line#2 ← phi( @15/(byte*) plot::line#0 plot/(word) 1236 )
|
||||
(byte) plot::i#3 ← phi( @15/(byte) plot::i#0 plot/(byte) 0 )
|
||||
to:plot::@2
|
||||
@7: from @6
|
||||
call flip param-assignment
|
||||
to:@19
|
||||
@19: from @7
|
||||
call plot param-assignment
|
||||
to:@20
|
||||
@20: from @19
|
||||
if(true) goto @2
|
||||
to:@END
|
||||
prepare: from @BEGIN
|
||||
to:prepare::@1
|
||||
prepare::@1: from prepare prepare::@1
|
||||
(byte) prepare::i#2 ← phi( prepare/(byte) 0 prepare::@1/(byte) prepare::i#1 )
|
||||
*((word) 4096 + (byte) prepare::i#2) ← (byte) prepare::i#2
|
||||
(byte) prepare::i#1 ← ++ (byte) prepare::i#2
|
||||
if((byte) prepare::i#1!=(byte) 0) goto prepare::@1
|
||||
to:prepare::@return
|
||||
prepare::@return: from prepare::@1
|
||||
return
|
||||
to:@RETURN
|
||||
flip: from @7
|
||||
to:flip::@1
|
||||
prepare: from @BEGIN
|
||||
to:prepare::@1
|
||||
@7: from @6
|
||||
call flip param-assignment
|
||||
to:@19
|
||||
flip::@1: from @11 flip
|
||||
(byte) flip::r#2 ← phi( @11/(byte) flip::r#0 flip/(byte) 16 )
|
||||
(byte) flip::dstIdx#5 ← phi( @11/(byte) flip::dstIdx#1 flip/(byte) 15 )
|
||||
(byte) flip::srcIdx#3 ← phi( @11/(byte) flip::srcIdx#0 flip/(byte) 0 )
|
||||
(byte) flip::r#2 ← phi( @11/(byte) flip::r#1 flip/(byte) 16 )
|
||||
(byte) flip::srcIdx#3 ← phi( @11/(byte) flip::srcIdx#1 flip/(byte) 0 )
|
||||
(byte) flip::dstIdx#5 ← phi( @11/(byte) flip::dstIdx#2 flip/(byte) 15 )
|
||||
to:flip::@2
|
||||
@15: from plot::@2
|
||||
(byte*) plot::line#0 ← (byte*) plot::line#2 + (byte) 40
|
||||
(byte) plot::y#0 ← -- (byte) plot::y#2
|
||||
if((byte) plot::y#0!=(byte) 0) goto plot::@1
|
||||
to:plot::@return
|
||||
flip::@2: from flip::@1 flip::@2
|
||||
(byte) flip::c#2 ← phi( flip::@1/(byte) 16 flip::@2/(byte) flip::c#1 )
|
||||
(byte) flip::dstIdx#3 ← phi( flip::@1/(byte) flip::dstIdx#5 flip::@2/(byte) flip::dstIdx#1 )
|
||||
(byte) flip::srcIdx#2 ← phi( flip::@1/(byte) flip::srcIdx#3 flip::@2/(byte) flip::srcIdx#1 )
|
||||
(byte~) flip::$0 ← (word) 4096 *idx (byte) flip::srcIdx#2
|
||||
*((word) 4352 + (byte) flip::dstIdx#3) ← (byte~) flip::$0
|
||||
(byte) flip::srcIdx#1 ← ++ (byte) flip::srcIdx#2
|
||||
(byte) flip::dstIdx#1 ← (byte) flip::dstIdx#3 + (byte) 16
|
||||
(byte) flip::c#1 ← -- (byte) flip::c#2
|
||||
if((byte) flip::c#1!=(byte) 0) goto flip::@2
|
||||
to:@11
|
||||
@11: from flip::@2
|
||||
(byte) flip::dstIdx#2 ← -- (byte) flip::dstIdx#1
|
||||
(byte) flip::r#1 ← -- (byte) flip::r#2
|
||||
if((byte) flip::r#1!=(byte) 0) goto flip::@1
|
||||
to:flip::@3
|
||||
flip::@3: from @11 flip::@3
|
||||
(byte) flip::i#2 ← phi( @11/(byte) 0 flip::@3/(byte) flip::i#1 )
|
||||
(byte~) flip::$4 ← (word) 4352 *idx (byte) flip::i#2
|
||||
@ -81,16 +66,31 @@ flip::@3: from @11 flip::@3
|
||||
(byte) flip::i#1 ← ++ (byte) flip::i#2
|
||||
if((byte) flip::i#1!=(byte) 0) goto flip::@3
|
||||
to:flip::@return
|
||||
@END: from @20
|
||||
@19: from @7
|
||||
call plot param-assignment
|
||||
to:@20
|
||||
plot: from @19
|
||||
to:plot::@1
|
||||
@3: from @2 @3
|
||||
(byte~) $1 ← * (word) 53266
|
||||
if((byte~) $1!=(byte) 254) goto @3
|
||||
to:@4
|
||||
flip::@return: from flip::@3
|
||||
return
|
||||
to:@RETURN
|
||||
plot: from @19
|
||||
to:plot::@1
|
||||
plot::@1: from @15 plot
|
||||
(byte) plot::y#2 ← phi( @15/(byte) plot::y#1 plot/(byte) 16 )
|
||||
(byte) plot::i#3 ← phi( @15/(byte) plot::i#1 plot/(byte) 0 )
|
||||
(byte*) plot::line#2 ← phi( @15/(byte*) plot::line#1 plot/(word) 1236 )
|
||||
to:plot::@2
|
||||
plot::@2: from plot::@1 plot::@2
|
||||
(byte) plot::x#2 ← phi( plot::@1/(byte) 0 plot::@2/(byte) plot::x#1 )
|
||||
(byte) plot::i#2 ← phi( plot::@1/(byte) plot::i#3 plot::@2/(byte) plot::i#1 )
|
||||
(byte~) plot::$3 ← (word) 4096 *idx (byte) plot::i#2
|
||||
*((byte*) plot::line#2 + (byte) plot::x#2) ← (byte~) plot::$3
|
||||
(byte) plot::i#1 ← ++ (byte) plot::i#2
|
||||
(byte) plot::x#1 ← ++ (byte) plot::x#2
|
||||
if((byte) plot::x#1<(byte) 16) goto plot::@2
|
||||
to:@15
|
||||
@15: from plot::@2
|
||||
(byte*) plot::line#1 ← (byte*) plot::line#2 + (byte) 40
|
||||
(byte) plot::y#1 ← -- (byte) plot::y#2
|
||||
if((byte) plot::y#1!=(byte) 0) goto plot::@1
|
||||
to:plot::@return
|
||||
plot::@return: from @15
|
||||
return
|
||||
to:@RETURN
|
||||
@END: from @20
|
||||
|
3829
src/dk/camelot64/kickc/test/ref/flipper-rex2.log
Normal file
3829
src/dk/camelot64/kickc/test/ref/flipper-rex2.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,21 +26,21 @@
|
||||
(label) flip::@3
|
||||
(label) flip::@return
|
||||
(byte) flip::c
|
||||
(byte) flip::c#0 zp byte:103
|
||||
(byte) flip::c#1 zp byte:103
|
||||
(byte) flip::c#2 zp byte:103
|
||||
(byte) flip::dstIdx
|
||||
(byte) flip::dstIdx#0 reg byte y
|
||||
(byte) flip::dstIdx#1 reg byte y
|
||||
(byte) flip::dstIdx#2 reg byte y
|
||||
(byte) flip::dstIdx#3 reg byte y
|
||||
(byte) flip::dstIdx#5 reg byte y
|
||||
(byte) flip::i
|
||||
(byte) flip::i#1 reg byte x
|
||||
(byte) flip::i#2 reg byte x
|
||||
(byte) flip::r
|
||||
(byte) flip::r#0 zp byte:104
|
||||
(byte) flip::r#1 zp byte:104
|
||||
(byte) flip::r#2 zp byte:104
|
||||
(byte) flip::srcIdx
|
||||
(byte) flip::srcIdx#0 reg byte x
|
||||
(byte) flip::srcIdx#1 reg byte x
|
||||
(byte) flip::srcIdx#2 reg byte x
|
||||
(byte) flip::srcIdx#3 reg byte x
|
||||
|
||||
@ -50,23 +50,23 @@
|
||||
(label) plot::@2
|
||||
(label) plot::@return
|
||||
(byte) plot::i
|
||||
(byte) plot::i#0 reg byte x
|
||||
(byte) plot::i#1 reg byte x
|
||||
(byte) plot::i#2 reg byte x
|
||||
(byte) plot::i#3 reg byte x
|
||||
(byte*) plot::line
|
||||
(byte*) plot::line#0 zp ptr byte:101
|
||||
(byte*) plot::line#1 zp ptr byte:101
|
||||
(byte*) plot::line#2 zp ptr byte:101
|
||||
(byte) plot::x
|
||||
(byte) plot::x#0 reg byte y
|
||||
(byte) plot::x#1 reg byte y
|
||||
(byte) plot::x#2 reg byte y
|
||||
(byte) plot::y
|
||||
(byte) plot::y#0 zp byte:100
|
||||
(byte) plot::y#1 zp byte:100
|
||||
(byte) plot::y#2 zp byte:100
|
||||
|
||||
(void()) prepare()
|
||||
(label) prepare::@1
|
||||
(label) prepare::@return
|
||||
(byte) prepare::i
|
||||
(byte) prepare::i#0 reg byte x
|
||||
(byte) prepare::i#1 reg byte x
|
||||
(byte) prepare::i#2 reg byte x
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user