From 4e4fee9035d5ee8b12d0381db8501c0c0d85d255 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 15 May 2017 17:01:11 +0200 Subject: [PATCH] Implmented asm fragment generator --- .../kickc/icl/AsmFragmentSignature.java | 83 ++++++++ .../icl/AsmFragmentSignatureAssignment.java | 31 +++ src/dk/camelot64/kickc/icl/AsmSequence.java | 48 +++++ .../camelot64/kickc/icl/ConstantInteger.java | 1 + .../kickc/icl/Pass2AliasElimination.java | 1 + .../kickc/icl/Pass2ConstantPropagation.java | 1 + .../kickc/icl/Pass2Optimization.java | 23 ++- .../icl/Pass2RedundantPhiElimination.java | 1 + .../kickc/icl/Pass3RegisterAllocation.java | 6 +- .../kickc/icl/Pass4CodeGeneration.java | 187 ++++++++++++++++++ .../kickc/icl/RegisterAllocation.java | 36 +++- .../camelot64/kickc/icl/asm/zpby1=coby1.asm | 2 + .../kickc/icl/asm/zpby1=zpby2+coby1.asm | 4 + .../kickc/icl/asm/zpby1=zpby2+zpby3.asm | 4 + .../kickc/icl/asm/zpby1=zpby2-coby1.asm | 4 + .../camelot64/kickc/icl/asm/zpby1=zpby2.asm | 2 + src/dk/camelot64/kickc/test/Main.java | 13 +- src/dk/camelot64/kickc/test/test.kc | 2 +- 18 files changed, 428 insertions(+), 21 deletions(-) create mode 100644 src/dk/camelot64/kickc/icl/AsmFragmentSignature.java create mode 100644 src/dk/camelot64/kickc/icl/AsmFragmentSignatureAssignment.java create mode 100644 src/dk/camelot64/kickc/icl/AsmSequence.java create mode 100644 src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java create mode 100644 src/dk/camelot64/kickc/icl/asm/zpby1=coby1.asm create mode 100644 src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+coby1.asm create mode 100644 src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+zpby3.asm create mode 100644 src/dk/camelot64/kickc/icl/asm/zpby1=zpby2-coby1.asm create mode 100644 src/dk/camelot64/kickc/icl/asm/zpby1=zpby2.asm diff --git a/src/dk/camelot64/kickc/icl/AsmFragmentSignature.java b/src/dk/camelot64/kickc/icl/AsmFragmentSignature.java new file mode 100644 index 000000000..1ed10e690 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/AsmFragmentSignature.java @@ -0,0 +1,83 @@ +package dk.camelot64.kickc.icl; + +import java.util.HashMap; +import java.util.Map; + +/** Signature and Binding for a Code Generation Fragment */ +public abstract class AsmFragmentSignature { + + /** The symbol table. */ + private SymbolTable symbols; + + /** Binding of named values in the fragment to values (constants, variables, ...) .*/ + private Map bindings; + + /** The string signature/name of the asm fragment. */ + private String signature; + + public AsmFragmentSignature(SymbolTable symbols) { + this.symbols = symbols; + this.bindings = new HashMap<>(); + } + + public RValue getBinding(String name) { + return bindings.get(name); + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + /** Zero page byte register name indexing. */ + private int nextZpByteIdx = 1; + + /** Zero page bool register name indexing. */ + private int nextZpBoolIdx = 1; + + /** Constant byte indexing. */ + private int nextConstByteIdx = 1; + + /** + * Add bindings of a value. + * @param value The value to bind. + * @return The bound name of the value. If the value has already been bound the existing bound name is returned. + */ + public String bind(RValue value) { + // Find value if it is already bound + for (String name : bindings.keySet()) { + if (value.equals(bindings.get(name))) { + return name; + } + } + if (value instanceof Variable) { + RegisterAllocation.Register register = symbols.getRegister((Variable) value); + if (RegisterAllocation.RegisterType.ZP_BYTE.equals(register.getType())) { + String name = "zpby" + nextZpByteIdx++; + bindings.put(name, value); + return name; + } else if (RegisterAllocation.RegisterType.ZP_BOOL.equals(register.getType())) { + String name = "zpbo" + nextZpBoolIdx++; + bindings.put(name, value); + return name; + } else { + throw new RuntimeException("Binding of register type not supported " + register.getType()); + } + } else if (value instanceof ConstantInteger) { + ConstantInteger intValue = (ConstantInteger) value; + if(intValue.getType().equals(SymbolType.BYTE)) { + String name = "coby"+ nextConstByteIdx++; + bindings.put(name, value); + return name; + } else { + throw new RuntimeException("Binding of word integers not supported " + intValue); + } + } else { + throw new RuntimeException("Binding of value type not supported " + value); + } + } + +} diff --git a/src/dk/camelot64/kickc/icl/AsmFragmentSignatureAssignment.java b/src/dk/camelot64/kickc/icl/AsmFragmentSignatureAssignment.java new file mode 100644 index 000000000..a748c6bb6 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/AsmFragmentSignatureAssignment.java @@ -0,0 +1,31 @@ +package dk.camelot64.kickc.icl; + +/** Assembler Fragemnt Signature for an assignment */ +public class AsmFragmentSignatureAssignment extends AsmFragmentSignature { + + public AsmFragmentSignatureAssignment(StatementAssignment assignment, SymbolTable symbols) { + super(symbols); + setSignature(assignment.getLValue(), assignment.getRValue1(), assignment.getOperator(), assignment.getRValue2()); + } + + public AsmFragmentSignatureAssignment(LValue lValue, RValue rValue, SymbolTable symbols) { + super(symbols); + setSignature(lValue, null, null, rValue); + } + + private void setSignature(LValue lValue, RValue rValue1, Operator operator, RValue rValue2) { + StringBuilder signature = new StringBuilder(); + signature.append(bind(lValue)); + signature.append("="); + if (rValue1 != null) { + signature.append(bind(rValue1)); + } + if (operator != null) { + signature.append(operator.getOperator()); + } + signature.append(bind(rValue2)); + setSignature(signature.toString()); + } + + +} diff --git a/src/dk/camelot64/kickc/icl/AsmSequence.java b/src/dk/camelot64/kickc/icl/AsmSequence.java new file mode 100644 index 000000000..9ba99df04 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/AsmSequence.java @@ -0,0 +1,48 @@ +package dk.camelot64.kickc.icl; + +import java.util.ArrayList; +import java.util.List; + +/** A sequence of assembler code. */ +public class AsmSequence { + + private List sequence; + + public AsmSequence() { + this.sequence = new ArrayList<>(); + } + + public List getSequence() { + return sequence; + } + + public void addAsm(String asm) { + sequence.add(new AsmStatement(asm)); + } + + public class AsmStatement { + private String asm; + + public AsmStatement(String asm) { + this.asm = asm; + } + + public String getAsm() { + return asm; + } + + @Override + public String toString() { + return asm ; + } + } + + @Override + public String toString() { + StringBuffer out = new StringBuffer(); + for (AsmStatement asmStatement : sequence) { + out.append(asmStatement+"\n"); + } + return out.toString(); + } +} diff --git a/src/dk/camelot64/kickc/icl/ConstantInteger.java b/src/dk/camelot64/kickc/icl/ConstantInteger.java index 38aff41a4..faf3cf0cb 100644 --- a/src/dk/camelot64/kickc/icl/ConstantInteger.java +++ b/src/dk/camelot64/kickc/icl/ConstantInteger.java @@ -23,4 +23,5 @@ public class ConstantInteger implements Constant { public String toString() { return "("+getType().getTypeName()+") "+Integer.toString(number); } + } diff --git a/src/dk/camelot64/kickc/icl/Pass2AliasElimination.java b/src/dk/camelot64/kickc/icl/Pass2AliasElimination.java index 24f802797..56da42a31 100644 --- a/src/dk/camelot64/kickc/icl/Pass2AliasElimination.java +++ b/src/dk/camelot64/kickc/icl/Pass2AliasElimination.java @@ -18,6 +18,7 @@ public class Pass2AliasElimination extends Pass2Optimization { final Map aliases = findAliases(); removeAssignments(aliases.values()); replaceVariables(aliases); + deleteSymbols(aliases.keySet()); for (Variable var : aliases.keySet()) { Variable alias = aliases.get(var); System.out.println("Alias " + var + " " + alias); diff --git a/src/dk/camelot64/kickc/icl/Pass2ConstantPropagation.java b/src/dk/camelot64/kickc/icl/Pass2ConstantPropagation.java index 6cba75b7d..0df412f9d 100644 --- a/src/dk/camelot64/kickc/icl/Pass2ConstantPropagation.java +++ b/src/dk/camelot64/kickc/icl/Pass2ConstantPropagation.java @@ -23,6 +23,7 @@ public class Pass2ConstantPropagation extends Pass2Optimization { System.out.println("Constant " + constantVar + " " + constantValue); } removeAssignments(constants.keySet()); + deleteSymbols(constants.keySet()); replaceVariables(constants); return constants.size() > 0; } diff --git a/src/dk/camelot64/kickc/icl/Pass2Optimization.java b/src/dk/camelot64/kickc/icl/Pass2Optimization.java index f7e302705..bd4a623b9 100644 --- a/src/dk/camelot64/kickc/icl/Pass2Optimization.java +++ b/src/dk/camelot64/kickc/icl/Pass2Optimization.java @@ -46,9 +46,9 @@ public abstract class Pass2Optimization { * @param aliases Variables that have alias values. */ public void replaceVariables(final Map aliases) { - ControlFlowGraphBaseVisitor visitor = new ControlFlowGraphBaseVisitor() { + ControlFlowGraphBaseVisitor visitor = new ControlFlowGraphBaseVisitor() { @Override - public Object visitAssignment(StatementAssignment assignment) { + public Void visitAssignment(StatementAssignment assignment) { if(getAlias(aliases, assignment.getLValue()) !=null) { RValue alias = getAlias(aliases, assignment.getLValue()); if(alias instanceof LValue) { @@ -65,7 +65,7 @@ public abstract class Pass2Optimization { } @Override - public Object visitConditionalJump(StatementConditionalJump conditionalJump) { + public Void visitConditionalJump(StatementConditionalJump conditionalJump) { if(getAlias(aliases, conditionalJump.getCondition())!=null) { conditionalJump.setCondition(getAlias(aliases, conditionalJump.getCondition())); } @@ -73,7 +73,7 @@ public abstract class Pass2Optimization { } @Override - public Object visitPhi(StatementPhi phi) { + public Void visitPhi(StatementPhi phi) { if(getAlias(aliases, phi.getLValue())!=null) { RValue alias = getAlias(aliases, phi.getLValue()); if(alias instanceof LValue) { @@ -164,7 +164,7 @@ public abstract class Pass2Optimization { /** - * Remove all assignments to specific LValues from the control frlo graph (as they are no longer needed). + * Remove all assignments to specific LValues from the control flow graph (as they are no longer needed). * @param variables The variables to eliminate */ public void removeAssignments(Collection variables) { @@ -175,17 +175,26 @@ public abstract class Pass2Optimization { StatementAssignment assignment = (StatementAssignment) statement; if (variables.contains(assignment.getLValue())) { iterator.remove(); - symbolTable.remove((Symbol) assignment.getLValue()); } } else if(statement instanceof StatementPhi) { StatementPhi phi = (StatementPhi) statement; if (variables.contains(phi.getLValue())) { iterator.remove(); - symbolTable.remove(phi.getLValue()); } } } } } + /** + * Remove variables from the symbol table + * @param variables The variables to remove + */ + public void deleteSymbols(Collection variables) { + for (LValue variable : variables) { + symbolTable.remove((Symbol) variable); + } + } + + } diff --git a/src/dk/camelot64/kickc/icl/Pass2RedundantPhiElimination.java b/src/dk/camelot64/kickc/icl/Pass2RedundantPhiElimination.java index 65c5adc0a..847ea83dc 100644 --- a/src/dk/camelot64/kickc/icl/Pass2RedundantPhiElimination.java +++ b/src/dk/camelot64/kickc/icl/Pass2RedundantPhiElimination.java @@ -17,6 +17,7 @@ public class Pass2RedundantPhiElimination extends Pass2Optimization{ public boolean optimize() { final Map aliases = findRedundantPhis(); removeAssignments(aliases.keySet()); + deleteSymbols(aliases.keySet()); replaceVariables(aliases); for (Variable var : aliases.keySet()) { RValue alias = aliases.get(var); diff --git a/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java b/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java index d025adc7f..7bb5de57a 100644 --- a/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java +++ b/src/dk/camelot64/kickc/icl/Pass3RegisterAllocation.java @@ -16,7 +16,11 @@ public class Pass3RegisterAllocation { int currentZp = 2; for (Variable var : symbols.getAllVariables()) { if(var instanceof VariableIntermediate || var instanceof VariableVersion) - allocation.allocate(var, new RegisterAllocation.RegisterZp(currentZp++)); + if(var.getType().equals(SymbolType.BYTE)) { + allocation.allocate(var, new RegisterAllocation.RegisterZpByte(currentZp++)); + } else if(var.getType().equals(SymbolType.BOOLEAN)) { + allocation.allocate(var, new RegisterAllocation.RegisterZpBool(currentZp++)); + } } symbols.setAllocation(allocation); } diff --git a/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java b/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java new file mode 100644 index 000000000..c974ee79f --- /dev/null +++ b/src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java @@ -0,0 +1,187 @@ +package dk.camelot64.kickc.icl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Code Generation of 6502 Assembler from ICL/SSA Control Flow Graph + */ +public class Pass4CodeGeneration { + + private ControlFlowGraph graph; + private SymbolTable symbols; + + public Pass4CodeGeneration(ControlFlowGraph graph, SymbolTable symbols) { + this.graph = graph; + this.symbols = symbols; + } + + public AsmSequence generate() { + AsmSequence asm = new AsmSequence(); + for (ControlFlowBlock block : graph.getAllBlocks()) { + // Generate entry points (if needed) + genBlockEntryPoints(asm, block); + // Generate label + genAsmLabel(asm, block.getLabel()); + // Generate statements + genStatements(asm, block); + // Generate exit + ControlFlowBlock defaultSuccessor = block.getDefaultSuccessor(); + if (defaultSuccessor != null) { + if(defaultSuccessor.getPredecessors().size()>1) { + String label = defaultSuccessor.getLabel().getName() + "_from_" + block.getLabel().getName(); + genAsmJump(asm, label); + } else { + genAsmJump(asm, defaultSuccessor.getLabel().getName()); + } + } + } + return asm; + } + + private void genStatements(AsmSequence asm, ControlFlowBlock block) { + for (Statement statement : block.getStatements()) { + if (!(statement instanceof StatementPhi)) { + genStatement(asm, statement); + } + } + } + + private void genStatement(AsmSequence asm, Statement statement) { + if (statement instanceof StatementAssignment) { + AsmFragmentSignature asmFragmentSignature = new AsmFragmentSignatureAssignment((StatementAssignment) statement, symbols); + asm.addAsm(" // " + statement + " // "+asmFragmentSignature.getSignature()); + genAsmFragment(asm, asmFragmentSignature); + } else { + asm.addAsm(" // TODO: " + statement); + } + } + + private void genBlockEntryPoints(AsmSequence asm, ControlFlowBlock block) { + List statements = block.getStatements(); + if (statements.size() > 0 && (statements.get(0) instanceof StatementPhi)) { + for (ControlFlowBlock predecessor : block.getPredecessors()) { + genBlockEntryPoint(asm, block, predecessor); + } + } + } + + private void genBlockEntryPoint(AsmSequence asm, ControlFlowBlock block, ControlFlowBlock predecessor) { + genAsmLabel(asm, block.getLabel().getName() + "_from_" + predecessor.getLabel().getName()); + for (Statement statement : block.getStatements()) { + if (!(statement instanceof StatementPhi)) { + // No more phi statements to handle + break; + } + StatementPhi phi = (StatementPhi) statement; + for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) { + if (previousSymbol.getBlock().equals(predecessor)) { + genAsmMove(asm, previousSymbol.getRValue(), phi.getLValue()); + break; + } + } + } + genAsmJump(asm, block.getLabel().getName()); + } + + /** + * Generate an assembler move from an Rvalue to an LValue + * + * @param asm The assembler sequence + * @param rValue The rValue + * @param lValue The lValue + */ + private void genAsmMove(AsmSequence asm, RValue rValue, LValue lValue) { + AsmFragmentSignatureAssignment signature = new AsmFragmentSignatureAssignment(lValue, rValue, symbols); + asm.addAsm(" // " + rValue + " = " + lValue + " // "+signature.getSignature()); + genAsmFragment(asm, signature); + } + + private void genAsmLabel(AsmSequence asm, Label label) { + genAsmLabel(asm, label.getName()); + } + + private void genAsmLabel(AsmSequence asm, String label) { + asm.addAsm(label.replace('@', 'B') + ":"); + } + + private void genAsmJump(AsmSequence asm, String label) { + asm.addAsm(" jmp " + label.replace('B', '_')); + } + + /** + * Generate assembler code for an assembler fragment. + * + * @param asm The assembler sequence to generate into. + * @param fragmentSignature Signature of the code fragment to generate + */ + private void genAsmFragment(AsmSequence asm, AsmFragmentSignature fragmentSignature) { + String signature = fragmentSignature.getSignature(); + ClassLoader classLoader = this.getClass().getClassLoader(); + URL fragmentResource = classLoader.getResource("dk/camelot64/kickc/icl/asm/" + signature + ".asm"); + if (fragmentResource == null) { + System.out.println("Fragment not found " + fragmentResource); + asm.addAsm(" // Fragment not found: " + signature); + return; + } + Pattern bindPattern = Pattern.compile(".*\\{([^}]*)}.*"); + try { + InputStream fragmentStream = fragmentResource.openStream(); + BufferedReader fragmentReader = new BufferedReader(new InputStreamReader(fragmentStream)); + String line; + while ((line = fragmentReader.readLine()) != null) { + Matcher matcher = bindPattern.matcher(line); + if(matcher.matches()) { + String name = matcher.group(1); + String bound = getFragmentBoundValue(name, fragmentSignature); + line = line.replaceFirst("\\{[^}]*}", bound); + } + asm.addAsm(" " + line); + } + fragmentReader.close(); + fragmentStream.close(); + } catch (IOException e) { + throw new RuntimeException("Error reading code fragment " + fragmentResource); + } + + } + + /** + * Get the value to replace a bound name with from the fragment signature + * @param boundName The name of the bound value in the fragment + * @param fragmentSignature The fragment signature containing the bindings + * @return The bound value to use in the generated ASM code + */ + private String getFragmentBoundValue(String boundName, AsmFragmentSignature fragmentSignature) { + RValue boundValue = fragmentSignature.getBinding(boundName); + String bound; + if(boundValue instanceof Variable) { + RegisterAllocation.Register register = symbols.getRegister((Variable) boundValue); + if(register instanceof RegisterAllocation.RegisterZpByte) { + bound = Integer.toString(((RegisterAllocation.RegisterZpByte) register).getZp()); + } else if(register instanceof RegisterAllocation.RegisterZpBool) { + bound = Integer.toString(((RegisterAllocation.RegisterZpBool) register).getZp()); + } else { + throw new RuntimeException("Register Type not implemented "+register); + } + } else if(boundValue instanceof ConstantInteger) { + ConstantInteger boundInt = (ConstantInteger) boundValue; + if(boundInt.getType().equals(SymbolType.BYTE)) { + bound = Integer.toString(boundInt.getNumber()); + } else { + throw new RuntimeException("Bound Value Type not implemented " + boundValue); + } + } else { + throw new RuntimeException("Bound Value Type not implemented " + boundValue); + } + return bound; + } + + +} diff --git a/src/dk/camelot64/kickc/icl/RegisterAllocation.java b/src/dk/camelot64/kickc/icl/RegisterAllocation.java index 06f52bad0..6b75100ae 100644 --- a/src/dk/camelot64/kickc/icl/RegisterAllocation.java +++ b/src/dk/camelot64/kickc/icl/RegisterAllocation.java @@ -35,14 +35,16 @@ public class RegisterAllocation { } /** The register type. */ - public enum RegisterType { ZP }; + public enum RegisterType { + ZP_BYTE, ZP_BOOL + }; /** A zero page address used as a register for a single byte variable. */ - public static class RegisterZp implements Register { + public static class RegisterZpByte implements Register { private int zp; - public RegisterZp(int zp) { + public RegisterZpByte(int zp) { this.zp = zp; } @@ -52,12 +54,35 @@ public class RegisterAllocation { @Override public RegisterType getType() { - return RegisterType.ZP; + return RegisterType.ZP_BYTE; } @Override public String toString() { - return "zp:"+zp; + return "zp byte:"+zp; + } + } + + /** A zero page address used as a register for a boolean variable. */ + public static class RegisterZpBool implements Register { + private int zp; + + public RegisterZpBool(int zp) { + this.zp = zp; + } + + public int getZp() { + return zp; + } + + @Override + public RegisterType getType() { + return RegisterType.ZP_BOOL; + } + + @Override + public String toString() { + return "zp bool:"+zp; } } @@ -70,4 +95,5 @@ public class RegisterAllocation { } return out.toString(); } + } diff --git a/src/dk/camelot64/kickc/icl/asm/zpby1=coby1.asm b/src/dk/camelot64/kickc/icl/asm/zpby1=coby1.asm new file mode 100644 index 000000000..74a2a50a8 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/asm/zpby1=coby1.asm @@ -0,0 +1,2 @@ +lda #{coby1} +sta {zpby1} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+coby1.asm b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+coby1.asm new file mode 100644 index 000000000..5bd825bba --- /dev/null +++ b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+coby1.asm @@ -0,0 +1,4 @@ +lda {zpby2} +clc +adc #{coby1} +sta {zpby1} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+zpby3.asm b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+zpby3.asm new file mode 100644 index 000000000..3a5edaaa0 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+zpby3.asm @@ -0,0 +1,4 @@ +lda {zpby2} +clc +adc {zpby3} +sta {zpby1} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2-coby1.asm b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2-coby1.asm new file mode 100644 index 000000000..a1cc2cef9 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2-coby1.asm @@ -0,0 +1,4 @@ +lda {zpby2} +sec +sbc #{coby1} +sta {zpby1} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2.asm b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2.asm new file mode 100644 index 000000000..f52963699 --- /dev/null +++ b/src/dk/camelot64/kickc/icl/asm/zpby1=zpby2.asm @@ -0,0 +1,2 @@ +lda {zpby2} +sta {zpby1} \ No newline at end of file diff --git a/src/dk/camelot64/kickc/test/Main.java b/src/dk/camelot64/kickc/test/Main.java index 4619fb11c..a35fc29d7 100644 --- a/src/dk/camelot64/kickc/test/Main.java +++ b/src/dk/camelot64/kickc/test/Main.java @@ -8,7 +8,6 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import java.io.IOException; -import java.io.LineNumberReader; import java.util.ArrayList; import java.util.List; @@ -33,12 +32,6 @@ public class Main { Pass1GenerateControlFlowGraph pass1GenerateControlFlowGraph = new Pass1GenerateControlFlowGraph(symbolTable); ControlFlowGraph controlFlowGraph = pass1GenerateControlFlowGraph.generate(statementSequence); - System.out.println("SYMBOLS"); - System.out.println(symbolTable.toString()); - System.out.println("CONTROL FLOW GRAPH"); - System.out.println(controlFlowGraph.toString()); - - Pass1GenerateSingleStaticAssignmentForm pass1GenerateSingleStaticAssignmentForm = new Pass1GenerateSingleStaticAssignmentForm(symbolTable, controlFlowGraph); pass1GenerateSingleStaticAssignmentForm.generate(); @@ -65,10 +58,16 @@ public class Main { Pass3RegisterAllocation pass3RegisterAllocation = new Pass3RegisterAllocation(controlFlowGraph, symbolTable); pass3RegisterAllocation.allocate(); + Pass4CodeGeneration pass4CodeGeneration = new Pass4CodeGeneration(controlFlowGraph, symbolTable); + + AsmSequence asmSequence = pass4CodeGeneration.generate(); + System.out.println("SYMBOLS"); System.out.println(symbolTable.toString()); System.out.println("CONTROL FLOW GRAPH"); System.out.println(controlFlowGraph.toString()); + System.out.println("ASSEMBLER"); + System.out.println(asmSequence.toString()); } } diff --git a/src/dk/camelot64/kickc/test/test.kc b/src/dk/camelot64/kickc/test/test.kc index 8fa686ee9..543ed766f 100644 --- a/src/dk/camelot64/kickc/test/test.kc +++ b/src/dk/camelot64/kickc/test/test.kc @@ -1,5 +1,5 @@ byte a = 0; -word b = 0; +byte b = 0; byte d=a+b+1; while(a<10) { b=b+a;