diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmFragment.java b/src/main/java/dk/camelot64/kickc/asm/AsmFragment.java index bdb59841f..a99935052 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmFragment.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmFragment.java @@ -59,8 +59,10 @@ public class AsmFragment { throw new AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment); } VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2(); - RegisterAllocation.Register rVal2Register = program.getAllocation().getRegister(assignmentRValue2); - if (!rVal2Register.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) { + Variable assignmentRValue2Var = program.getScope().getVariable(assignmentRValue2); + 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); } StringBuilder signature = new StringBuilder(); @@ -218,7 +220,7 @@ public class AsmFragment { value = program.getScope().getVariable((VariableRef) value); } if (value instanceof Variable) { - value = program.getAllocation().getRegister(((Variable) value).getRef()); + value = ((Variable) value).getAllocation(); } else if (value instanceof PointerDereferenceSimple) { PointerDereferenceSimple deref = (PointerDereferenceSimple) value; return "_star_" + bind(deref.getPointer()); @@ -233,37 +235,37 @@ public class AsmFragment { return name; } } - if (value instanceof RegisterAllocation.Register) { - RegisterAllocation.Register register = (RegisterAllocation.Register) value; - if (RegisterAllocation.RegisterType.ZP_BYTE.equals(register.getType())) { + if (value instanceof Registers.Register) { + Registers.Register register = (Registers.Register) value; + if (Registers.RegisterType.ZP_BYTE.equals(register.getType())) { String name = "zpby" + nextZpByteIdx++; bindings.put(name, value); return name; - } else if (RegisterAllocation.RegisterType.ZP_WORD.equals(register.getType())) { + } else if (Registers.RegisterType.ZP_WORD.equals(register.getType())) { String name = "zpwo" + nextZpWordIdx++; bindings.put(name, value); return name; - } else if (RegisterAllocation.RegisterType.ZP_BOOL.equals(register.getType())) { + } else if (Registers.RegisterType.ZP_BOOL.equals(register.getType())) { String name = "zpbo" + nextZpBoolIdx++; bindings.put(name, value); 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"; bindings.put(name, value); 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"; bindings.put(name, value); 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"; bindings.put(name, value); 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++; bindings.put(name, value); 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(); } } else if (value instanceof ConstantInteger) { @@ -297,16 +299,16 @@ public class AsmFragment { throw new RuntimeException("Binding '" + name + "' not found in fragment " + signature + ".asm"); } String bound; - if (boundValue instanceof RegisterAllocation.Register) { - RegisterAllocation.Register register = (RegisterAllocation.Register) boundValue; - if (register instanceof RegisterAllocation.RegisterZpByte) { - bound = String.format("$%x", ((RegisterAllocation.RegisterZpByte) register).getZp()); - } else if (register instanceof RegisterAllocation.RegisterZpWord) { - bound = String.format("$%x", ((RegisterAllocation.RegisterZpWord) register).getZp()); - } else if (register instanceof RegisterAllocation.RegisterZpBool) { - bound = String.format("$%x", ((RegisterAllocation.RegisterZpBool) register).getZp()); - } else if (register instanceof RegisterAllocation.RegisterZpPointerByte) { - bound = String.format("$%x", ((RegisterAllocation.RegisterZpPointerByte) register).getZp()); + if (boundValue instanceof Registers.Register) { + Registers.Register register = (Registers.Register) boundValue; + if (register instanceof Registers.RegisterZpByte) { + bound = String.format("$%x", ((Registers.RegisterZpByte) register).getZp()); + } else if (register instanceof Registers.RegisterZpWord) { + bound = String.format("$%x", ((Registers.RegisterZpWord) register).getZp()); + } else if (register instanceof Registers.RegisterZpBool) { + bound = String.format("$%x", ((Registers.RegisterZpBool) register).getZp()); + } else if (register instanceof Registers.RegisterZpPointerByte) { + bound = String.format("$%x", ((Registers.RegisterZpPointerByte) register).getZp()); } else { throw new RuntimeException("Register Type not implemented " + register); } diff --git a/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClass.java b/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClass.java index afa6285a1..39a7f91ce 100644 --- a/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClass.java +++ b/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClass.java @@ -18,7 +18,7 @@ public class LiveRangeEquivalenceClass { private LiveRange liveRange; /** 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) { this.program = program; @@ -27,11 +27,11 @@ public class LiveRangeEquivalenceClass { this.register = null; } - public RegisterAllocation.Register getRegister() { + public Registers.Register getRegister() { return register; } - public void setRegister(RegisterAllocation.Register register) { + public void setRegister(Registers.Register register) { this.register = register; } diff --git a/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClassSet.java b/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClassSet.java index f0857a7a8..496ea665e 100644 --- a/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClassSet.java +++ b/src/main/java/dk/camelot64/kickc/icl/LiveRangeEquivalenceClassSet.java @@ -61,15 +61,17 @@ public class LiveRangeEquivalenceClassSet { 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()) { - RegisterAllocation.Register register = equivalenceClass.getRegister(); + Registers.Register register = equivalenceClass.getRegister(); for (VariableRef variable : equivalenceClass.getVariables()) { - allocation.setRegister(variable, register); + Variable var = program.getScope().getVariable(variable); + var.setAllocation(register); } } - return allocation; } diff --git a/src/main/java/dk/camelot64/kickc/icl/Program.java b/src/main/java/dk/camelot64/kickc/icl/Program.java index ab66f0bce..fb8ab4c8c 100644 --- a/src/main/java/dk/camelot64/kickc/icl/Program.java +++ b/src/main/java/dk/camelot64/kickc/icl/Program.java @@ -28,8 +28,6 @@ public class Program { /** Information about loops. */ private NaturalLoopSet loopSet; - /** The register allocation for the variables used during ASM code generation. */ - private RegisterAllocation allocation; /** The live ranges of all variables. */ private LiveRangeVariables liveRangeVariables; /** Live range equivalence classes containing variables that do not have overlapping live ranges. */ @@ -80,7 +78,6 @@ public class Program { return procedureModifiedVars; } - public AsmProgram getAsm() { return asm; } @@ -113,14 +110,6 @@ public class Program { return loopSet; } - public void setAllocation(RegisterAllocation allocation) { - this.allocation = allocation; - } - - public RegisterAllocation getAllocation() { - return allocation; - } - public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) { this.liveRangeVariables = liveRangeVariables; } diff --git a/src/main/java/dk/camelot64/kickc/icl/RegisterCombination.java b/src/main/java/dk/camelot64/kickc/icl/RegisterCombination.java index af95320de..00154ac09 100644 --- a/src/main/java/dk/camelot64/kickc/icl/RegisterCombination.java +++ b/src/main/java/dk/camelot64/kickc/icl/RegisterCombination.java @@ -6,31 +6,32 @@ import java.util.Map; /** A combination of register/ZP assignments for a set of equivalence classes */ public class RegisterCombination { - /** - * The registers allocated to each equivalence class. - */ - private Map allocation; + /** The registers allocated to each equivalence class. */ + private Map allocation; + + public RegisterCombination() { this.allocation = new LinkedHashMap<>(); } - void setRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) { + void setRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) { allocation.put(equivalenceClass, register); } - public RegisterAllocation.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) { + public Registers.Register getRegister(LiveRangeEquivalenceClass equivalenceClass) { return allocation.get(equivalenceClass); } /** * 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()) { - RegisterAllocation.Register register = allocation.get(equivalenceClass); + Registers.Register register = allocation.get(equivalenceClass); 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()) { VariableRef variable = equivalenceClass.getVariables().get(0); LiveRangeEquivalenceClass globalEquivalenceClass = equivalenceClassSet.getEquivalenceClass(variable); - RegisterAllocation.Register register = allocation.get(equivalenceClass); + Registers.Register register = allocation.get(equivalenceClass); globalEquivalenceClass.setRegister(register); } } @@ -51,7 +52,7 @@ public class RegisterCombination { public String toString() { StringBuilder out = new StringBuilder(); 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(" "); } return out.toString(); diff --git a/src/main/java/dk/camelot64/kickc/icl/RegisterCombinationIterator.java b/src/main/java/dk/camelot64/kickc/icl/RegisterCombinationIterator.java index c670c8560..bb7aa592d 100644 --- a/src/main/java/dk/camelot64/kickc/icl/RegisterCombinationIterator.java +++ b/src/main/java/dk/camelot64/kickc/icl/RegisterCombinationIterator.java @@ -31,7 +31,7 @@ public class RegisterCombinationIterator implements Iterator registers = registerPotentials.getPotentialRegisters(equivalenceClass); + List registers = registerPotentials.getPotentialRegisters(equivalenceClass); numIterations = numIterations * registers.size(); } return numIterations; @@ -42,9 +42,9 @@ public class RegisterCombinationIterator implements Iterator potentials = registerPotentials.getPotentialRegisters(equivalenceClass); + List potentials = registerPotentials.getPotentialRegisters(equivalenceClass); int registerIdx = (combinationIdRest % potentials.size()); - RegisterAllocation.Register register = potentials.get(registerIdx); + Registers.Register register = potentials.get(registerIdx); combination.setRegister(equivalenceClass, register); combinationIdRest = (int) Math.floor(combinationIdRest / potentials.size()); } diff --git a/src/main/java/dk/camelot64/kickc/icl/RegisterPotentials.java b/src/main/java/dk/camelot64/kickc/icl/RegisterPotentials.java index a3dbee309..0e40fa27d 100644 --- a/src/main/java/dk/camelot64/kickc/icl/RegisterPotentials.java +++ b/src/main/java/dk/camelot64/kickc/icl/RegisterPotentials.java @@ -7,22 +7,22 @@ import java.util.*; */ public class RegisterPotentials { - private Map> potentials; + private Map> potentials; public RegisterPotentials() { this.potentials = new LinkedHashMap<>(); } - public List getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) { + public List getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) { return potentials.get(equivalenceClass); } - public void setPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass, List registers) { + public void setPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass, List registers) { potentials.put(equivalenceClass, new ArrayList<>(registers)); } - public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) { - List registers = potentials.get(equivalenceClass); + public void removePotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) { + List registers = potentials.get(equivalenceClass); registers.remove(register); } @@ -37,8 +37,8 @@ public class RegisterPotentials { out.append("Potential registers "); out.append(liveRangeEquivalenceClass.toString()); out.append(" : "); - List registers = potentials.get(liveRangeEquivalenceClass); - for (RegisterAllocation.Register register : registers) { + List registers = potentials.get(liveRangeEquivalenceClass); + for (Registers.Register register : registers) { out.append(register.toString()); out.append(" , "); } @@ -47,8 +47,8 @@ public class RegisterPotentials { return out.toString(); } - public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, RegisterAllocation.Register register) { - List registers = potentials.get(equivalenceClass); + public void addPotentialRegister(LiveRangeEquivalenceClass equivalenceClass, Registers.Register register) { + List registers = potentials.get(equivalenceClass); if (!registers.contains(register)) { registers.add(register); } diff --git a/src/main/java/dk/camelot64/kickc/icl/RegisterAllocation.java b/src/main/java/dk/camelot64/kickc/icl/Registers.java similarity index 88% rename from src/main/java/dk/camelot64/kickc/icl/RegisterAllocation.java rename to src/main/java/dk/camelot64/kickc/icl/Registers.java index ef566ecc0..b63b04542 100644 --- a/src/main/java/dk/camelot64/kickc/icl/RegisterAllocation.java +++ b/src/main/java/dk/camelot64/kickc/icl/Registers.java @@ -1,33 +1,28 @@ 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 class RegisterAllocation { - - private Map allocation; - - public RegisterAllocation() { - this.allocation = new LinkedHashMap<>(); + public static Register getRegisterX() { + return new RegisterXByte(); } - /** - * Get the register allocated for a specific variable - * - * @param variable The variable - * @return The allocated register. - */ - public Register getRegister(VariableRef ref) { - return allocation.get(ref); + public static Register getRegisterY() { + return new RegisterYByte(); } + public static Register getRegisterA() { + return new RegisterAByte(); + } - public void setRegister(VariableRef variable, Register register) { - if(variable!=null) { - allocation.put(variable, register); - } + public static Register getRegisterALU() { + return new RegisterALUByte(); + } + + /** 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. */ @@ -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. */ 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. */ public static class RegisterZpBool implements Register { private int zp; @@ -239,7 +228,6 @@ public class RegisterAllocation { } - /** The X register. */ public static class RegisterXByte implements Register { @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(); - } - } diff --git a/src/main/java/dk/camelot64/kickc/icl/Scope.java b/src/main/java/dk/camelot64/kickc/icl/Scope.java index 8cb973835..ebd108d1d 100644 --- a/src/main/java/dk/camelot64/kickc/icl/Scope.java +++ b/src/main/java/dk/camelot64/kickc/icl/Scope.java @@ -256,8 +256,6 @@ public abstract class Scope implements Symbol { @JsonIgnore public String getSymbolTableContents(Program program, Class symbolClass) { - ProgramScope scope = program.getScope(); - RegisterAllocation allocation = program.getAllocation(); VariableRegisterWeights registerWeights = program.getVariableRegisterWeights(); StringBuilder res = new StringBuilder(); Set names = symbols.keySet(); @@ -270,8 +268,8 @@ public abstract class Scope implements Symbol { } else { if (symbolClass == null || symbolClass.isInstance(symbol)) { res.append(symbol.toString(program)); - if (symbol instanceof Variable && allocation != null) { - RegisterAllocation.Register register = allocation.getRegister(((Variable) symbol).getRef()); + if (symbol instanceof Variable) { + Registers.Register register = ((Variable) symbol).getAllocation(); if (register != null) { res.append(" " + register); } diff --git a/src/main/java/dk/camelot64/kickc/icl/Variable.java b/src/main/java/dk/camelot64/kickc/icl/Variable.java index acb85e76c..698e8cd1b 100644 --- a/src/main/java/dk/camelot64/kickc/icl/Variable.java +++ b/src/main/java/dk/camelot64/kickc/icl/Variable.java @@ -19,7 +19,7 @@ public abstract class Variable implements Symbol { 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. */ - 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.*/ private Constant constant; @@ -74,11 +74,11 @@ public abstract class Variable implements Symbol { return name; } - public RegisterAllocation.Register getAllocation() { + public Registers.Register getAllocation() { return allocation; } - public void setAllocation(RegisterAllocation.Register allocation) { + public void setAllocation(Registers.Register allocation) { this.allocation = allocation; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java b/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java index 4a84f9542..0a97590e2 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4AssertNoCpuClobber.java @@ -31,7 +31,6 @@ public class Pass4AssertNoCpuClobber extends Pass2Base { * @return true if there is a clobber problem in the program */ public boolean hasClobberProblem(boolean verbose) { - RegisterAllocation allocation = getProgram().getAllocation(); LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables(); AsmProgram asm = getProgram().getAsm(); boolean clobberProblem = false; @@ -42,7 +41,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base { Statement statement = getGraph().getStatementByIndex(statementIdx); // Find the registered clobbered by the ASM asmSegment AsmClobber asmSegmentClobber = asmSegment.getClobber(); - Collection clobberRegisters = getClobberRegisters(asmSegmentClobber); + Collection clobberRegisters = getClobberRegisters(asmSegmentClobber); // Find vars assigned to in the statement Collection assignedVars = Pass4RegisterUpliftPotentialRegisterAnalysis.getAssignedVars(statement); // Two assigned vars cannot use same register @@ -53,8 +52,8 @@ public class Pass4AssertNoCpuClobber extends Pass2Base { // Same variable - not relevant continue; } - RegisterAllocation.Register register1 = allocation.getRegister(assignedVar1); - RegisterAllocation.Register register2 = allocation.getRegister(assignedVar2); + Registers.Register register1 = getProgram().getScope().getVariable(assignedVar1).getAllocation(); + Registers.Register register2 = getProgram().getScope().getVariable(assignedVar2).getAllocation(); if (register1.equals(register2)) { if (verbose) { 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 aliveVars = new ArrayList<>(liveRangeVariables.getAlive(statement)); // Non-assigned alive variables must not be clobbered for (VariableRef aliveVar : aliveVars) { - RegisterAllocation.Register aliveVarRegister = allocation.getRegister(aliveVar); + Registers.Register aliveVarRegister = getProgram().getScope().getVariable(aliveVar).getAllocation(); if (aliveVarRegister.isZp()) { // No need to check a zp-register - here we are only interested in CPU registers continue; @@ -99,16 +98,16 @@ public class Pass4AssertNoCpuClobber extends Pass2Base { * @param clobber The clobber * @return The clobbered CPU registers */ - public static Collection getClobberRegisters(AsmClobber clobber) { - List clobberRegisters = new ArrayList<>(); + public static Collection getClobberRegisters(AsmClobber clobber) { + List clobberRegisters = new ArrayList<>(); if (clobber.isClobberA()) { - clobberRegisters.add(RegisterAllocation.getRegisterA()); + clobberRegisters.add(Registers.getRegisterA()); } if (clobber.isClobberX()) { - clobberRegisters.add(RegisterAllocation.getRegisterX()); + clobberRegisters.add(Registers.getRegisterX()); } if (clobber.isClobberY()) { - clobberRegisters.add(RegisterAllocation.getRegisterY()); + clobberRegisters.add(Registers.getRegisterY()); } return clobberRegisters; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index cab2f79ad..f6a7d0ca7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -106,8 +106,8 @@ public class Pass4CodeGeneration { boolean isAlu = false; if (lValue instanceof VariableRef) { VariableRef lValueRef = (VariableRef) lValue; - RegisterAllocation.Register lValRegister = program.getAllocation().getRegister(lValueRef); - if (lValRegister.getType().equals(RegisterAllocation.RegisterType.REG_ALU_BYTE)) { + Registers.Register lValRegister = program.getScope().getVariable(lValueRef).getAllocation(); + if (lValRegister.getType().equals(Registers.RegisterType.REG_ALU_BYTE)) { asm.addComment(statement + " // ALU"); StatementAssignment assignmentAlu = assignment; 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) { VariableRef rValueRef = (VariableRef) rValue; - return program.getAllocation().getRegister(rValueRef); + return program.getScope().getVariable(rValueRef).getAllocation(); } else { return null; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java index b9a8c7306..e2b03297a 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java @@ -35,7 +35,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base { // Reset register allocation to original zero page allocation new Pass4RegistersFinalize(getProgram()).allocate(false); // Apply the uplift combination - combination.allocate(getProgram().getAllocation()); + combination.allocate(getProgram().getScope()); // Generate ASM try { new Pass4CodeGeneration(getProgram()).generate(); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialAluAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialAluAnalysis.java index 0f597026f..34d2de179 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialAluAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialAluAnalysis.java @@ -87,7 +87,7 @@ public class Pass4RegisterUpliftPotentialAluAnalysis extends Pass2Base { private void hasAluPotential(RegisterPotentials registerPotentials, VariableRef ref) { LiveRangeEquivalenceClass potentialAluEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(ref); - registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, RegisterAllocation.getRegisterALU()); + registerPotentials.addPotentialRegister(potentialAluEquivalenceClass, Registers.getRegisterALU()); getLog().append("Equivalence Class "+potentialAluEquivalenceClass+" has ALU potential."); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java index f6e11e1e2..4e082fc30 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java @@ -36,14 +36,14 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { modified = true; registerPotentials = new RegisterPotentials(); for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) { - RegisterAllocation.Register defaultRegister = equivalenceClass.getRegister(); - RegisterAllocation.RegisterType registerType = defaultRegister.getType(); - if (registerType.equals(RegisterAllocation.RegisterType.ZP_BYTE)) { - List potentials = Arrays.asList( + Registers.Register defaultRegister = equivalenceClass.getRegister(); + Registers.RegisterType registerType = defaultRegister.getType(); + if (registerType.equals(Registers.RegisterType.ZP_BYTE)) { + List potentials = Arrays.asList( defaultRegister, - RegisterAllocation.getRegisterA(), - RegisterAllocation.getRegisterX(), - RegisterAllocation.getRegisterY()); + Registers.getRegisterA(), + Registers.getRegisterX(), + Registers.getRegisterY()); registerPotentials.setPotentialRegisters(equivalenceClass, potentials); } else { 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 // Find the registers clobbered by all combinations! - Set alwaysClobbered = findAlwaysClobberedRegisters(block, statement, combinationIterator); + Set alwaysClobbered = findAlwaysClobberedRegisters(block, statement, combinationIterator); if (alwaysClobbered.isEmpty()) { // No registers are always clobbered - move on to the next statement continue; @@ -82,7 +82,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { StringBuilder msg = new StringBuilder(); msg.append("Statement ").append(statement.toString(getProgram())); msg.append(" always clobbers "); - for (RegisterAllocation.Register register : alwaysClobbered) { + for (Registers.Register register : alwaysClobbered) { msg.append(register).append(" "); } getLog().append(msg.toString()); @@ -96,8 +96,8 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { // Assigned registers are allowed to be be clobbered continue; } - List alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass); - for (RegisterAllocation.Register clobberedRegister : alwaysClobbered) { + List alivePotentialRegisters = registerPotentials.getPotentialRegisters(aliveClass); + for (Registers.Register clobberedRegister : alwaysClobbered) { if (alivePotentialRegisters.contains(clobberedRegister)) { registerPotentials.removePotentialRegister(aliveClass, clobberedRegister); StringBuilder msg = new StringBuilder(); @@ -125,13 +125,13 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { * @param combinations The regsiter combinations to test * @return A set with registers that are clobbered by all different register assignments in the combination */ - private Set findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) { + private Set findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) { // Initially assume all registers are always clobbered - Set alwaysClobbered = new LinkedHashSet<>(); - alwaysClobbered.add(RegisterAllocation.getRegisterA()); - alwaysClobbered.add(RegisterAllocation.getRegisterX()); - alwaysClobbered.add(RegisterAllocation.getRegisterY()); + Set alwaysClobbered = new LinkedHashSet<>(); + alwaysClobbered.add(Registers.getRegisterA()); + alwaysClobbered.add(Registers.getRegisterX()); + alwaysClobbered.add(Registers.getRegisterY()); Set unknownFragments = new LinkedHashSet<>(); @@ -140,7 +140,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { // Reset register allocation to original zero page allocation new Pass4RegistersFinalize(getProgram()).allocate(false); // Apply the combination - combination.allocate(getProgram().getAllocation()); + combination.allocate(getProgram().getScope()); // Generate ASM AsmProgram asm = new AsmProgram(); asm.startSegment(statement.getIndex(), statement.toString(getProgram())); @@ -157,10 +157,10 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { continue; } AsmClobber clobber = asm.getClobber(); - Collection clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber); - Iterator alwaysClobberIt = alwaysClobbered.iterator(); + Collection clobberRegisters = Pass4AssertNoCpuClobber.getClobberRegisters(clobber); + Iterator alwaysClobberIt = alwaysClobbered.iterator(); while (alwaysClobberIt.hasNext()) { - RegisterAllocation.Register alwaysClobberRegister = alwaysClobberIt.next(); + Registers.Register alwaysClobberRegister = alwaysClobberIt.next(); if (!clobberRegisters.contains(alwaysClobberRegister)) { alwaysClobberIt.remove(); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java index 75efe611a..c66d7f2d2 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftRemains.java @@ -27,7 +27,7 @@ public class Pass4RegisterUpliftRemains extends Pass2Base { Set unknownFragments = new LinkedHashSet<>(); 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; RegisterCombination bestCombination = null; 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 new Pass4RegistersFinalize(getProgram()).allocate(false); // Apply the uplift combination - combination.allocate(getProgram().getAllocation()); + combination.allocate(getProgram().getScope()); // Generate ASM try { new Pass4CodeGeneration(getProgram()).generate(); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java index 02f32fa7c..2a048fb6d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegistersFinalize.java @@ -17,8 +17,7 @@ public class Pass4RegistersFinalize extends Pass2Base { if(reallocZp) { reallocateZp(liveRangeEquivalenceClassSet); } - RegisterAllocation allocation = liveRangeEquivalenceClassSet.createRegisterAllocation(); - getProgram().setAllocation(allocation); + liveRangeEquivalenceClassSet.storeRegisterAllocation(); } /** @@ -28,7 +27,7 @@ public class Pass4RegistersFinalize extends Pass2Base { */ private void reallocateZp(LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet) { for (LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) { - RegisterAllocation.Register register = equivalenceClass.getRegister(); + Registers.Register register = equivalenceClass.getRegister(); if(register==null || register.isZp()) { String before = register==null?null:register.toString(); 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 * @return The new zeropage register */ - private RegisterAllocation.Register allocateNewRegisterZp(SymbolType varType) { + private Registers.Register allocateNewRegisterZp(SymbolType varType) { if (varType.equals(SymbolTypeBasic.BYTE)) { - return new RegisterAllocation.RegisterZpByte(currentZp++); + return new Registers.RegisterZpByte(currentZp++); } else if (varType.equals(SymbolTypeBasic.WORD)) { - RegisterAllocation.RegisterZpWord registerZpWord = - new RegisterAllocation.RegisterZpWord(currentZp); + Registers.RegisterZpWord registerZpWord = + new Registers.RegisterZpWord(currentZp); currentZp = currentZp + 2; return registerZpWord; } else if (varType.equals(SymbolTypeBasic.BOOLEAN)) { - return new RegisterAllocation.RegisterZpBool(currentZp++); + return new Registers.RegisterZpBool(currentZp++); } else if (varType.equals(SymbolTypeBasic.VOID)) { // No need to setRegister register for VOID value return null; } else if (varType instanceof SymbolTypePointer) { - RegisterAllocation.RegisterZpPointerByte registerZpPointerByte = - new RegisterAllocation.RegisterZpPointerByte(currentZp); + Registers.RegisterZpPointerByte registerZpPointerByte = + new Registers.RegisterZpPointerByte(currentZp); currentZp = currentZp + 2; return registerZpPointerByte; } else {