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:
parent
5c907162f3
commit
5367a41bcf
@ -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
|
||||
|
@ -0,0 +1,4 @@
|
||||
inc {zpptrby1}
|
||||
bne !+
|
||||
inc {zpptrby1}+1
|
||||
!:
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 + ')';
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user