1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00

Implemented A register - and achieved optimal asm in sprite tabel generation.

This commit is contained in:
jespergravgaard 2017-05-31 00:59:30 +02:00
parent aac15e64dd
commit 0bdd9d2f2e
15 changed files with 177 additions and 96 deletions

View File

@ -166,11 +166,22 @@ public class AsmFragment {
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);
} else if (value instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) value;
RValue pointer = deref.getPointer();
if(pointer instanceof Variable) {
Variable pointerVar = (Variable) pointer;
RegisterAllocation.Register register = symbols.getRegister(pointerVar);
value = new PointerDereferenceRegisterZpByte((RegisterAllocation.RegisterZpPointerByte) register);
}
} else if (value instanceof PointerDereferenceIndexed) {
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) value;
String compositeName =
"ptr_"
+ bind(deref.getPointer())
+ "_"
+ bind(deref.getIndex());
return compositeName;
}
// Find value if it is already bound
@ -201,6 +212,10 @@ public class AsmFragment {
String name = "yby";
bindings.put(name, value);
return name;
} else if (RegisterAllocation.RegisterType.REG_A_BYTE.equals(register.getType())) {
String name = "aby";
bindings.put(name, value);
return name;
} else if (RegisterAllocation.RegisterType.ZP_PTR_BYTE.equals(register.getType())) {
String name = "zpptrby" + nextZpPtrIdx++;
bindings.put(name, value);
@ -213,13 +228,16 @@ public class AsmFragment {
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++;
bindings.put(name, value);
return name;
} else if (value instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) value;
RValue pointer = deref.getPointer();
if(pointer instanceof Constant) {
Constant pointerConst = (Constant) pointer;
if (pointerConst instanceof ConstantInteger) {
String name = "coptr" + nextConstByteIdx++;
bindings.put(name, value);
return name;
}
}
} else if (value instanceof ConstantInteger) {
ConstantInteger intValue = (ConstantInteger) value;
@ -269,12 +287,17 @@ public class AsmFragment {
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) {
ConstantInteger intPointer = (ConstantInteger) pointer;
bound = Integer.toString(intPointer.getNumber());
} else if (boundValue instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) boundValue;
RValue pointer = deref.getPointer();
if(pointer instanceof Constant) {
Constant pointerConst = (Constant) pointer;
if (pointerConst instanceof ConstantInteger) {
ConstantInteger intPointer = (ConstantInteger) pointerConst;
bound = Integer.toString(intPointer.getNumber());
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);
}

View File

@ -0,0 +1,2 @@
clc
adc #{coby1}

View File

@ -0,0 +1 @@
lda #{coby1}

View File

@ -0,0 +1,3 @@
txa
lsr
lsr

View File

@ -0,0 +1 @@
sta {cowo1},x

View File

@ -0,0 +1,2 @@
lda {zpby1}
sta {cowo1},x

View File

@ -73,12 +73,24 @@ public class Pass1GenerateSingleStaticAssignmentForm {
if (lValue instanceof VariableVersion) {
VariableVersion versioned = (VariableVersion) lValue;
blockVersions.put(versioned.getVersionOf(), versioned);
} else if(lValue instanceof PointerDereferenceVariable) {
PointerDereferenceVariable deref = (PointerDereferenceVariable) lValue;
Variable pointer = deref.getPointer();
} else if(lValue instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) lValue;
RValue pointer = deref.getPointer();
VariableVersion version = findOrCreateVersion(pointer, blockVersions, blockNewPhis);
if (version != null) {
deref.setPointerVariable(version);
deref.setPointer(version);
}
} else if(lValue instanceof PointerDereferenceIndexed) {
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) lValue;
RValue pointer = deref.getPointer();
VariableVersion version = findOrCreateVersion(pointer, blockVersions, blockNewPhis);
if (version != null) {
deref.setPointer(version);
}
RValue index = deref.getIndex();
VariableVersion iVersion = findOrCreateVersion(index, blockVersions, blockNewPhis);
if (iVersion != null) {
deref.setIndex(iVersion);
}
}
}

View File

@ -156,7 +156,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
public LValue visitLvaluePtr(KickCParser.LvaluePtrContext ctx) {
LValue lval = (LValue) visit(ctx.lvalue());
if(lval instanceof Variable) {
return new PointerDereferenceVariable((Variable) lval);
return new PointerDereferenceSimple((Variable) lval);
} else {
throw new RuntimeException("Not implemented");
}
@ -166,11 +166,7 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
public LValue visitLvalueArray(KickCParser.LvalueArrayContext ctx) {
LValue lval = (LValue) visit(ctx.lvalue());
RValue index = (RValue) visit(ctx.expr());
Operator operator = new Operator("+");
VariableIntermediate tmpVar = symbolTable.newIntermediateAssignment();
Statement stmt = new StatementAssignment(tmpVar, lval, operator, index);
sequence.addStatement(stmt);
return new PointerDereferenceVariable(tmpVar);
return new PointerDereferenceIndexed((Variable) lval, (Variable)index);
}
@Override

View File

@ -66,18 +66,25 @@ public abstract class Pass2SsaOptimization {
assignment.setRValue2(getAlias(aliases, assignment.getRValue2()));
}
// Handle pointer dereference in LValue
if (lValue instanceof PointerDereferenceVariable) {
PointerDereferenceVariable deref = (PointerDereferenceVariable) lValue;
Variable pointer = deref.getPointer();
if (lValue instanceof PointerDereferenceSimple) {
PointerDereferenceSimple deref = (PointerDereferenceSimple) lValue;
RValue pointer = deref.getPointer();
if (getAlias(aliases, pointer) != null) {
RValue alias = getAlias(aliases, pointer);
if (alias instanceof Variable) {
deref.setPointerVariable((Variable) alias);
} else if (alias instanceof Constant) {
assignment.setLValue(new PointerDereferenceConstant((Constant) alias));
} else {
throw new RuntimeException("Error replacing LValue variable " + lValue + " with " + alias);
}
deref.setPointer(alias);
}
}
if (lValue instanceof PointerDereferenceIndexed) {
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) lValue;
RValue pointer = deref.getPointer();
if (getAlias(aliases, pointer) != null) {
RValue alias = getAlias(aliases, pointer);
deref.setPointer( alias);
}
RValue index = deref.getIndex();
if (getAlias(aliases, index) != null) {
RValue alias = getAlias(aliases, index);
deref.setIndex(alias);
}
}
return null;

View File

@ -58,11 +58,13 @@ public class Pass3RegisterAllocation {
allocation.allocate(symbols.getVariable("ptr#1"), new RegisterAllocation.RegisterZpPointerByte(135));
allocation.allocate(symbols.getVariable("ptr#2"), new RegisterAllocation.RegisterZpPointerByte(135));
allocation.allocate(symbols.getVariable("ptr#3"), new RegisterAllocation.RegisterZpPointerByte(135));
allocation.allocate(symbols.getVariable("v#1"), new RegisterAllocation.RegisterZpByte(137));
allocation.allocate(symbols.getVariable("v#2"), new RegisterAllocation.RegisterZpByte(137));
allocation.allocate(symbols.getVariable("v#3"), new RegisterAllocation.RegisterZpByte(137));
allocation.allocate(symbols.getVariable("v#4"), new RegisterAllocation.RegisterZpByte(137));
allocation.allocate(symbols.getVariable("v#5"), new RegisterAllocation.RegisterZpByte(137));
allocation.allocate(symbols.getVariable("v#1"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("v#2"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("v#3"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("v#4"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("v#5"), new RegisterAllocation.RegisterAByte());
allocation.allocate(symbols.getVariable("$0"), new RegisterAllocation.RegisterAByte());
symbols.setAllocation(allocation);
}

View File

@ -1,24 +0,0 @@
package dk.camelot64.kickc.icl;
/** A dereferenced constant pointer */
public class PointerDereferenceConstant implements PointerDereference {
private Constant pointer;
public PointerDereferenceConstant(Constant pointer) {
this.pointer = pointer;
}
public Constant getPointer() {
return pointer;
}
public Constant getPointerConstant() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
}

View File

@ -0,0 +1,36 @@
package dk.camelot64.kickc.icl;
/** A dereferenced variable pointer plus an index (used for array writes)*/
public class PointerDereferenceIndexed implements PointerDereference {
private RValue pointer;
private RValue index;
public PointerDereferenceIndexed(RValue pointer, RValue index) {
this.pointer = pointer;
this.index = index;
}
public RValue getPointer() {
return pointer;
}
public void setPointer(RValue pointer) {
this.pointer = pointer;
}
public RValue getIndex() {
return index;
}
public void setIndex(RValue index) {
this.index = index;
}
@Override
public String toString() {
return "*(" + pointer + " + " +index + ')';
}
}

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.icl;
/** A dereferenced pointer (based on a variable or a constant pointer)*/
public class PointerDereferenceSimple implements PointerDereference {
private RValue pointer;
public PointerDereferenceSimple(Variable pointer) {
this.pointer = pointer;
}
public RValue getPointer() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
public void setPointer(RValue pointer) {
this.pointer = pointer;
}
}

View File

@ -1,28 +0,0 @@
package dk.camelot64.kickc.icl;
/** A dereferenced variable pointer */
public class PointerDereferenceVariable implements PointerDereference {
private Variable pointer;
public PointerDereferenceVariable(Variable pointer) {
this.pointer = pointer;
}
public Variable getPointer() {
return pointer;
}
public Variable getPointerVariable() {
return pointer;
}
@Override
public String toString() {
return "*(" + pointer + ')';
}
public void setPointerVariable(Variable pointer) {
this.pointer = pointer;
}
}

View File

@ -36,7 +36,7 @@ public class RegisterAllocation {
/** The register type. */
public enum RegisterType {
ZP_BYTE, ZP_BOOL, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
}
/** A zero page address used as a register for a single byte variable. */
@ -227,6 +227,26 @@ public class RegisterAllocation {
}
}
/** The A register. */
public static class RegisterAByte implements Register {
@Override
public RegisterType getType() {
return RegisterType.REG_A_BYTE;
}
@Override
public String toString() {
return "reg byte a";
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return true;
}
}
public static Register getRegisterX() {
return new RegisterXByte();
}
@ -235,6 +255,10 @@ public class RegisterAllocation {
return new RegisterYByte();
}
public static Register getRegisterA() {
return new RegisterAByte();
}
@Override
public String toString() {
StringBuffer out = new StringBuffer();