mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-07 06:37:31 +00:00
Implmented asm fragment generator
This commit is contained in:
parent
4ca3fe0787
commit
4e4fee9035
83
src/dk/camelot64/kickc/icl/AsmFragmentSignature.java
Normal file
83
src/dk/camelot64/kickc/icl/AsmFragmentSignature.java
Normal file
@ -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<String, RValue> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
48
src/dk/camelot64/kickc/icl/AsmSequence.java
Normal file
48
src/dk/camelot64/kickc/icl/AsmSequence.java
Normal file
@ -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<AsmStatement> sequence;
|
||||
|
||||
public AsmSequence() {
|
||||
this.sequence = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<AsmStatement> 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();
|
||||
}
|
||||
}
|
@ -23,4 +23,5 @@ public class ConstantInteger implements Constant {
|
||||
public String toString() {
|
||||
return "("+getType().getTypeName()+") "+Integer.toString(number);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ public class Pass2AliasElimination extends Pass2Optimization {
|
||||
final Map<Variable, Variable> 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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -46,9 +46,9 @@ public abstract class Pass2Optimization {
|
||||
* @param aliases Variables that have alias values.
|
||||
*/
|
||||
public void replaceVariables(final Map<Variable, ? extends RValue> aliases) {
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor() {
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@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<? extends LValue> 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<? extends LValue> variables) {
|
||||
for (LValue variable : variables) {
|
||||
symbolTable.remove((Symbol) variable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ public class Pass2RedundantPhiElimination extends Pass2Optimization{
|
||||
public boolean optimize() {
|
||||
final Map<Variable, RValue> aliases = findRedundantPhis();
|
||||
removeAssignments(aliases.keySet());
|
||||
deleteSymbols(aliases.keySet());
|
||||
replaceVariables(aliases);
|
||||
for (Variable var : aliases.keySet()) {
|
||||
RValue alias = aliases.get(var);
|
||||
|
@ -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);
|
||||
}
|
||||
|
187
src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java
Normal file
187
src/dk/camelot64/kickc/icl/Pass4CodeGeneration.java
Normal file
@ -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<Statement> 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
2
src/dk/camelot64/kickc/icl/asm/zpby1=coby1.asm
Normal file
2
src/dk/camelot64/kickc/icl/asm/zpby1=coby1.asm
Normal file
@ -0,0 +1,2 @@
|
||||
lda #{coby1}
|
||||
sta {zpby1}
|
4
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+coby1.asm
Normal file
4
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+coby1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {zpby2}
|
||||
clc
|
||||
adc #{coby1}
|
||||
sta {zpby1}
|
4
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+zpby3.asm
Normal file
4
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2+zpby3.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {zpby2}
|
||||
clc
|
||||
adc {zpby3}
|
||||
sta {zpby1}
|
4
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2-coby1.asm
Normal file
4
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2-coby1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {zpby2}
|
||||
sec
|
||||
sbc #{coby1}
|
||||
sta {zpby1}
|
2
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2.asm
Normal file
2
src/dk/camelot64/kickc/icl/asm/zpby1=zpby2.asm
Normal file
@ -0,0 +1,2 @@
|
||||
lda {zpby2}
|
||||
sta {zpby1}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
byte a = 0;
|
||||
word b = 0;
|
||||
byte b = 0;
|
||||
byte d=a+b+1;
|
||||
while(a<10) {
|
||||
b=b+a;
|
||||
|
Loading…
x
Reference in New Issue
Block a user