private void Spill(List <AssemblyOperation> operations, Instruction instruction, Address address) { foreach (Register register in _registers.All) { LiveAnalysisEntry candidateEntry = instruction.LiveVariableEntries.FirstOrDefault(x => x.Variable.Register != null && !instruction.GetAddresses().Contains(x.Variable)); if (candidateEntry != null) { string registerName = candidateEntry.Variable.Register.Name; candidateEntry.Variable.Register.Clear(); operations.Add(new MoveOperation() { Target = candidateEntry.Variable.ToMemoryLocation(), Value = registerName }); operations.Add(new XorInstruction() { Target = registerName, Value = registerName }); candidateEntry.Variable.Spilled = true; TryAssignRegister(address); return; } } }
private void AllocateRegister(ref int relativeAddress, Instruction instruction, Address address, List <AssemblyOperation> operations) { if (address == null) { return; } address.CalculateRelativeAddress(ref relativeAddress); if (address is ConstantValue) { return; } if (!TryAssignRegister(address)) { LiveAnalysisEntry deadEntry = instruction.LiveVariableEntries.FirstOrDefault(x => x.NextUse == null && x.Variable.Register != null); if (deadEntry != null) { deadEntry.Variable.Register.Clear(); TryAssignRegister(address); if (address.Spilled) { operations.Add(new MoveOperation() { Target = address.Register.Name, Value = address.ToMemoryLocation() }); } else { operations.Add(new XorInstruction() { Target = address.Register.Name, Value = address.Register.Name }); } } else { Spill(operations, instruction, address); } } }