mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-22 13:29:18 +00:00
Moved register allocation into symbol table Variable
This commit is contained in:
parent
1982d01297
commit
5a91902c21
@ -59,8 +59,10 @@ public class AsmFragment {
|
|||||||
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
||||||
}
|
}
|
||||||
VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2();
|
VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2();
|
||||||
RegisterAllocation.Register rVal2Register = program.getAllocation().getRegister(assignmentRValue2);
|
Variable assignmentRValue2Var = program.getScope().getVariable(assignmentRValue2);
|
||||||
if (!rVal2Register.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
|
Registers.Register rVal2Register = assignmentRValue2Var.getAllocation();
|
||||||
|
|
||||||
|
if (!rVal2Register.getType().equals(Registers.RegisterType.REG_ALU_BYTE)) {
|
||||||
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
||||||
}
|
}
|
||||||
StringBuilder signature = new StringBuilder();
|
StringBuilder signature = new StringBuilder();
|
||||||
@ -218,7 +220,7 @@ public class AsmFragment {
|
|||||||
value = program.getScope().getVariable((VariableRef) value);
|
value = program.getScope().getVariable((VariableRef) value);
|
||||||
}
|
}
|
||||||
if (value instanceof Variable) {
|
if (value instanceof Variable) {
|
||||||
value = program.getAllocation().getRegister(((Variable) value).getRef());
|
value = ((Variable) value).getAllocation();
|
||||||
} else if (value instanceof PointerDereferenceSimple) {
|
} else if (value instanceof PointerDereferenceSimple) {
|
||||||
PointerDereferenceSimple deref = (PointerDereferenceSimple) value;
|
PointerDereferenceSimple deref = (PointerDereferenceSimple) value;
|
||||||
return "_star_" + bind(deref.getPointer());
|
return "_star_" + bind(deref.getPointer());
|
||||||
@ -233,37 +235,37 @@ public class AsmFragment {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value instanceof RegisterAllocation.Register) {
|
if (value instanceof Registers.Register) {
|
||||||
RegisterAllocation.Register register = (RegisterAllocation.Register) value;
|
Registers.Register register = (Registers.Register) value;
|
||||||
if (RegisterAllocation.RegisterType.ZP_BYTE.equals(register.getType())) {
|
if (Registers.RegisterType.ZP_BYTE.equals(register.getType())) {
|
||||||
String name = "zpby" + nextZpByteIdx++;
|
String name = "zpby" + nextZpByteIdx++;
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.ZP_WORD.equals(register.getType())) {
|
} else if (Registers.RegisterType.ZP_WORD.equals(register.getType())) {
|
||||||
String name = "zpwo" + nextZpWordIdx++;
|
String name = "zpwo" + nextZpWordIdx++;
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.ZP_BOOL.equals(register.getType())) {
|
} else if (Registers.RegisterType.ZP_BOOL.equals(register.getType())) {
|
||||||
String name = "zpbo" + nextZpBoolIdx++;
|
String name = "zpbo" + nextZpBoolIdx++;
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.REG_X_BYTE.equals(register.getType())) {
|
} else if (Registers.RegisterType.REG_X_BYTE.equals(register.getType())) {
|
||||||
String name = "xby";
|
String name = "xby";
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.REG_Y_BYTE.equals(register.getType())) {
|
} else if (Registers.RegisterType.REG_Y_BYTE.equals(register.getType())) {
|
||||||
String name = "yby";
|
String name = "yby";
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.REG_A_BYTE.equals(register.getType())) {
|
} else if (Registers.RegisterType.REG_A_BYTE.equals(register.getType())) {
|
||||||
String name = "aby";
|
String name = "aby";
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.ZP_PTR_BYTE.equals(register.getType())) {
|
} else if (Registers.RegisterType.ZP_PTR_BYTE.equals(register.getType())) {
|
||||||
String name = "zpptrby" + nextZpPtrIdx++;
|
String name = "zpptrby" + nextZpPtrIdx++;
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
} else if (RegisterAllocation.RegisterType.REG_ALU_BYTE.equals(register.getType())) {
|
} else if (Registers.RegisterType.REG_ALU_BYTE.equals(register.getType())) {
|
||||||
throw new AluNotApplicableException();
|
throw new AluNotApplicableException();
|
||||||
}
|
}
|
||||||
} else if (value instanceof ConstantInteger) {
|
} else if (value instanceof ConstantInteger) {
|
||||||
@ -297,16 +299,16 @@ public class AsmFragment {
|
|||||||
throw new RuntimeException("Binding '" + name + "' not found in fragment " + signature + ".asm");
|
throw new RuntimeException("Binding '" + name + "' not found in fragment " + signature + ".asm");
|
||||||
}
|
}
|
||||||
String bound;
|
String bound;
|
||||||
if (boundValue instanceof RegisterAllocation.Register) {
|
if (boundValue instanceof Registers.Register) {
|
||||||
RegisterAllocation.Register register = (RegisterAllocation.Register) boundValue;
|
Registers.Register register = (Registers.Register) boundValue;
|
||||||
if (register instanceof RegisterAllocation.RegisterZpByte) {
|
if (register instanceof Registers.RegisterZpByte) {
|
||||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpByte) register).getZp());
|
bound = String.format("$%x", ((Registers.RegisterZpByte) register).getZp());
|
||||||
} else if (register instanceof RegisterAllocation.RegisterZpWord) {
|
} else if (register instanceof Registers.RegisterZpWord) {
|
||||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpWord) register).getZp());
|
bound = String.format("$%x", ((Registers.RegisterZpWord) register).getZp());
|
||||||
} else if (register instanceof RegisterAllocation.RegisterZpBool) {
|
} else if (register instanceof Registers.RegisterZpBool) {
|
||||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpBool) register).getZp());
|
bound = String.format("$%x", ((Registers.RegisterZpBool) register).getZp());
|
||||||
} else if (register instanceof RegisterAllocation.RegisterZpPointerByte) {
|
} else if (register instanceof Registers.RegisterZpPointerByte) {
|
||||||
bound = String.format("$%x", ((RegisterAllocation.RegisterZpPointerByte) register).getZp());
|
bound = String.format("$%x", ((Registers.RegisterZpPointerByte) register).getZp());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Register Type not implemented " + register);
|
throw new RuntimeException("Register Type not implemented " + register);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ public class LiveRangeEquivalenceClass {
|
|||||||
private LiveRange liveRange;
|
private LiveRange liveRange;
|
||||||
|
|
||||||
/** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */
|
/** A register allocated to hold all variables of the equivalence class. (null if no register is currently allocated) */
|
||||||
private RegisterAllocation.Register register;
|
private Registers.Register register;
|
||||||
|
|
||||||
public LiveRangeEquivalenceClass(Program program) {
|
public LiveRangeEquivalenceClass(Program program) {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
@ -27,11 +27,11 @@ public class LiveRangeEquivalenceClass {
|
|||||||
this.register = null;
|
this.register = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterAllocation.Register getRegister() {
|
public Registers.Register getRegister() {
|
||||||
return register;
|
return register;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRegister(RegisterAllocation.Register register) {
|
public void setRegister(Registers.Register register) {
|
||||||
this.register = register;
|
this.register = register;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,15 +61,17 @@ public class LiveRangeEquivalenceClassSet {
|
|||||||
equivalenceClasses.remove(equivalenceClass);
|
equivalenceClasses.remove(equivalenceClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterAllocation createRegisterAllocation() {
|
/**
|
||||||
RegisterAllocation allocation = new RegisterAllocation();
|
* Store the register allocation of the live range equivalence classes into the variables in the symbol table (program scope).
|
||||||
|
*/
|
||||||
|
public void storeRegisterAllocation() {
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : getEquivalenceClasses()) {
|
for (LiveRangeEquivalenceClass equivalenceClass : getEquivalenceClasses()) {
|
||||||
RegisterAllocation.Register register = equivalenceClass.getRegister();
|
Registers.Register register = equivalenceClass.getRegister();
|
||||||
for (VariableRef variable : equivalenceClass.getVariables()) {
|
for (VariableRef variable : equivalenceClass.getVariables()) {
|
||||||
allocation.setRegister(variable, register);
|
Variable var = program.getScope().getVariable(variable);
|
||||||
|
var.setAllocation(register);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allocation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,8 +28,6 @@ public class Program {
|
|||||||
/** Information about loops. */
|
/** Information about loops. */
|
||||||
private NaturalLoopSet loopSet;
|
private NaturalLoopSet loopSet;
|
||||||
|
|
||||||
/** The register allocation for the variables used during ASM code generation. */
|
|
||||||
private RegisterAllocation allocation;
|
|
||||||
/** The live ranges of all variables. */
|
/** The live ranges of all variables. */
|
||||||
private LiveRangeVariables liveRangeVariables;
|
private LiveRangeVariables liveRangeVariables;
|
||||||
/** Live range equivalence classes containing variables that do not have overlapping live ranges. */
|
/** Live range equivalence classes containing variables that do not have overlapping live ranges. */
|
||||||
@ -80,7 +78,6 @@ public class Program {
|
|||||||
return procedureModifiedVars;
|
return procedureModifiedVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AsmProgram getAsm() {
|
public AsmProgram getAsm() {
|
||||||
return asm;
|
return asm;
|
||||||
}
|
}
|
||||||
@ -113,14 +110,6 @@ public class Program {
|
|||||||
return loopSet;
|
return loopSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllocation(RegisterAllocation allocation) {
|
|
||||||
this.allocation = allocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegisterAllocation getAllocation() {
|
|
||||||
return allocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
|
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
|
||||||
this.liveRangeVariables = liveRangeVariables;
|
this.liveRangeVariables = liveRangeVariables;
|
||||||
}
|
}
|
||||||
|
@ -6,31 +6,32 @@ import java.util.Map;
|
|||||||
/** A combination of register/ZP assignments for a set of equivalence classes */
|
/** A combination of register/ZP assignments for a set of equivalence classes */
|
||||||
public class RegisterCombination {
|
public class RegisterCombination {
|
||||||
|
|
||||||
/**
|
/** The registers allocated to each equivalence class. */
|
||||||
* The registers allocated to each equivalence class.
|
private Map<LiveRangeEquivalenceClass, Registers.Register> allocation;
|
||||||
*/
|
|
||||||
private Map<LiveRangeEquivalenceClass, RegisterAllocation.Register> allocation;
|
|
||||||
|
|
||||||
public RegisterCombination() {
|
public RegisterCombination() {
|
||||||
this.allocation = new LinkedHashMap<>();
|
this.allocation = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
void setRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
|
||||||
allocation.put(equivalenceClass, register);
|
allocation.put(equivalenceClass, register);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterAllocation.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) {
|
public Registers.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) {
|
||||||
return allocation.get(equivalenceClass);
|
return allocation.get(equivalenceClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate the registers of the combination into the programs register allocation
|
* Allocate the registers of the combination into the programs register allocation
|
||||||
*/
|
*/
|
||||||
public void allocate(RegisterAllocation registerAllocation) {
|
public void allocate(ProgramScope scope) {
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
||||||
RegisterAllocation.Register register = allocation.get(equivalenceClass);
|
Registers.Register register = allocation.get(equivalenceClass);
|
||||||
for (VariableRef variable : equivalenceClass.getVariables()) {
|
for (VariableRef variable : equivalenceClass.getVariables()) {
|
||||||
registerAllocation.setRegister(variable, register);
|
Variable var = scope.getVariable(variable);
|
||||||
|
var.setAllocation(register);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,7 +43,7 @@ public class RegisterCombination {
|
|||||||
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
||||||
VariableRef variable = equivalenceClass.getVariables().get(0);
|
VariableRef variable = equivalenceClass.getVariables().get(0);
|
||||||
LiveRangeEquivalenceClass globalEquivalenceClass = equivalenceClassSet.getEquivalenceClass(variable);
|
LiveRangeEquivalenceClass globalEquivalenceClass = equivalenceClassSet.getEquivalenceClass(variable);
|
||||||
RegisterAllocation.Register register = allocation.get(equivalenceClass);
|
Registers.Register register = allocation.get(equivalenceClass);
|
||||||
globalEquivalenceClass.setRegister(register);
|
globalEquivalenceClass.setRegister(register);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,7 +52,7 @@ public class RegisterCombination {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder out = new StringBuilder();
|
StringBuilder out = new StringBuilder();
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
for (LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
||||||
RegisterAllocation.Register register = allocation.get(equivalenceClass);
|
Registers.Register register = allocation.get(equivalenceClass);
|
||||||
out.append(register.toString()).append(" ").append(equivalenceClass.toString(false)).append(" ");
|
out.append(register.toString()).append(" ").append(equivalenceClass.toString(false)).append(" ");
|
||||||
}
|
}
|
||||||
return out.toString();
|
return out.toString();
|
||||||
|
@ -31,7 +31,7 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
|
|||||||
public int getNumIterations() {
|
public int getNumIterations() {
|
||||||
int numIterations = 1;
|
int numIterations = 1;
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||||
List<RegisterAllocation.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass);
|
List<Registers.Register> registers = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||||
numIterations = numIterations * registers.size();
|
numIterations = numIterations * registers.size();
|
||||||
}
|
}
|
||||||
return numIterations;
|
return numIterations;
|
||||||
@ -42,9 +42,9 @@ public class RegisterCombinationIterator implements Iterator<RegisterCombination
|
|||||||
RegisterCombination combination = new RegisterCombination();
|
RegisterCombination combination = new RegisterCombination();
|
||||||
int combinationIdRest = nextIterationId;
|
int combinationIdRest = nextIterationId;
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||||
List<RegisterAllocation.Register> potentials = registerPotentials.getPotentialRegisters(equivalenceClass);
|
List<Registers.Register> potentials = registerPotentials.getPotentialRegisters(equivalenceClass);
|
||||||
int registerIdx = (combinationIdRest % potentials.size());
|
int registerIdx = (combinationIdRest % potentials.size());
|
||||||
RegisterAllocation.Register register = potentials.get(registerIdx);
|
Registers.Register register = potentials.get(registerIdx);
|
||||||
combination.setRegister(equivalenceClass, register);
|
combination.setRegister(equivalenceClass, register);
|
||||||
combinationIdRest = (int) Math.floor(combinationIdRest / potentials.size());
|
combinationIdRest = (int) Math.floor(combinationIdRest / potentials.size());
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,22 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class RegisterPotentials {
|
public class RegisterPotentials {
|
||||||
|
|
||||||
private Map<LiveRangeEquivalenceClass, List<RegisterAllocation.Register>> potentials;
|
private Map<LiveRangeEquivalenceClass, List<Registers.Register>> potentials;
|
||||||
|
|
||||||
public RegisterPotentials() {
|
public RegisterPotentials() {
|
||||||
this.potentials = new LinkedHashMap<>();
|
this.potentials = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RegisterAllocation.Register> getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) {
|
public List<Registers.Register> getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) {
|
||||||
return potentials.get(equivalenceClass);
|
return potentials.get(equivalenceClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass, List<RegisterAllocation.Register> registers) {
|
public void setPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass, List<Registers.Register> registers) {
|
||||||
potentials.put(equivalenceClass, new ArrayList<>(registers));
|
potentials.put(equivalenceClass, new ArrayList<>(registers));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
|
||||||
List<RegisterAllocation.Register> registers = potentials.get(equivalenceClass);
|
List<Registers.Register> registers = potentials.get(equivalenceClass);
|
||||||
registers.remove(register);
|
registers.remove(register);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,8 +37,8 @@ public class RegisterPotentials {
|
|||||||
out.append("Potential registers ");
|
out.append("Potential registers ");
|
||||||
out.append(liveRangeEquivalenceClass.toString());
|
out.append(liveRangeEquivalenceClass.toString());
|
||||||
out.append(" : ");
|
out.append(" : ");
|
||||||
List<RegisterAllocation.Register> registers = potentials.get(liveRangeEquivalenceClass);
|
List<Registers.Register> registers = potentials.get(liveRangeEquivalenceClass);
|
||||||
for (RegisterAllocation.Register register : registers) {
|
for (Registers.Register register : registers) {
|
||||||
out.append(register.toString());
|
out.append(register.toString());
|
||||||
out.append(" , ");
|
out.append(" , ");
|
||||||
}
|
}
|
||||||
@ -47,8 +47,8 @@ public class RegisterPotentials {
|
|||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) {
|
public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) {
|
||||||
List<RegisterAllocation.Register> registers = potentials.get(equivalenceClass);
|
List<Registers.Register> registers = potentials.get(equivalenceClass);
|
||||||
if (!registers.contains(register)) {
|
if (!registers.contains(register)) {
|
||||||
registers.add(register);
|
registers.add(register);
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,28 @@
|
|||||||
package dk.camelot64.kickc.icl;
|
package dk.camelot64.kickc.icl;
|
||||||
|
|
||||||
|
/** The different registers available for a program */
|
||||||
|
public class Registers {
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/** Register Allocation for Variable Symbols */
|
public static Register getRegisterX() {
|
||||||
public class RegisterAllocation {
|
return new RegisterXByte();
|
||||||
|
|
||||||
private Map<VariableRef, Register> allocation;
|
|
||||||
|
|
||||||
public RegisterAllocation() {
|
|
||||||
this.allocation = new LinkedHashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static Register getRegisterY() {
|
||||||
* Get the register allocated for a specific variable
|
return new RegisterYByte();
|
||||||
*
|
|
||||||
* @param variable The variable
|
|
||||||
* @return The allocated register.
|
|
||||||
*/
|
|
||||||
public Register getRegister(VariableRef ref) {
|
|
||||||
return allocation.get(ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Register getRegisterA() {
|
||||||
|
return new RegisterAByte();
|
||||||
|
}
|
||||||
|
|
||||||
public void setRegister(VariableRef variable, Register register) {
|
public static Register getRegisterALU() {
|
||||||
if(variable!=null) {
|
return new RegisterALUByte();
|
||||||
allocation.put(variable, register);
|
}
|
||||||
}
|
|
||||||
|
/** The register type. */
|
||||||
|
public enum RegisterType {
|
||||||
|
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_ALU_BYTE, REG_Y_BYTE, REG_X_BYTE, ZP_PTR_BYTE, ZP_WORD
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A register used for storing a single variable. */
|
/** A register used for storing a single variable. */
|
||||||
@ -39,11 +34,6 @@ public class RegisterAllocation {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The register type. */
|
|
||||||
public enum RegisterType {
|
|
||||||
ZP_BYTE, ZP_BOOL, REG_A_BYTE, REG_ALU_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. */
|
/** A zero page address used as a register for a single byte variable. */
|
||||||
public static class RegisterZpByte implements Register {
|
public static class RegisterZpByte implements Register {
|
||||||
|
|
||||||
@ -144,7 +134,6 @@ public class RegisterAllocation {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** A zero page address used as a register for a boolean variable. */
|
/** A zero page address used as a register for a boolean variable. */
|
||||||
public static class RegisterZpBool implements Register {
|
public static class RegisterZpBool implements Register {
|
||||||
private int zp;
|
private int zp;
|
||||||
@ -239,7 +228,6 @@ public class RegisterAllocation {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** The X register. */
|
/** The X register. */
|
||||||
public static class RegisterXByte implements Register {
|
public static class RegisterXByte implements Register {
|
||||||
@Override
|
@Override
|
||||||
@ -363,31 +351,4 @@ public class RegisterAllocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Register getRegisterX() {
|
|
||||||
return new RegisterXByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Register getRegisterY() {
|
|
||||||
return new RegisterYByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Register getRegisterA() {
|
|
||||||
return new RegisterAByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Register getRegisterALU() {
|
|
||||||
return new RegisterALUByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer out = new StringBuffer();
|
|
||||||
for (VariableRef var: allocation.keySet()) {
|
|
||||||
Register register = getRegister(var);
|
|
||||||
out.append(var.toString()+" : "+register.toString()+"\n");
|
|
||||||
}
|
|
||||||
return out.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -256,8 +256,6 @@ public abstract class Scope implements Symbol {
|
|||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public String getSymbolTableContents(Program program, Class symbolClass) {
|
public String getSymbolTableContents(Program program, Class symbolClass) {
|
||||||
ProgramScope scope = program.getScope();
|
|
||||||
RegisterAllocation allocation = program.getAllocation();
|
|
||||||
VariableRegisterWeights registerWeights = program.getVariableRegisterWeights();
|
VariableRegisterWeights registerWeights = program.getVariableRegisterWeights();
|
||||||
StringBuilder res = new StringBuilder();
|
StringBuilder res = new StringBuilder();
|
||||||
Set<String> names = symbols.keySet();
|
Set<String> names = symbols.keySet();
|
||||||
@ -270,8 +268,8 @@ public abstract class Scope implements Symbol {
|
|||||||
} else {
|
} else {
|
||||||
if (symbolClass == null || symbolClass.isInstance(symbol)) {
|
if (symbolClass == null || symbolClass.isInstance(symbol)) {
|
||||||
res.append(symbol.toString(program));
|
res.append(symbol.toString(program));
|
||||||
if (symbol instanceof Variable && allocation != null) {
|
if (symbol instanceof Variable) {
|
||||||
RegisterAllocation.Register register = allocation.getRegister(((Variable) symbol).getRef());
|
Registers.Register register = ((Variable) symbol).getAllocation();
|
||||||
if (register != null) {
|
if (register != null) {
|
||||||
res.append(" " + register);
|
res.append(" " + register);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public abstract class Variable implements Symbol {
|
|||||||
private boolean inferredType;
|
private boolean inferredType;
|
||||||
|
|
||||||
/** If the variable is assigned to an ASM register, this contains the register. If null the variable has no no allocation (yet). Constants are never assigned to registers. */
|
/** If the variable is assigned to an ASM register, this contains the register. If null the variable has no no allocation (yet). Constants are never assigned to registers. */
|
||||||
private RegisterAllocation.Register allocation;
|
private Registers.Register allocation;
|
||||||
|
|
||||||
/** If the variable is a constant this is the constant value. If null the variable is not considered constant.*/
|
/** If the variable is a constant this is the constant value. If null the variable is not considered constant.*/
|
||||||
private Constant constant;
|
private Constant constant;
|
||||||
@ -74,11 +74,11 @@ public abstract class Variable implements Symbol {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterAllocation.Register getAllocation() {
|
public Registers.Register getAllocation() {
|
||||||
return allocation;
|
return allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllocation(RegisterAllocation.Register allocation) {
|
public void setAllocation(Registers.Register allocation) {
|
||||||
this.allocation = allocation;
|
this.allocation = allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
|||||||
* @return true if there is a clobber problem in the program
|
* @return true if there is a clobber problem in the program
|
||||||
*/
|
*/
|
||||||
public boolean hasClobberProblem(boolean verbose) {
|
public boolean hasClobberProblem(boolean verbose) {
|
||||||
RegisterAllocation allocation = getProgram().getAllocation();
|
|
||||||
LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables();
|
LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables();
|
||||||
AsmProgram asm = getProgram().getAsm();
|
AsmProgram asm = getProgram().getAsm();
|
||||||
boolean clobberProblem = false;
|
boolean clobberProblem = false;
|
||||||
@ -42,7 +41,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
|||||||
Statement statement = getGraph().getStatementByIndex(statementIdx);
|
Statement statement = getGraph().getStatementByIndex(statementIdx);
|
||||||
// Find the registered clobbered by the ASM asmSegment
|
// Find the registered clobbered by the ASM asmSegment
|
||||||
AsmClobber asmSegmentClobber = asmSegment.getClobber();
|
AsmClobber asmSegmentClobber = asmSegment.getClobber();
|
||||||
Collection<RegisterAllocation.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
|
Collection<Registers.Register> clobberRegisters = getClobberRegisters(asmSegmentClobber);
|
||||||
// Find vars assigned to in the statement
|
// Find vars assigned to in the statement
|
||||||
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
|
Collection<VariableRef> assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement);
|
||||||
// Two assigned vars cannot use same register
|
// Two assigned vars cannot use same register
|
||||||
@ -53,8 +52,8 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
|||||||
// Same variable - not relevant
|
// Same variable - not relevant
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RegisterAllocation.Register register1 = allocation.getRegister(assignedVar1);
|
Registers.Register register1 = getProgram().getScope().getVariable(assignedVar1).getAllocation();
|
||||||
RegisterAllocation.Register register2 = allocation.getRegister(assignedVar2);
|
Registers.Register register2 = getProgram().getScope().getVariable(assignedVar2).getAllocation();
|
||||||
if (register1.equals(register2)) {
|
if (register1.equals(register2)) {
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
getLog().append("Two assigned variables " + assignedVar1 + " and " + assignedVar2 + " clobbered by use of same register " + register1 + " in statement " + statement);
|
getLog().append("Two assigned variables " + assignedVar1 + " and " + assignedVar2 + " clobbered by use of same register " + register1 + " in statement " + statement);
|
||||||
@ -70,7 +69,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
|||||||
List<VariableRef> aliveVars = new ArrayList<>(liveRangeVariables.getAlive(statement));
|
List<VariableRef> aliveVars = new ArrayList<>(liveRangeVariables.getAlive(statement));
|
||||||
// Non-assigned alive variables must not be clobbered
|
// Non-assigned alive variables must not be clobbered
|
||||||
for (VariableRef aliveVar : aliveVars) {
|
for (VariableRef aliveVar : aliveVars) {
|
||||||
RegisterAllocation.Register aliveVarRegister = allocation.getRegister(aliveVar);
|
Registers.Register aliveVarRegister = getProgram().getScope().getVariable(aliveVar).getAllocation();
|
||||||
if (aliveVarRegister.isZp()) {
|
if (aliveVarRegister.isZp()) {
|
||||||
// No need to check a zp-register - here we are only interested in CPU registers
|
// No need to check a zp-register - here we are only interested in CPU registers
|
||||||
continue;
|
continue;
|
||||||
@ -99,16 +98,16 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
|||||||
* @param clobber The clobber
|
* @param clobber The clobber
|
||||||
* @return The clobbered CPU registers
|
* @return The clobbered CPU registers
|
||||||
*/
|
*/
|
||||||
public static Collection<RegisterAllocation.Register> getClobberRegisters(AsmClobber clobber) {
|
public static Collection<Registers.Register> getClobberRegisters(AsmClobber clobber) {
|
||||||
List<RegisterAllocation.Register> clobberRegisters = new ArrayList<>();
|
List<Registers.Register> clobberRegisters = new ArrayList<>();
|
||||||
if (clobber.isClobberA()) {
|
if (clobber.isClobberA()) {
|
||||||
clobberRegisters.add(RegisterAllocation.getRegisterA());
|
clobberRegisters.add(Registers.getRegisterA());
|
||||||
}
|
}
|
||||||
if (clobber.isClobberX()) {
|
if (clobber.isClobberX()) {
|
||||||
clobberRegisters.add(RegisterAllocation.getRegisterX());
|
clobberRegisters.add(Registers.getRegisterX());
|
||||||
}
|
}
|
||||||
if (clobber.isClobberY()) {
|
if (clobber.isClobberY()) {
|
||||||
clobberRegisters.add(RegisterAllocation.getRegisterY());
|
clobberRegisters.add(Registers.getRegisterY());
|
||||||
}
|
}
|
||||||
return clobberRegisters;
|
return clobberRegisters;
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,8 @@ public class Pass4CodeGeneration {
|
|||||||
boolean isAlu = false;
|
boolean isAlu = false;
|
||||||
if (lValue instanceof VariableRef) {
|
if (lValue instanceof VariableRef) {
|
||||||
VariableRef lValueRef = (VariableRef) lValue;
|
VariableRef lValueRef = (VariableRef) lValue;
|
||||||
RegisterAllocation.Register lValRegister = program.getAllocation().getRegister(lValueRef);
|
Registers.Register lValRegister = program.getScope().getVariable(lValueRef).getAllocation();
|
||||||
if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) {
|
if (lValRegister.getType().equals(Registers.RegisterType.REG_ALU_BYTE)) {
|
||||||
asm.addComment(statement + " // ALU");
|
asm.addComment(statement + " // ALU");
|
||||||
StatementAssignment assignmentAlu = assignment;
|
StatementAssignment assignmentAlu = assignment;
|
||||||
aluState.setAluAssignment(assignmentAlu);
|
aluState.setAluAssignment(assignmentAlu);
|
||||||
@ -214,10 +214,10 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RegisterAllocation.Register getRegister(RValue rValue) {
|
private Registers.Register getRegister(RValue rValue) {
|
||||||
if (rValue instanceof VariableRef) {
|
if (rValue instanceof VariableRef) {
|
||||||
VariableRef rValueRef = (VariableRef) rValue;
|
VariableRef rValueRef = (VariableRef) rValue;
|
||||||
return program.getAllocation().getRegister(rValueRef);
|
return program.getScope().getVariable(rValueRef).getAllocation();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
|||||||
// Reset register allocation to original zero page allocation
|
// Reset register allocation to original zero page allocation
|
||||||
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
||||||
// Apply the uplift combination
|
// Apply the uplift combination
|
||||||
combination.allocate(getProgram().getAllocation());
|
combination.allocate(getProgram().getScope());
|
||||||
// Generate ASM
|
// Generate ASM
|
||||||
try {
|
try {
|
||||||
new Pass4CodeGeneration(getProgram()).generate();
|
new Pass4CodeGeneration(getProgram()).generate();
|
||||||
|
@ -87,7 +87,7 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base {
|
|||||||
|
|
||||||
private void hasAluPotential(RegisterPotentials registerPotentials, VariableRef ref) {
|
private void hasAluPotential(RegisterPotentials registerPotentials, VariableRef ref) {
|
||||||
LiveRangeEquivalenceClass potentialAluEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(ref);
|
LiveRangeEquivalenceClass potentialAluEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(ref);
|
||||||
registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, RegisterAllocation.getRegisterALU());
|
registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, Registers.getRegisterALU());
|
||||||
getLog().append("Equivalence Class "+potentialAluEquivalenceClass+" has ALU potential.");
|
getLog().append("Equivalence Class "+potentialAluEquivalenceClass+" has ALU potential.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
modified = true;
|
modified = true;
|
||||||
registerPotentials = new RegisterPotentials();
|
registerPotentials = new RegisterPotentials();
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||||
RegisterAllocation.Register defaultRegister = equivalenceClass.getRegister();
|
Registers.Register defaultRegister = equivalenceClass.getRegister();
|
||||||
RegisterAllocation.RegisterType registerType = defaultRegister.getType();
|
Registers.RegisterType registerType = defaultRegister.getType();
|
||||||
if (registerType.equals(RegisterAllocation.RegisterType.ZP_BYTE)) {
|
if (registerType.equals(Registers.RegisterType.ZP_BYTE)) {
|
||||||
List<RegisterAllocation.Register> potentials = Arrays.asList(
|
List<Registers.Register> potentials = Arrays.asList(
|
||||||
defaultRegister,
|
defaultRegister,
|
||||||
RegisterAllocation.getRegisterA(),
|
Registers.getRegisterA(),
|
||||||
RegisterAllocation.getRegisterX(),
|
Registers.getRegisterX(),
|
||||||
RegisterAllocation.getRegisterY());
|
Registers.getRegisterY());
|
||||||
registerPotentials.setPotentialRegisters(equivalenceClass, potentials);
|
registerPotentials.setPotentialRegisters(equivalenceClass, potentials);
|
||||||
} else {
|
} else {
|
||||||
registerPotentials.setPotentialRegisters(equivalenceClass, Arrays.asList(defaultRegister));
|
registerPotentials.setPotentialRegisters(equivalenceClass, Arrays.asList(defaultRegister));
|
||||||
@ -74,7 +74,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
|
|
||||||
// For each combination generate the ASM and examine the clobber of all alive variables
|
// For each combination generate the ASM and examine the clobber of all alive variables
|
||||||
// Find the registers clobbered by all combinations!
|
// Find the registers clobbered by all combinations!
|
||||||
Set<RegisterAllocation.Register> alwaysClobbered = findAlwaysClobberedRegisters(block, statement, combinationIterator);
|
Set<Registers.Register> alwaysClobbered = findAlwaysClobberedRegisters(block, statement, combinationIterator);
|
||||||
if (alwaysClobbered.isEmpty()) {
|
if (alwaysClobbered.isEmpty()) {
|
||||||
// No registers are always clobbered - move on to the next statement
|
// No registers are always clobbered - move on to the next statement
|
||||||
continue;
|
continue;
|
||||||
@ -82,7 +82,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
StringBuilder msg = new StringBuilder();
|
StringBuilder msg = new StringBuilder();
|
||||||
msg.append("Statement ").append(statement.toString(getProgram()));
|
msg.append("Statement ").append(statement.toString(getProgram()));
|
||||||
msg.append(" always clobbers ");
|
msg.append(" always clobbers ");
|
||||||
for (RegisterAllocation.Register register : alwaysClobbered) {
|
for (Registers.Register register : alwaysClobbered) {
|
||||||
msg.append(register).append(" ");
|
msg.append(register).append(" ");
|
||||||
}
|
}
|
||||||
getLog().append(msg.toString());
|
getLog().append(msg.toString());
|
||||||
@ -96,8 +96,8 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
// Assigned registers are allowed to be be clobbered
|
// Assigned registers are allowed to be be clobbered
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
List<RegisterAllocation.Register> alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass);
|
List<Registers.Register> alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass);
|
||||||
for (RegisterAllocation.Register clobberedRegister : alwaysClobbered) {
|
for (Registers.Register clobberedRegister : alwaysClobbered) {
|
||||||
if (alivePotentialRegisters.contains(clobberedRegister)) {
|
if (alivePotentialRegisters.contains(clobberedRegister)) {
|
||||||
registerPotentials.removePotentialRegister(aliveClass, clobberedRegister);
|
registerPotentials.removePotentialRegister(aliveClass, clobberedRegister);
|
||||||
StringBuilder msg = new StringBuilder();
|
StringBuilder msg = new StringBuilder();
|
||||||
@ -125,13 +125,13 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
* @param combinations The regsiter combinations to test
|
* @param combinations The regsiter combinations to test
|
||||||
* @return A set with registers that are clobbered by all different register assignments in the combination
|
* @return A set with registers that are clobbered by all different register assignments in the combination
|
||||||
*/
|
*/
|
||||||
private Set<RegisterAllocation.Register> findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) {
|
private Set<Registers.Register> findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) {
|
||||||
|
|
||||||
// Initially assume all registers are always clobbered
|
// Initially assume all registers are always clobbered
|
||||||
Set<RegisterAllocation.Register> alwaysClobbered = new LinkedHashSet<>();
|
Set<Registers.Register> alwaysClobbered = new LinkedHashSet<>();
|
||||||
alwaysClobbered.add(RegisterAllocation.getRegisterA());
|
alwaysClobbered.add(Registers.getRegisterA());
|
||||||
alwaysClobbered.add(RegisterAllocation.getRegisterX());
|
alwaysClobbered.add(Registers.getRegisterX());
|
||||||
alwaysClobbered.add(RegisterAllocation.getRegisterY());
|
alwaysClobbered.add(Registers.getRegisterY());
|
||||||
|
|
||||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
// Reset register allocation to original zero page allocation
|
// Reset register allocation to original zero page allocation
|
||||||
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
||||||
// Apply the combination
|
// Apply the combination
|
||||||
combination.allocate(getProgram().getAllocation());
|
combination.allocate(getProgram().getScope());
|
||||||
// Generate ASM
|
// Generate ASM
|
||||||
AsmProgram asm = new AsmProgram();
|
AsmProgram asm = new AsmProgram();
|
||||||
asm.startSegment(statement.getIndex(), statement.toString(getProgram()));
|
asm.startSegment(statement.getIndex(), statement.toString(getProgram()));
|
||||||
@ -157,10 +157,10 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
AsmClobber clobber = asm.getClobber();
|
AsmClobber clobber = asm.getClobber();
|
||||||
Collection<RegisterAllocation.Register> clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber);
|
Collection<Registers.Register> clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber);
|
||||||
Iterator<RegisterAllocation.Register> alwaysClobberIt = alwaysClobbered.iterator();
|
Iterator<Registers.Register> alwaysClobberIt = alwaysClobbered.iterator();
|
||||||
while (alwaysClobberIt.hasNext()) {
|
while (alwaysClobberIt.hasNext()) {
|
||||||
RegisterAllocation.Register alwaysClobberRegister = alwaysClobberIt.next();
|
Registers.Register alwaysClobberRegister = alwaysClobberIt.next();
|
||||||
if (!clobberRegisters.contains(alwaysClobberRegister)) {
|
if (!clobberRegisters.contains(alwaysClobberRegister)) {
|
||||||
alwaysClobberIt.remove();
|
alwaysClobberIt.remove();
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
|
|||||||
Set<String> unknownFragments = new LinkedHashSet<>();
|
Set<String> unknownFragments = new LinkedHashSet<>();
|
||||||
|
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
for (LiveRangeEquivalenceClass equivalenceClass : equivalenceClasses) {
|
||||||
if (equivalenceClass.getRegister().getType().equals(RegisterAllocation.RegisterType.ZP_BYTE)) {
|
if (equivalenceClass.getRegister().getType().equals(Registers.RegisterType.ZP_BYTE)) {
|
||||||
int bestScore = Integer.MAX_VALUE;
|
int bestScore = Integer.MAX_VALUE;
|
||||||
RegisterCombination bestCombination = null;
|
RegisterCombination bestCombination = null;
|
||||||
RegisterCombinationIterator combinationIterator = new RegisterCombinationIterator(Arrays.asList(equivalenceClass), getProgram().getRegisterPotentials());
|
RegisterCombinationIterator combinationIterator = new RegisterCombinationIterator(Arrays.asList(equivalenceClass), getProgram().getRegisterPotentials());
|
||||||
@ -37,7 +37,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base {
|
|||||||
// Reset register allocation to original zero page allocation
|
// Reset register allocation to original zero page allocation
|
||||||
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
new Pass4RegistersFinalize(getProgram()).allocate(false);
|
||||||
// Apply the uplift combination
|
// Apply the uplift combination
|
||||||
combination.allocate(getProgram().getAllocation());
|
combination.allocate(getProgram().getScope());
|
||||||
// Generate ASM
|
// Generate ASM
|
||||||
try {
|
try {
|
||||||
new Pass4CodeGeneration(getProgram()).generate();
|
new Pass4CodeGeneration(getProgram()).generate();
|
||||||
|
@ -17,8 +17,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
if(reallocZp) {
|
if(reallocZp) {
|
||||||
reallocateZp(liveRangeEquivalenceClassSet);
|
reallocateZp(liveRangeEquivalenceClassSet);
|
||||||
}
|
}
|
||||||
RegisterAllocation allocation = liveRangeEquivalenceClassSet.createRegisterAllocation();
|
liveRangeEquivalenceClassSet.storeRegisterAllocation();
|
||||||
getProgram().setAllocation(allocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,7 +27,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
*/
|
*/
|
||||||
private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
|
private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) {
|
||||||
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||||
RegisterAllocation.Register register = equivalenceClass.getRegister();
|
Registers.Register register = equivalenceClass.getRegister();
|
||||||
if(register==null || register.isZp()) {
|
if(register==null || register.isZp()) {
|
||||||
String before = register==null?null:register.toString();
|
String before = register==null?null:register.toString();
|
||||||
VariableRef variable = equivalenceClass.getVariables().get(0);
|
VariableRef variable = equivalenceClass.getVariables().get(0);
|
||||||
@ -54,22 +53,22 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
* The register type created uses one or more zero page locations based on the variable type
|
* The register type created uses one or more zero page locations based on the variable type
|
||||||
* @return The new zeropage register
|
* @return The new zeropage register
|
||||||
*/
|
*/
|
||||||
private RegisterAllocation.Register allocateNewRegisterZp(SymbolType varType) {
|
private Registers.Register allocateNewRegisterZp(SymbolType varType) {
|
||||||
if (varType.equals(SymbolTypeBasic.BYTE)) {
|
if (varType.equals(SymbolTypeBasic.BYTE)) {
|
||||||
return new RegisterAllocation.RegisterZpByte(currentZp++);
|
return new Registers.RegisterZpByte(currentZp++);
|
||||||
} else if (varType.equals(SymbolTypeBasic.WORD)) {
|
} else if (varType.equals(SymbolTypeBasic.WORD)) {
|
||||||
RegisterAllocation.RegisterZpWord registerZpWord =
|
Registers.RegisterZpWord registerZpWord =
|
||||||
new RegisterAllocation.RegisterZpWord(currentZp);
|
new Registers.RegisterZpWord(currentZp);
|
||||||
currentZp = currentZp + 2;
|
currentZp = currentZp + 2;
|
||||||
return registerZpWord;
|
return registerZpWord;
|
||||||
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
|
} else if (varType.equals(SymbolTypeBasic.BOOLEAN)) {
|
||||||
return new RegisterAllocation.RegisterZpBool(currentZp++);
|
return new Registers.RegisterZpBool(currentZp++);
|
||||||
} else if (varType.equals(SymbolTypeBasic.VOID)) {
|
} else if (varType.equals(SymbolTypeBasic.VOID)) {
|
||||||
// No need to setRegister register for VOID value
|
// No need to setRegister register for VOID value
|
||||||
return null;
|
return null;
|
||||||
} else if (varType instanceof SymbolTypePointer) {
|
} else if (varType instanceof SymbolTypePointer) {
|
||||||
RegisterAllocation.RegisterZpPointerByte registerZpPointerByte =
|
Registers.RegisterZpPointerByte registerZpPointerByte =
|
||||||
new RegisterAllocation.RegisterZpPointerByte(currentZp);
|
new Registers.RegisterZpPointerByte(currentZp);
|
||||||
currentZp = currentZp + 2;
|
currentZp = currentZp + 2;
|
||||||
return registerZpPointerByte;
|
return registerZpPointerByte;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user