mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-06 15:41:05 +00:00
Implemented A register - and achieved optimal asm in sprite tabel generation.
This commit is contained in:
parent
aac15e64dd
commit
0bdd9d2f2e
@ -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);
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
clc
|
||||
adc #{coby1}
|
1
src/dk/camelot64/kickc/asm/fragment/aby=coby1.asm
Normal file
1
src/dk/camelot64/kickc/asm/fragment/aby=coby1.asm
Normal file
@ -0,0 +1 @@
|
||||
lda #{coby1}
|
3
src/dk/camelot64/kickc/asm/fragment/aby=xby_ror_2.asm
Normal file
3
src/dk/camelot64/kickc/asm/fragment/aby=xby_ror_2.asm
Normal file
@ -0,0 +1,3 @@
|
||||
txa
|
||||
lsr
|
||||
lsr
|
@ -0,0 +1 @@
|
||||
sta {cowo1},x
|
@ -0,0 +1,2 @@
|
||||
lda {zpby1}
|
||||
sta {cowo1},x
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 + ')';
|
||||
}
|
||||
}
|
36
src/dk/camelot64/kickc/icl/PointerDereferenceIndexed.java
Normal file
36
src/dk/camelot64/kickc/icl/PointerDereferenceIndexed.java
Normal 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 + ')';
|
||||
}
|
||||
|
||||
}
|
24
src/dk/camelot64/kickc/icl/PointerDereferenceSimple.java
Normal file
24
src/dk/camelot64/kickc/icl/PointerDereferenceSimple.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user