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

Asm Fragment binding using registers instead of variables.

This commit is contained in:
jespergravgaard 2017-05-28 18:22:57 +02:00
parent 5c907162f3
commit 5367a41bcf
8 changed files with 66 additions and 36 deletions

View File

@ -171,14 +171,23 @@ public class AsmFragment {
* @return The bound name of the value. If the value has already been bound the existing bound name is returned.
*/
public String bind(Value value) {
if (value instanceof Variable) {
value = symbols.getRegister((Variable) value);
} else if (value instanceof PointerDereferenceVariable) {
PointerDereferenceVariable deref = (PointerDereferenceVariable) value;
Variable pointer = deref.getPointer();
RegisterAllocation.Register register = symbols.getRegister(pointer);
value = new PointerDereferenceRegisterZpByte((RegisterAllocation.RegisterZpPointerByte) register);
}
// 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 (value instanceof RegisterAllocation.Register) {
RegisterAllocation.Register register = (RegisterAllocation.Register) value;
if (RegisterAllocation.RegisterType.ZP_BYTE.equals(register.getType())) {
String name = "zpby" + nextZpByteIdx++;
bindings.put(name, value);
@ -200,20 +209,18 @@ public class AsmFragment {
bindings.put(name, value);
return name;
}
} else if (value instanceof PointerDereferenceVariable) {
PointerDereferenceVariable deref = (PointerDereferenceVariable) value;
Variable pointer = deref.getPointer();
RegisterAllocation.Register register = symbols.getRegister(pointer);
} else if (value instanceof PointerDereferenceRegisterZpByte) {
RegisterAllocation.Register register = ((PointerDereferenceRegisterZpByte) value).getPointerRegister();
if (RegisterAllocation.RegisterType.ZP_PTR_BYTE.equals(register.getType())) {
String name = "zpiby"+ nextZpPtrIdx++;
String name = "zpiby" + nextZpPtrIdx++;
bindings.put(name, value);
return name;
}
} else if (value instanceof PointerDereferenceConstant) {
PointerDereferenceConstant deref = (PointerDereferenceConstant) value;
Constant pointer = deref.getPointer();
if(pointer instanceof ConstantInteger) {
String name = "coptr"+ nextConstByteIdx++;
if (pointer instanceof ConstantInteger) {
String name = "coptr" + nextConstByteIdx++;
bindings.put(name, value);
return name;
}
@ -244,12 +251,12 @@ public class AsmFragment {
*/
public String getBoundValue(String name) {
Value boundValue = getBinding(name);
if(boundValue==null) {
throw new RuntimeException("Binding not found in fragment '" + name+"'");
if (boundValue == null) {
throw new RuntimeException("Binding not found in fragment '" + name + "'");
}
String bound;
if (boundValue instanceof Variable) {
RegisterAllocation.Register register = symbols.getRegister((Variable) boundValue);
if (boundValue instanceof RegisterAllocation.Register) {
RegisterAllocation.Register register = (RegisterAllocation.Register) boundValue;
if (register instanceof RegisterAllocation.RegisterZpByte) {
bound = Integer.toString(((RegisterAllocation.RegisterZpByte) register).getZp());
} else if (register instanceof RegisterAllocation.RegisterZpBool) {
@ -259,16 +266,11 @@ public class AsmFragment {
} else {
throw new RuntimeException("Register Type not implemented " + register);
}
} else if(boundValue instanceof PointerDereferenceVariable) {
PointerDereferenceVariable deref = (PointerDereferenceVariable) boundValue;
Variable pointer = deref.getPointer();
RegisterAllocation.Register register = symbols.getRegister(pointer);
if(register instanceof RegisterAllocation.RegisterZpPointerByte) {
bound = Integer.toString(((RegisterAllocation.RegisterZpPointerByte) register).getZp());
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}
} else if(boundValue instanceof PointerDereferenceConstant) {
} else if (boundValue instanceof PointerDereferenceRegisterZpByte) {
PointerDereferenceRegisterZpByte deref = (PointerDereferenceRegisterZpByte) boundValue;
RegisterAllocation.RegisterZpPointerByte register = deref.getPointerRegister();
bound = Integer.toString(register.getZp());
} else if (boundValue instanceof PointerDereferenceConstant) {
PointerDereferenceConstant deref = (PointerDereferenceConstant) boundValue;
Constant pointer = deref.getPointer();
if (pointer instanceof ConstantInteger) {
@ -430,13 +432,13 @@ public class AsmFragment {
public Object visitExprBinary(Asm6502Parser.ExprBinaryContext ctx) {
Object left = this.visit(ctx.expr(0));
Object right = this.visit(ctx.expr(1));
return ""+left+ctx.getChild(1).getText()+right;
return "" + left + ctx.getChild(1).getText() + right;
}
@Override
public Object visitExprUnary(Asm6502Parser.ExprUnaryContext ctx) {
Object sub = this.visit(ctx.expr());
return ctx.getChild(0).getText()+sub;
return ctx.getChild(0).getText() + sub;
}
@Override

View File

@ -0,0 +1,4 @@
inc {zpptrby1}
bne !+
inc {zpptrby1}+1
!:

View File

@ -5,12 +5,12 @@ import dk.camelot64.kickc.asm.*;
/**
* Code Generation of 6502 Assembler from ICL/SSA Control Flow Graph
*/
public class Pass4CodeGeneration {
public class Pass3CodeGeneration {
private ControlFlowGraph graph;
private SymbolTable symbols;
public Pass4CodeGeneration(ControlFlowGraph graph, SymbolTable symbols) {
public Pass3CodeGeneration(ControlFlowGraph graph, SymbolTable symbols) {
this.graph = graph;
this.symbols = symbols;
}

View File

@ -9,11 +9,11 @@ import java.util.List;
/** Optimization performed on Assembler Code (Asm Code).
* Optimizations are performed repeatedly until none of them yield any result
**/
public class Pass5AsmOptimization {
public class Pass4AsmOptimization {
private AsmProgram program;
public Pass5AsmOptimization(AsmProgram program) {
public Pass4AsmOptimization(AsmProgram program) {
this.program = program;
}

View File

@ -6,13 +6,12 @@ import dk.camelot64.kickc.asm.AsmLine;
import dk.camelot64.kickc.asm.AsmProgram;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/** Optimize assembler code by removing jumps to labels immediately following the jump */
public class Pass5NextJumpElimination extends Pass5AsmOptimization {
public class Pass4NextJumpElimination extends Pass4AsmOptimization {
public Pass5NextJumpElimination(AsmProgram program) {
public Pass4NextJumpElimination(AsmProgram program) {
super(program);
}

View File

@ -0,0 +1,25 @@
package dk.camelot64.kickc.icl;
/** A dereferenced ZP pointer to a byte */
public class PointerDereferenceRegisterZpByte implements PointerDereference {
private RegisterAllocation.RegisterZpPointerByte pointer;
public PointerDereferenceRegisterZpByte(RegisterAllocation.RegisterZpPointerByte pointer) {
this.pointer = pointer;
}
public RegisterAllocation.RegisterZpPointerByte getPointer() {
return pointer;
}
public RegisterAllocation.RegisterZpPointerByte getPointerRegister() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
}

View File

@ -28,7 +28,7 @@ public class RegisterAllocation {
}
/** A register used for storing a single variable. */
public interface Register {
public interface Register extends Value {
RegisterType getType();

View File

@ -69,10 +69,10 @@ public class Main {
Pass3RegisterAllocation pass3RegisterAllocation = new Pass3RegisterAllocation(controlFlowGraph, symbolTable);
pass3RegisterAllocation.allocate();
Pass3CodeGeneration pass3CodeGeneration = new Pass3CodeGeneration(controlFlowGraph, symbolTable);
AsmProgram asmProgram = pass3CodeGeneration.generate();
Pass4CodeGeneration pass4CodeGeneration = new Pass4CodeGeneration(controlFlowGraph, symbolTable);
AsmProgram asmProgram = pass4CodeGeneration.generate();
Pass5NextJumpElimination pass5NextJumpElimination = new Pass5NextJumpElimination(asmProgram);
Pass4NextJumpElimination pass5NextJumpElimination = new Pass4NextJumpElimination(asmProgram);
boolean asmOptimized = true;
while(asmOptimized) {
asmOptimized = pass5NextJumpElimination.optimize();