private void Alloc(RegisterClass @class) { if (Done.Get(@class) == Count.Get(@class)) { return; } var list = VaList[(int)@class]; var count = Count.Get(@class); var state = VariableContext.State; // var sVars = state.GetListByClass(@class); bool didWork; do { didWork = false; int i; for (i = 0; i < count; i++) { var aVa = list[i]; var aVd = aVa.VariableData; if ((aVa.Flags & (VariableFlags.RReg | VariableFlags.AllocRDone)) != VariableFlags.RReg) { continue; } var aIndex = aVd.RegisterIndex; var bIndex = aVa.InRegIndex; // Shouldn't be the same. if (aIndex == bIndex) { throw new ArgumentException(); } var bVd = state.GetListByClass(@class)[bIndex]; if (bVd != null) { var bVa = bVd.Attributes; // Gp registers only - Swap two registers if we can solve two // allocation tasks by a single 'xchg' instruction, swapping // two registers required by the instruction/node or one register // required with another non-required. if (@class != RegisterClass.Gp) { continue; } Translator.SwapGp(aVd, bVd); aVa.Flags |= VariableFlags.AllocRDone; Done.Add(@class); // Doublehit, two registers allocated by a single swap. if (bVa != null && bVa.InRegIndex == aIndex) { bVa.Flags |= VariableFlags.AllocRDone; Done.Add(@class); } didWork = true; } else if (aIndex != RegisterIndex.Invalid) { Translator.Move(aVd, @class, bIndex); VariableContext.ClobberedRegs.Or(@class, Utils.Mask(bIndex)); aVa.Flags |= VariableFlags.AllocRDone; Done.Add(@class); didWork = true; } else { Translator.Alloc(aVd, @class, bIndex); VariableContext.ClobberedRegs.Or(@class, Utils.Mask(bIndex)); aVa.Flags |= VariableFlags.AllocRDone; Done.Add(@class); didWork = true; } } }while (didWork); }