Пример #1
0
        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);
        }