mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-20 02:32:36 +00:00
Eliminating ZP_BYTE/ZP_WORD/ZP_DWORD register calses & types.
This commit is contained in:
parent
9877da213d
commit
9f523beeaf
@ -453,6 +453,7 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
Registers.RegisterType.ZP_BOOL.equals(register.getType()) ||
|
||||
Registers.RegisterType.ZP_BYTE.equals(register.getType()) ||
|
||||
Registers.RegisterType.ZP_WORD.equals(register.getType()) ||
|
||||
Registers.RegisterType.ZP_MEM.equals(register.getType()) ||
|
||||
Registers.RegisterType.ZP_DWORD.equals(register.getType()) ||
|
||||
Registers.RegisterType.ZP_STRUCT.equals(register.getType())
|
||||
) {
|
||||
|
@ -44,7 +44,7 @@ public class AsmFragmentTemplate {
|
||||
/** The cycles consumed by the ASM of the fragment. */
|
||||
private Double cycles;
|
||||
|
||||
public AsmFragmentTemplate(String signature, String body, boolean cache) {
|
||||
AsmFragmentTemplate(String signature, String body, boolean cache) {
|
||||
this.signature = signature;
|
||||
this.body = body;
|
||||
this.file = true;
|
||||
@ -72,8 +72,6 @@ public class AsmFragmentTemplate {
|
||||
|
||||
/**
|
||||
* Initialize the fields that require parsing the ASM (bodyAsm, clobber, cycles).
|
||||
*
|
||||
* @return The parsed fragment ready for generating
|
||||
*/
|
||||
private void initAsm() {
|
||||
// Parse the body ASM
|
||||
@ -88,12 +86,12 @@ public class AsmFragmentTemplate {
|
||||
Variable v4 = new Variable("z4", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION);
|
||||
Variable v5 = new Variable("z5", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION);
|
||||
Variable v6 = new Variable("z6", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION);
|
||||
v1.setAllocation(new Registers.RegisterZpByte(2));
|
||||
v2.setAllocation(new Registers.RegisterZpByte(4));
|
||||
v3.setAllocation(new Registers.RegisterZpByte(6));
|
||||
v4.setAllocation(new Registers.RegisterZpByte(8));
|
||||
v5.setAllocation(new Registers.RegisterZpByte(9));
|
||||
v6.setAllocation(new Registers.RegisterZpByte(10));
|
||||
v1.setAllocation(new Registers.RegisterZpMem(2, 1));
|
||||
v2.setAllocation(new Registers.RegisterZpMem(4, 1));
|
||||
v3.setAllocation(new Registers.RegisterZpMem(6, 1));
|
||||
v4.setAllocation(new Registers.RegisterZpMem(8, 1));
|
||||
v5.setAllocation(new Registers.RegisterZpMem(9, 1));
|
||||
v6.setAllocation(new Registers.RegisterZpMem(10, 1));
|
||||
if(signature.contains("z1")) bindings.put("z1", v1);
|
||||
if(signature.contains("z2")) bindings.put("z2", v2);
|
||||
if(signature.contains("z3")) bindings.put("z3", v3);
|
||||
@ -108,12 +106,12 @@ public class AsmFragmentTemplate {
|
||||
Variable v4 = new Variable("m4", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.MEMORY);
|
||||
Variable v5 = new Variable("m5", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.MEMORY);
|
||||
Variable v6 = new Variable("m6", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.MEMORY);
|
||||
v1.setAllocation(new Registers.RegisterMemory(v1.getRef()));
|
||||
v2.setAllocation(new Registers.RegisterMemory(v2.getRef()));
|
||||
v3.setAllocation(new Registers.RegisterMemory(v3.getRef()));
|
||||
v4.setAllocation(new Registers.RegisterMemory(v4.getRef()));
|
||||
v5.setAllocation(new Registers.RegisterMemory(v5.getRef()));
|
||||
v6.setAllocation(new Registers.RegisterMemory(v6.getRef()));
|
||||
v1.setAllocation(new Registers.RegisterMemory(v1.getRef(), 1));
|
||||
v2.setAllocation(new Registers.RegisterMemory(v2.getRef(), 1));
|
||||
v3.setAllocation(new Registers.RegisterMemory(v3.getRef(), 1));
|
||||
v4.setAllocation(new Registers.RegisterMemory(v4.getRef(), 1));
|
||||
v5.setAllocation(new Registers.RegisterMemory(v5.getRef(), 1));
|
||||
v6.setAllocation(new Registers.RegisterMemory(v6.getRef(), 1));
|
||||
if(signature.contains("m1")) bindings.put("m1", v1);
|
||||
if(signature.contains("m2")) bindings.put("m2", v2);
|
||||
if(signature.contains("m3")) bindings.put("m3", v3);
|
||||
@ -138,7 +136,7 @@ public class AsmFragmentTemplate {
|
||||
this.cycles = asm.getCycles();
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@ -146,7 +144,7 @@ public class AsmFragmentTemplate {
|
||||
return body;
|
||||
}
|
||||
|
||||
public KickCParser.AsmLinesContext getBodyAsm() {
|
||||
KickCParser.AsmLinesContext getBodyAsm() {
|
||||
if(bodyAsm == null) {
|
||||
initAsm();
|
||||
}
|
||||
@ -175,11 +173,11 @@ public class AsmFragmentTemplate {
|
||||
return cache;
|
||||
}
|
||||
|
||||
public AsmFragmentTemplateSynthesisRule getSynthesis() {
|
||||
AsmFragmentTemplateSynthesisRule getSynthesis() {
|
||||
return synthesis;
|
||||
}
|
||||
|
||||
public AsmFragmentTemplate getSubFragment() {
|
||||
AsmFragmentTemplate getSubFragment() {
|
||||
return subFragment;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ public class Registers {
|
||||
ZP_STRUCT,
|
||||
ZP_BOOL,
|
||||
ZP_VAR,
|
||||
ZP_MEM,
|
||||
CONSTANT,
|
||||
MEMORY
|
||||
}
|
||||
@ -63,14 +64,19 @@ public class Registers {
|
||||
|
||||
boolean isZp();
|
||||
|
||||
int getBytes();
|
||||
|
||||
}
|
||||
|
||||
public static class RegisterMemory implements Register {
|
||||
|
||||
private VariableRef variableRef;
|
||||
|
||||
public RegisterMemory(VariableRef variableRef) {
|
||||
private int bytes;
|
||||
|
||||
public RegisterMemory(VariableRef variableRef, int bytes ) {
|
||||
this.variableRef = variableRef;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public VariableRef getVariableRef() {
|
||||
@ -87,6 +93,11 @@ public class Registers {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "mem "+variableRef.toString();
|
||||
@ -116,7 +127,7 @@ public class Registers {
|
||||
/** The ZP address used for the byte. */
|
||||
private int zp;
|
||||
|
||||
public RegisterZp(int zp) {
|
||||
RegisterZp(int zp) {
|
||||
this.zp = zp;
|
||||
}
|
||||
|
||||
@ -124,6 +135,8 @@ public class Registers {
|
||||
return zp;
|
||||
}
|
||||
|
||||
public abstract int getBytes();
|
||||
|
||||
@Override
|
||||
public boolean isZp() {
|
||||
return true;
|
||||
@ -158,6 +171,51 @@ public class Registers {
|
||||
|
||||
}
|
||||
|
||||
/** Two zero page addresses used as a register for a single unsigned word variable. */
|
||||
public static class RegisterZpMem extends RegisterZp {
|
||||
|
||||
int bytes;
|
||||
|
||||
public RegisterZpMem(int zp, int bytes) {
|
||||
super(zp);
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisterType getType() {
|
||||
return RegisterType.ZP_MEM;
|
||||
}
|
||||
|
||||
public int getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String typeString;
|
||||
if(getBytes()==1) {
|
||||
typeString = RegisterType.ZP_BYTE.toString();
|
||||
} else if(getBytes()==2) {
|
||||
typeString = RegisterType.ZP_WORD.toString();
|
||||
} else if(getBytes()==4) {
|
||||
typeString = RegisterType.ZP_DWORD.toString();
|
||||
} else {
|
||||
typeString = RegisterType.ZP_MEM.toString();
|
||||
}
|
||||
return "zp " + typeString + ":" + getZp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/** A zero page address used as a register for a declared register allocation. Size is initially unknown and will be resolved when performing allocation by setting the type. */
|
||||
public static class RegisterZpDeclared extends RegisterZp {
|
||||
|
||||
@ -177,6 +235,11 @@ public class Registers {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(this == o) return true;
|
||||
@ -194,58 +257,14 @@ public class Registers {
|
||||
}
|
||||
|
||||
|
||||
/** A zero page address used as a register for a single unsigned byte variable. */
|
||||
public static class RegisterZpByte extends RegisterZp {
|
||||
|
||||
public RegisterZpByte(int zp) {
|
||||
super(zp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisterType getType() {
|
||||
return RegisterType.ZP_BYTE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/** Two zero page addresses used as a register for a single unsigned word variable. */
|
||||
public static class RegisterZpWord extends RegisterZp {
|
||||
|
||||
public RegisterZpWord(int zp) {
|
||||
super(zp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisterType getType() {
|
||||
return RegisterType.ZP_WORD;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Four zero page addresses used as a register for a single unsigned word variable. */
|
||||
public static class RegisterZpDWord extends RegisterZp {
|
||||
|
||||
public RegisterZpDWord(int zp) {
|
||||
super(zp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisterType getType() {
|
||||
return RegisterType.ZP_DWORD;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Zero page addresses used as a register for a struct variable. */
|
||||
public static class RegisterZpStruct extends RegisterZp {
|
||||
|
||||
public RegisterZpStruct(int zp) {
|
||||
super(zp);
|
||||
}
|
||||
private int bytes;
|
||||
|
||||
public RegisterZpStructMember getMemberRegister(long memberByteOffset) {
|
||||
return new RegisterZpStructMember((int) (getZp()+memberByteOffset));
|
||||
public RegisterZpStruct(int zp, int bytes) {
|
||||
super(zp);
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -253,20 +272,10 @@ public class Registers {
|
||||
return RegisterType.ZP_STRUCT;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Zero page addresses used as a register for a struct member variable. */
|
||||
public static class RegisterZpStructMember extends RegisterZp {
|
||||
|
||||
public RegisterZpStructMember(int zp) {
|
||||
super(zp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegisterType getType() {
|
||||
return RegisterType.ZP_STRUCT;
|
||||
public int getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** A zero page address used as a register for a boolean variable. */
|
||||
@ -281,7 +290,10 @@ public class Registers {
|
||||
return RegisterType.ZP_BOOL;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBytes() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** A CPU byte register. */
|
||||
@ -294,6 +306,11 @@ public class Registers {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
@ -302,10 +319,7 @@ public class Registers {
|
||||
if(this == obj) {
|
||||
return true;
|
||||
}
|
||||
if(obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return obj != null && getClass() == obj.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -396,6 +410,11 @@ public class Registers {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ConstantValue getConstantValue() {
|
||||
return constantValue;
|
||||
}
|
||||
|
@ -45,7 +45,9 @@ public class Pass4RegisterUpliftPotentialInitialize extends Pass2Base {
|
||||
Registers.RegisterType registerType = defaultRegister.getType();
|
||||
List<Registers.Register> potentials = new ArrayList<>();
|
||||
potentials.add(defaultRegister);
|
||||
if(registerType.equals(Registers.RegisterType.ZP_BYTE) && !varVolatile(equivalenceClass)) {
|
||||
boolean isByte1 = registerType.equals(Registers.RegisterType.ZP_BYTE);
|
||||
boolean isByte2 = defaultRegister instanceof Registers.RegisterZpMem && ((Registers.RegisterZpMem) defaultRegister).getBytes() == 1;
|
||||
if((isByte1 || isByte2) && !varVolatile(equivalenceClass)) {
|
||||
potentials.add(Registers.getRegisterA());
|
||||
potentials.add(Registers.getRegisterX());
|
||||
potentials.add(Registers.getRegisterY());
|
||||
|
@ -23,7 +23,10 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
|
||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||
|
||||
for(LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||
if(equivalenceClass.getRegister().getType().equals(Registers.RegisterType.ZP_BYTE)) {
|
||||
Registers.Register register = equivalenceClass.getRegister();
|
||||
boolean isByte1 = register.getType().equals(Registers.RegisterType.ZP_BYTE);
|
||||
boolean isByte2 = register instanceof Registers.RegisterZpMem && ((Registers.RegisterZpMem) register).getBytes()==1;
|
||||
if(isByte1 || isByte2) {
|
||||
getLog().append("Attempting to uplift remaining variables in" + equivalenceClass);
|
||||
RegisterCombinationIterator combinationIterator = new RegisterCombinationIterator(Arrays.asList(equivalenceClass), getProgram().getRegisterPotentials());
|
||||
VariableRef variableRef = equivalenceClass.getVariables().get(0);
|
||||
|
@ -185,7 +185,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
VariableRef variableRef = equivalenceClass.getVariables().get(0);
|
||||
Variable variable = getProgram().getSymbolInfos().getVariable(variableRef);
|
||||
if(variable.isStorageMemory()) {
|
||||
register = new Registers.RegisterMemory(variableRef);
|
||||
register = new Registers.RegisterMemory(variableRef, variable.getType().getSizeBytes());
|
||||
} else {
|
||||
register = allocateNewRegisterZp(variable);
|
||||
}
|
||||
@ -233,24 +233,24 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
private Registers.Register allocateNewRegisterZp(Variable variable) {
|
||||
SymbolType varType = variable.getType();
|
||||
if(SymbolType.BYTE.equals(varType)) {
|
||||
return new Registers.RegisterZpByte(allocateZp((1)));
|
||||
return new Registers.RegisterZpMem(allocateZp(1), 1);
|
||||
} else if(SymbolType.SBYTE.equals(varType)) {
|
||||
return new Registers.RegisterZpByte(allocateZp(1));
|
||||
return new Registers.RegisterZpMem(allocateZp(1),1);
|
||||
} else if(SymbolType.WORD.equals(varType)) {
|
||||
Registers.RegisterZpWord registerZpWord =
|
||||
new Registers.RegisterZpWord(allocateZp(2));
|
||||
Registers.RegisterZpMem registerZpWord =
|
||||
new Registers.RegisterZpMem(allocateZp(2), 2);
|
||||
return registerZpWord;
|
||||
} else if(SymbolType.SWORD.equals(varType)) {
|
||||
Registers.RegisterZpWord registerZpWord =
|
||||
new Registers.RegisterZpWord(allocateZp(2));
|
||||
Registers.RegisterZpMem registerZpWord =
|
||||
new Registers.RegisterZpMem(allocateZp(2), 2);
|
||||
return registerZpWord;
|
||||
} else if(SymbolType.DWORD.equals(varType)) {
|
||||
Registers.RegisterZpDWord registerZpDWord =
|
||||
new Registers.RegisterZpDWord(allocateZp(4));
|
||||
Registers.RegisterZpMem registerZpDWord =
|
||||
new Registers.RegisterZpMem(allocateZp(4), 4);
|
||||
return registerZpDWord;
|
||||
} else if(SymbolType.SDWORD.equals(varType)) {
|
||||
Registers.RegisterZpDWord registerZpDWord =
|
||||
new Registers.RegisterZpDWord(allocateZp(4));
|
||||
Registers.RegisterZpMem registerZpDWord =
|
||||
new Registers.RegisterZpMem(allocateZp(4), 4);
|
||||
return registerZpDWord;
|
||||
} else if(varType.equals(SymbolType.BOOLEAN)) {
|
||||
return new Registers.RegisterZpBool(allocateZp(1));
|
||||
@ -258,12 +258,12 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
// No need to setRegister register for VOID value
|
||||
return null;
|
||||
} else if(varType instanceof SymbolTypePointer) {
|
||||
Registers.RegisterZpWord registerZpWord =
|
||||
new Registers.RegisterZpWord(allocateZp(2));
|
||||
Registers.RegisterZpMem registerZpWord =
|
||||
new Registers.RegisterZpMem(allocateZp(2), 2);
|
||||
return registerZpWord;
|
||||
} else if(varType instanceof SymbolTypeStruct) {
|
||||
Registers.RegisterZpStruct registerZpStruct =
|
||||
new Registers.RegisterZpStruct(allocateZp(varType.getSizeBytes()));
|
||||
new Registers.RegisterZpStruct(allocateZp(varType.getSizeBytes()), varType.getSizeBytes());
|
||||
return registerZpStruct;
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled variable type " + varType);
|
||||
|
@ -63,7 +63,7 @@ public abstract class Pass4ZeroPageCoalesce extends Pass2Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two lice range equivalence classes are candidates for coalescing by checking that they are not the same
|
||||
* Determines if two live range equivalence classes are candidates for coalescing by checking that they are not the same
|
||||
*
|
||||
* @param ec1 One equivalence class
|
||||
* @param ec2 Another equivalence class
|
||||
@ -142,7 +142,7 @@ public abstract class Pass4ZeroPageCoalesce extends Pass2Base {
|
||||
private static boolean canCoalesceClobber(LiveRangeEquivalenceClass ec1, LiveRangeEquivalenceClass ec2, Set<String> unknownFragments, Program program) {
|
||||
Registers.Register register1 = ec1.getRegister();
|
||||
Registers.Register register2 = ec2.getRegister();
|
||||
if(register1.isZp() && register2.isZp() && register1.getType().equals(register2.getType())) {
|
||||
if(register1.isZp() && register2.isZp() && register1.getBytes()==register2.getBytes()) {
|
||||
// Both registers are on Zero Page & have the same zero page size
|
||||
// Try out the coalesce to test if it works
|
||||
RegisterCombination combination = new RegisterCombination();
|
||||
|
Loading…
Reference in New Issue
Block a user