Beispiel #1
0
        public x86RegisterMask Union(x86RegisterMask With)
        {
            var Start = Math.Min(Offset, With.Offset);
            var End   = Math.Max(Offset + Size, With.Offset + With.Size);

            return(new x86RegisterMask(Start, End - Start));
        }
Beispiel #2
0
 public void SetUsed(x86RegisterList List, x86RegisterMask Mask)
 {
     for (var i = 0; i < List.Size; i++)
     {
         if (List[i])
         {
             SetUsed(i, Mask);
         }
     }
 }
Beispiel #3
0
 public void Reset()
 {
     if (Initialized)
     {
         for (var i = 0; i < Size; i++)
         {
             UsedRegs[i] = new x86RegisterMask();
         }
     }
 }
Beispiel #4
0
        public x86GRegisterList ToGRegList(x86RegisterMask Mask)
        {
            var Ret = new x86GRegisterList(Size);

            for (var i = 0; i < Size; i++)
            {
                Ret[i] = Mask;
            }

            return(Ret);
        }
Beispiel #5
0
        public x86RegisterMask Intersect(x86RegisterMask With)
        {
            var Start = Math.Max(Offset, With.Offset);
            var End   = Math.Min(Offset + Size, With.Offset + With.Size);

            if (End <= Start)
            {
                return(new x86RegisterMask(0));
            }
            return(new x86RegisterMask(Start, End - Start));
        }
Beispiel #6
0
        public x86RegisterMask Subract(x86RegisterMask Mask)
        {
            if (Mask.Offset > Offset)
            {
                if (Mask.Offset >= Offset + Size)
                {
                    return(this);
                }
                return(new x86RegisterMask(Offset, Mask.Offset - Offset));
            }

            var Cut = Offset - Mask.Offset;

            return(new x86RegisterMask(Offset + Cut, Size - Cut));
        }
Beispiel #7
0
        x86GRegLocation AllocGRegHelper(int Size, bool OneByteVariant,
                                        x86GRegisterList CantBe = new x86GRegisterList(), bool EnableParamLocs = false)
        {
            if (Size == 1)
            {
                OneByteVariant = false;
            }

            var Mask     = new x86RegisterMask(Size);
            var HighMask = new x86RegisterMask(1, 1);

            var Sequence = x86CallConv.AllocationSequence.GRegisters;

            for (var i = 0; i < Sequence.Length; i++)
            {
                var Reg = Sequence[i];
                if (Arch.IsGRegisterExists(Reg, Mask) && IsGRegisterFree(Reg, Mask, EnableParamLocs))
                {
                    if (CantBe.Initialized && !CantBe.IsFree(Reg, Mask))
                    {
                        continue;
                    }
                    if (OneByteVariant && !Arch.IsGRegisterExists(Reg, 0, 1))
                    {
                        continue;
                    }

                    GRegisters.SetUsed(Reg, Mask);
                    return(new x86GRegLocation(Arch, Reg, Mask));
                }

                if (Size == 1 && Arch.IsGRegisterExists(Reg, HighMask) &&
                    IsGRegisterFree(Reg, HighMask, EnableParamLocs))
                {
                    if (CantBe.Initialized && !CantBe.IsFree(Reg, HighMask))
                    {
                        continue;
                    }
                    GRegisters.SetUsed(Reg, HighMask);
                    return(new x86GRegLocation(Arch, Reg, HighMask));
                }
            }

            return(null);
        }
Beispiel #8
0
        bool IsGRegisterFree(int Index, x86RegisterMask Mask, bool EnableParamLocs = false)
        {
            if (!GRegisters.IsFree(Index, Mask))
            {
                return(false);
            }
            if (!FSData.DisabledLocations.GRegisters.IsFree(Index, Mask))
            {
                return(false);
            }

            if (!EnableParamLocs)
            {
                var P = ContainerData.UsedByParams;
                if (P.GRegisters.Initialized && !P.GRegisters.IsFree(Index, Mask))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #9
0
 public bool IsFree(int Index, x86RegisterMask Mask)
 {
     return(UsedRegs[Index].IsFree(Mask));
 }
Beispiel #10
0
 public void SetUnused(int Index, x86RegisterMask Mask)
 {
     UsedRegs[Index] = UsedRegs[Index].Subract(Mask);
 }
Beispiel #11
0
 public void SetUsed(int Index, x86RegisterMask Mask)
 {
     UsedRegs[Index] = UsedRegs[Index].Union(Mask);
 }
Beispiel #12
0
 public bool IsFree(x86RegisterMask Mask)
 {
     return(Size == 0 || Mask.Size == 0 || Mask.Offset >= Offset + Size ||
            Mask.Offset + Mask.Size <= Offset);
 }
Beispiel #13
0
        public x86DataLocation GetAllocated(x86DataLocationType Type, int Size, int Align = -1)
        {
            if ((Type & x86DataLocationType.General) != 0)
            {
                var Sequence = x86CallConv.AllocationSequence.GRegisters;
                var Mask     = new x86RegisterMask(Size);
                var HighMask = new x86RegisterMask(1, Size);

                if ((Type & x86DataLocationType.OneByte) == 0)
                {
                    for (var i = 0; i < Sequence.Length; i++)
                    {
                        var Reg = Sequence[i];
                        if (Arch.IsGRegisterExists(Reg, Mask) && !Arch.IsGRegisterExists(Reg, 0, 1) && !GRegisters.IsFree(Reg, Mask))
                        {
                            return(new x86GRegLocation(Arch, Reg, Mask));
                        }
                    }

                    for (var i = 0; i < Sequence.Length; i++)
                    {
                        var Reg = Sequence[i];
                        if (Arch.IsGRegisterExists(Reg, Mask) && !GRegisters.IsFree(Reg, Mask))
                        {
                            return(new x86GRegLocation(Arch, Reg, Mask));
                        }
                    }
                }
                else
                {
                    for (var i = 0; i < Sequence.Length; i++)
                    {
                        var Reg = Sequence[i];
                        if (Arch.IsGRegisterExists(Reg, Mask) && Arch.IsGRegisterExists(Reg, 0, 1) && !GRegisters.IsFree(Reg, Mask))
                        {
                            return(new x86GRegLocation(Arch, Reg, Mask));
                        }
                    }
                }
            }

            if ((Type & x86DataLocationType.SSEReg) != 0)
            {
                var Sequence = x86CallConv.AllocationSequence.SSERegisters;
                for (var i = 0; i < Sequence.Length; i++)
                {
                    var Reg = Sequence[i];
                    if (Reg < Arch.RegCount && !SSERegisters.IsFree(Reg))
                    {
                        return(new x86SSERegLocation(Arch, Reg, Size));
                    }
                }
            }

            if ((Type & x86DataLocationType.Memory) != 0)
            {
                StackOffset = DataStoring.AlignWithDecrease(StackOffset - Size, Align);
                return(new x86StackLocation(Arch, FuncScope, StackOffset, Size, false));
            }

            return(null);
        }