Click here to Skip to main content
15,886,873 members
Articles / High Performance Computing / Vectorization

Bird Programming Language: Part 1

Rate me:
Please Sign up or sign in to vote.
4.92/5 (129 votes)
1 Jan 2013GPL312 min read 377.9K   2.7K   153  
A new general purpose language that aims to be fast, high level and simple to use.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;

namespace Bird.x86
{
	public static class x86DataLocations
	{
		public static x86DataLocation GetPartOrSelf(x86DataLocation Location, int Offset, int Size = -1)
		{
			if (Size == -1) Size = Location.Size - Offset;
			if (Offset == 0 && Location.Size == Size)
				return Location;

			if (Location is x86MultiLocation)
			{
				var MLocation = Location as x86MultiLocation;

				var Failed = false;
				var HasOtherParts = false;
				x86DataLocation Ret = null;

				MLocation.GetPartHelper(Offset, Size, (Part, PartOffset, PartSize) =>
				{
					var RetPart = GetPartOrSelf(Part, PartOffset, PartSize);
					if (RetPart == null || Failed)
					{
						Failed = true;
						return;
					}

					if (PartSize == Size) Ret = RetPart;
					else HasOtherParts = true;
				});

				if (Failed) return null;
				if (!HasOtherParts) return Ret;
			}

			return Location.GetPart(Offset, Size);
		}

		public static x86DataLocation CutDownFromEnd(x86DataLocation Location, int Size)
		{
			if (Size == 0) return null;
			if (Location.Size < Size)
				throw new ArgumentOutOfRangeException(null, "Size");

			if (Location.Size == Size) return Location;
			else return Location.GetPart(Location.Size - Size, Size);
		}

		public static x86DataLocation CutDownFromEnd(ref x86DataLocation Location, int Size)
		{
			if (Size == 0) return null;
			if (Location.Size < Size)
				throw new ArgumentOutOfRangeException(null, "Size");

			if (Location.Size == Size)
			{
				var Ret = Location;
				Location = null;
				return Ret;
			}
			else
			{
				var Ret = Location.GetPart(Location.Size - Size, Size);
				Location = Location.GetPart(0, Location.Size - Size);
				return Ret;
			}
		}

		public static x86DataLocation CutDownFromStart(x86DataLocation Location, int Size)
		{
			if (Size == 0) return null;
			if (Location.Size < Size)
				throw new ArgumentOutOfRangeException(null, "Size");

			if (Location.Size == Size) return Location;
			else return Location.GetPart(0, Size);
		}

		public static x86DataLocation CutDownFromStart(ref x86DataLocation Location, int Size)
		{
			if (Size == 0) return null;
			if (Location.Size < Size)
				throw new ArgumentOutOfRangeException(null, "Size");

			if (Location.Size == Size)
			{
				var Ret = Location;
				Location = null;
				return Ret;
			}
			else
			{
				var Ret = Location.GetPart(0, Size);
				Location = Location.GetPart(Size);
				return Ret;
			}
		}

		public static void SplitByPow2Size(ref x86DataLocation Location, int MinSize, int MaxSize,
			x86StoredDataType StoredDataType, Action<x86DataLocation, x86StoredDataType> Func)
		{
			x86DataLocation Ret = null;

			SplitByPow2Size(Location, MinSize, MaxSize, StoredDataType,
				(LocationPart, StoredDataTypePart) =>
				{
					if (LocationPart.Size >= MinSize)
						Func(LocationPart, StoredDataTypePart);
					else Ret = LocationPart;
				}
			);

			Location = Ret;
		}

		public static void SplitByPow2Size(ref x86DataLocation Dst, ref x86DataLocation Src,
			int MinSize, int MaxSize, x86StoredDataType StoredDataType,
			Action<x86DataLocation, x86DataLocation, x86StoredDataType> Func)
		{
			x86DataLocation RetDst = null;
			x86DataLocation RetSrc = null;

			SplitByPow2Size(Dst, Src, MinSize, MaxSize, StoredDataType,
				(DstPart, SrcPart, StoredDataTypePart) =>
				{
					if (DstPart.Size >= MinSize)
					{
						Func(DstPart, SrcPart, StoredDataTypePart);
					}
					else
					{
						RetDst = DstPart;
						RetSrc = SrcPart;
					}
				}
			);

			Dst = RetDst;
			Src = RetSrc;
		}

		public static void SplitByPow2Size(x86DataLocation Location, int MinSize, int MaxSize, 
			x86StoredDataType StoredDataType, Action<x86DataLocation, x86StoredDataType> Func)
		{
			SplitBySize(Location, MaxSize, StoredDataType,
				(LocationPart, StoredDataTypePart) =>
				{
					var SizeLeft = LocationPart.Size;
					var Offset = 0;

					for (var s = SizeLeft; s >= MinSize; s /= 2)
					{
						var LocationParts = LocationPart.GetPart(Offset, s);
						if (LocationParts == null) throw new ApplicationException();

						var StoredDataTypeParts = StoredDataTypePart.GetPart(0, s);
						Func(LocationPart, StoredDataTypeParts);

						Offset += s;
						SizeLeft -= s;

						if (SizeLeft == 0)
							return;
					}

					if (SizeLeft > 0)
					{
						var LocationLeft = LocationPart.GetPart(Offset, SizeLeft);
						if (LocationLeft == null) throw new ApplicationException();

						var StoredDataTypeLeft = StoredDataTypePart.GetPart(0, SizeLeft);
						Func(LocationLeft, StoredDataTypeLeft);
					}
				}
			);
		}

		public static void SplitByPow2Size(x86DataLocation Dst, x86DataLocation Src, 
			int MinSize, int MaxSize, x86StoredDataType StoredDataType,
			Action<x86DataLocation, x86DataLocation, x86StoredDataType> Func)
		{
			SplitBySize(Dst, Src, MaxSize, StoredDataType,
				(DstPart, SrcPart, StoredDataTypePart) =>
				{
					var SizeLeft = DstPart.Size;
					var Offset = 0;

					for (var s = SizeLeft; s >= MinSize; s /= 2)
					{
						var DstParts = GetPartOrSelf(DstPart, Offset, s);
						var SrcParts = GetPartOrSelf(SrcPart, Offset, s);
						if (DstParts == null || SrcParts == null)
							throw new ApplicationException();

						var StoredDataTypeParts = StoredDataTypePart.GetPart(0, s);
						Func(DstParts, SrcParts, StoredDataTypeParts);

						Offset += s;
						SizeLeft -= s;

						if (SizeLeft == 0)
							return;
					}

					if (SizeLeft > 0)
					{
						var DstLeft = GetPartOrSelf(DstPart, Offset, SizeLeft);
						var SrcLeft = GetPartOrSelf(SrcPart, Offset, SizeLeft);
						if (DstLeft == null || SrcLeft == null)
							throw new ApplicationException();

						var StoredDataTypeLeft = StoredDataTypePart.GetPart(0, SizeLeft);
						Func(DstLeft, SrcLeft, StoredDataTypeLeft);
					}
				}
			);
		}

		public static void SplitBySize(x86DataLocation Dst, x86DataLocation Src, int DstSize, int SrcSize,
			x86StoredDataType ToStoredDataType, x86StoredDataType FromStoredDataType,
			Action<x86DataLocation, x86DataLocation, x86StoredDataType, x86StoredDataType> Func)
		{
			if (Dst.Size <= DstSize && Src.Size <= SrcSize)
			{
				Func(Dst, Src, ToStoredDataType, FromStoredDataType);
			}
			else
			{
				var SplittedDst = x86DataLocations.Split(Dst, DstSize);
				var SplittedSrc = x86DataLocations.Split(Src, SrcSize);
				if (SplittedDst.Length != SplittedSrc.Length)
					throw new ApplicationException();

				for (var i = 0; i < SplittedDst.Length; i++)
				{
					if (SplittedDst[i] == null || SplittedSrc[i] == null)
						throw new ApplicationException();

					var ToStoredDataTypePart = ToStoredDataType.GetPart(i * DstSize, DstSize);
					var FromStoredDataTypePart = FromStoredDataType.GetPart(i * SrcSize, SrcSize);
					Func(SplittedDst[i], SplittedSrc[i], ToStoredDataTypePart, FromStoredDataTypePart);
				}
			}
		}


		public static void SplitBySize(x86DataLocation Dst, x86DataLocation Src, int Size,
			x86StoredDataType StoredDataType, Action<x86DataLocation, x86DataLocation, x86StoredDataType> Func)
		{
			if (Dst.Size != Src.Size)
				throw new ArgumentException("Dst.Size != Src.Size");

			if (Dst.Size <= Size)
			{
				Func(Dst, Src, StoredDataType);
			}
			else
			{
				var SplittedDst = x86DataLocations.Split(Dst, Size);
				var SplittedSrc = x86DataLocations.Split(Src, Size);
				if (SplittedDst.Length != SplittedSrc.Length)
					throw new ApplicationException();

				for (var i = 0; i < SplittedDst.Length; i++)
				{
					if (SplittedDst[i] == null || SplittedSrc[i] == null)
						throw new ApplicationException();

					var StoredDataTypePart = StoredDataType.GetPart(i * Size, Size);
					Func(SplittedDst[i], SplittedSrc[i], StoredDataTypePart);
				}
			}
		}

		public static void SplitBySize(x86DataLocation Location, int Size,
			x86StoredDataType StoredDataType, Action<x86DataLocation, x86StoredDataType> Func)
		{
			if (Location.Size <= Size)
			{
				Func(Location, StoredDataType);
			}
			else
			{
				var Parts = x86DataLocations.Split(Location, Size);
				for (var i = 0; i < Parts.Length; i++)
					Func(Parts[i], StoredDataType.GetPart(i * Size, Parts[i].Size));
			}
		}

		public static void SplitByMultiLocation(x86DataLocation Location, 
			x86StoredDataType StoredDataType, Action<x86DataLocation, x86StoredDataType> Func)
		{
			if (Location is x86MultiLocation)
			{
				var MLocation = Location as x86MultiLocation;
				var Offset = 0;

				for (var i = 0; i < MLocation.Locations.Length; i++)
				{
					var LocPart = MLocation.Locations[i];
					var PartStoredDataType = StoredDataType.GetPart(Offset, LocPart.Size);
					Func(LocPart, PartStoredDataType);
					Offset += LocPart.Size;
				}
			}
			else
			{
				throw new ArgumentException();
			}
		}

		public static void SplitByMultiLocation(x86DataLocation Dst, 
			x86DataLocation Src, x86StoredDataType StoredDataType, 
			Action<x86DataLocation, x86DataLocation, x86StoredDataType> Func)
		{
			if (Dst is x86MultiLocation)
			{
				var MDst = Dst as x86MultiLocation;
				var Offset = 0;

				for (var i = 0; i < MDst.Locations.Length; i++)
				{
					var DstPart = MDst.Locations[i];
					var SrcPart = Src.GetPart(Offset, DstPart.Size);
					var PartStoredDataType = StoredDataType.GetPart(Offset, DstPart.Size);
					Func(DstPart, SrcPart, PartStoredDataType);
					Offset += DstPart.Size;
				}
			}
			else if (Src is x86MultiLocation)
			{
				var MSrc = Src as x86MultiLocation;
				var Offset = 0;

				for (var i = 0; i < MSrc.Locations.Length; i++)
				{
					var SrcPart = MSrc.Locations[i];
					var DstPart = Dst.GetPart(Offset, SrcPart.Size);
					var PartStoredDataType = StoredDataType.GetPart(Offset, SrcPart.Size);
					Func(DstPart, SrcPart, PartStoredDataType);
					Offset += SrcPart.Size;
				}
			}
			else
			{
				throw new ArgumentException();
			}
		}

		public static x86DataLocation GetZeroData(x86Architecture Arch, IdContainer Container, int Size)
		{
			var Global = Container.GlobalContainer;
			var Type = Global.CommonIds.GetIdentifier<UnsignedType>(Size);
			return new x86ConstLocation(Arch, new ZeroValue(), Type, 0, Size);
		}

		public static void Foreach(x86DataLocation Location, Action<x86DataLocation> Func)
		{
			if (Location is x86MultiLocation)
			{
				var MLoc = Location as x86MultiLocation;
				for (var i = 0; i < MLoc.Locations.Length; i++)
					Func(MLoc.Locations[i]);
			}
			else
			{
				Func(Location);
			}
		}

		public static bool Check(x86DataLocation Location, Predicate<x86DataLocation> Func)
		{
			if (Location is x86MultiLocation)
			{
				var MLoc = Location as x86MultiLocation;
				for (var i = 0; i < MLoc.Locations.Length; i++)
					if (!Func(MLoc.Locations[i])) return false;

				return true;
			}
			else
			{
				return Func(Location);
			}
		}

		public static bool Contains(IEnumerable<x86DataLocation> Locations, x86DataLocation Loc)
		{
			foreach (var e in Locations)
				if (e.Compare(Loc)) return true;

			return false;
		}

		public static x86DataLocation Select(x86DataLocation[] List, x86DataLocation Preferred)
		{
			for (var i = 0; i < List.Length; i++)
				if (List[i].Compare(Preferred)) return List[i];

			return List[0];
		}

		public static x86DataLocation[] Split(x86DataLocation Location, int Size)
		{
			if (Location == null)
				throw new ArgumentNullException("Location");

			if (Location.Size > Size && Location is x86SplittableLocation)
			{
				var Spl = Location as x86SplittableLocation;
				return Spl.Split(Size);
			}

			return new x86DataLocation[] { Location };
		}
	}

	public enum x86OverlappingMode
	{
		Partial,
		Whole,
	}
	
	public abstract class x86DataLocation
	{
		public x86Architecture Arch;
		public int Size;

		public abstract bool HasPart(int Offset, int Size);
		public abstract x86DataLocation GetPart(int Offset, int Size = -1);

		public abstract x86DataLocationType DataType { get; }

		protected abstract bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole);

		public bool Compare(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			if (Mode == x86OverlappingMode.Partial)
			{
				var MSelf = this as x86MultiLocation;
				var MLoc = Loc as x86MultiLocation;

				if (MSelf != null && MLoc != null)
				{
					for (var i = 0; i < MSelf.Locations.Length; i++)
					{
						for (var j = 0; j < MLoc.Locations.Length; j++)
						{
							if (MSelf.Locations[i].CompareSingle(MLoc.Locations[j], Mode))
								return true;
						}
					}

					return false;
				}
				else if (MSelf != null)
				{
					for (var i = 0; i < MSelf.Locations.Length; i++)
					{
						if (MSelf.Locations[i].CompareSingle(Loc, Mode))
							return true;
					}

					return false;
				}
				else if (MLoc != null)
				{
					for (var i = 0; i < MLoc.Locations.Length; i++)
					{
						if (MLoc.Locations[i].CompareSingle(this, Mode))
							return true;
					}

					return false;
				}
				else
				{
					return CompareSingle(Loc, Mode);
				}
			}
			else if (Mode == x86OverlappingMode.Whole)
			{
				var MSelf = this as x86MultiLocation;
				var MLoc = Loc as x86MultiLocation;

				if (MSelf != null || MLoc != null)
				{
					if (MSelf == null || MLoc == null) return false;
					if (MSelf.Locations.Length != MLoc.Locations.Length)
						return false;

					for (var i = 0; i < MSelf.Locations.Length; i++)
					{
						if (!MSelf.Locations[i].CompareSingle(MLoc.Locations[i], Mode))
							return false;
					}

					return true;
				}
				else
				{
					return CompareSingle(Loc, Mode);
				}
			}
			else
			{
				throw new ApplicationException();
			}
		}

		public x86DataLocation(x86Architecture Arch, int Size)
		{
			if (Size < 0)
				throw new ArgumentOutOfRangeException("Size");

			this.Arch = Arch;
			this.Size = Size;
		}

		public virtual x86GRegisterList GetRegs(bool AddressRegs = false)
		{
			return new x86GRegisterList();
		}

		public override string ToString()
		{
			throw new ApplicationException();
		}
		
		public virtual bool IsMemory(x86OverlappingMode Mode = x86OverlappingMode.Partial)
		{
			return false;
		}
	}

	public class x86SSERegLocation : x86DataLocation
	{
		public int Index;

		public override x86DataLocationType DataType
		{
			get { return x86DataLocationType.SSEReg; }
		}

		public x86SSERegLocation(x86Architecture Arch, int Index, int Size = 16)
			: base(Arch, Size)
		{
			if (Size != 16 && Size != 32)
				throw new ArgumentOutOfRangeException("Size must be 16 or 32", "Size");

			this.Index = Index;
		}

		public override string ToString()
		{
			if (Size == 16) return "xmm" + Index.ToString();
			else if (Size == 32) return "ymm" + Index.ToString();
			else throw new ApplicationException();
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var SSE = Loc as x86SSERegLocation;
			if (SSE == null) return false;

			if (Mode == x86OverlappingMode.Whole && SSE.Size != this.Size) 
				return false;

			return SSE.Index == Index;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;

			if (HasPart(Offset, Size))
				return new x86SSERegLocation(Arch, Index, Size);

			return null;
		}

		public override bool HasPart(int Offset, int Size)
		{
			if (Offset == 0)
			{
				if (Size == 16) return true;
				if (Size == 32 && (Arch.Extensions & x86Extensions.AVX) != 0)
					return true;
			}

			return false;
		}
	}

	public class x86FPURegLocation : x86DataLocation
	{
		public int Index;

		public x86FPURegLocation(x86Architecture Arch, int Index)
			: base(Arch, -1)
		{
			this.Index = Index;
		}

		public override x86DataLocationType DataType
		{
			get { throw new NotImplementedException(); }
		}

		public override string ToString()
		{
			return "st" + Index.ToString();
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var FPReg = Loc as x86FPURegLocation;
			return FPReg != null && FPReg.Index == Index;
		}

		public override bool HasPart(int Offset, int Size)
		{
			return false;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			return null;
		}
	}

	public abstract class x86PostCalcedLocation : x86SplittableLocation
	{
		public ExpressionNode AssignedTo;

		public x86PostCalcedLocation(x86Architecture Arch, ExpressionNode AssignedTo, int Offset, int Size)
			: base(Arch, Offset, Size)
		{
			this.AssignedTo = AssignedTo;
		}

		public override x86DataLocationType DataType
		{
			get { return x86DataLocationType.None; }
		}

		public abstract x86DataLocation Location
		{
			get;
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var Self = Location;
			if (Self == null) return false;
			return Location.Compare(Loc, Mode);
		}

		public override x86GRegisterList GetRegs(bool AddressRegs = false)
		{
			return Location.GetRegs(AddressRegs);
		}
	}

	public class x86AssignVarLoc : x86PostCalcedLocation
	{
		public ExpressionNode Assigned;
		public ExpressionNode AssignNode;

		public x86AssignVarLoc(x86Architecture Arch, ExpressionNode AssignNode, ExpressionNode Assigned, ExpressionNode AssignedTo)
			: base(Arch, AssignedTo, 0, (Assigned.Type.RealId as Type).Size)
		{
			if (x86Expressions.NeedsInstructions(Assigned))
				throw new ArgumentException("The node needs instructions", "AssignNode");

			this.Assigned = Assigned;
			this.AssignNode = AssignNode;
		}

		public x86AssignVarLoc(x86Architecture Arch, ExpressionNode AssignNode, ExpressionNode Assigned, ExpressionNode AssignedTo, int Offset, int Size)
			: base(Arch, AssignedTo, Offset, Size)
		{
			if (x86Expressions.NeedsInstructions(Assigned))
				throw new ArgumentException("The node needs instructions", "AssignNode");

			this.Assigned = Assigned;
			this.AssignNode = AssignNode;
		}

		public override bool IsMemory(x86OverlappingMode Mode = x86OverlappingMode.Partial)
		{
			return Assigned.IsMemory(Arch);
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			return new x86AssignVarLoc(Arch, AssignNode, Assigned, AssignedTo, this.Offset + Offset, Size);
		}

		public override bool HasPart(int Offset, int Size)
		{
			return true;
		}

		public override x86DataLocation Location
		{
			get
			{
				var Location = x86Expressions.GetLocation(Arch, Assigned);
				if (Location != null && !(Location is x86SSERegLocation))
				{
					if (Offset != 0 || Location.Size != Size)
						Location = Location.GetPart(Offset, Size);
				}

				return Location;
			}
		}
	}

	public class x86LinkedNodeLocation : x86PostCalcedLocation
	{
		public LinkedExprNode LNode;
		public x86LinkedNodeData LData;

		public x86LinkedNodeLocation(x86Architecture Arch, LinkedExprNode LNode)
			: base(Arch, LNode.Node, 0, (LNode.Node.Type.RealId as Type).Size)
		{
			this.LNode = LNode;
			this.LData = LNode.Data.Get<x86LinkedNodeData>();
		}

		public x86LinkedNodeLocation(x86Architecture Arch, LinkedExprNode LNode, int Offset, int Size)
			: base(Arch, LNode.Node, Offset, Size)
		{
			this.LNode = LNode;
			this.LData = LNode.Data.Get<x86LinkedNodeData>();
		}

		public override bool IsMemory(x86OverlappingMode Mode = x86OverlappingMode.Partial)
		{
			return LData.Location.IsMemory();
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			return new x86LinkedNodeLocation(Arch, LNode, this.Offset + Offset, Size);
		}

		public override bool HasPart(int Offset, int Size)
		{
			return true;
		}

		public override x86DataLocation Location
		{
			get
			{
				if (LData.Location != null && !(LData.Location is x86SSERegLocation))
				{
					if (LData.Location.Size != Size || Offset != 0)
						return LData.Location.GetPart(Offset, Size);
				}

				return LData.Location;
			}
		}
	}

	public abstract class x86SplittableLocation : x86DataLocation
	{
		public int Offset;

		public virtual int AllOffset
		{
			get { return Offset; }
		}

		public x86SplittableLocation(x86Architecture Arch, int Offset, int Size)
			: base(Arch, Size)
		{
			this.Offset = Offset;
		}

		public x86DataLocation[] Split(int Size)
		{
			var Count = (this.Size - 1) / Size + 1;
			var Ret = new x86DataLocation[Count];

			for (var i = 0; i < Count; i++)
			{
				var Offset = i * Size;

				if (Offset + Size > this.Size)
					Ret[i] = GetPart(Offset, this.Size - Offset);
				else Ret[i] = GetPart(Offset, Size);
			}

			return Ret;
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var Splittable = Loc as x86SplittableLocation;
			if (Mode == x86OverlappingMode.Whole)
			{
				return Offset == Splittable.Offset && Size == Splittable.Size;
			}
			else if (Mode == x86OverlappingMode.Partial)
			{
				if (Offset + Size <= Splittable.Offset) return false;
				if (Offset >= Splittable.Offset + Splittable.Size) return false;
				return true;
			}
			else
			{
				throw new NotImplementedException();
			}
		}
	}

	public class x86ConstLocation : x86SplittableLocation
	{
		public ConstValue Value;
		public Identifier Type;

		static ConstValue GetNonStructuredValue(ConstValue Value)
		{
			var SValue = Value as StructuredValue;
			if (SValue != null && SValue.Members.Count == 1)
				return GetNonStructuredValue(SValue.Members[0]);

			return Value;
		}

		public ConstValue NonStructuredValue
		{
			get
			{
				return GetNonStructuredValue(Value);
			}
		}

		public ulong Unsigned
		{
			get
			{
				return Value == null ? 0 : NonStructuredValue.GetUnsigned(Offset, Size);
			}
		}

		public long Signed
		{
			get
			{
				return Value == null ? 0 : NonStructuredValue.GetSigned(Offset, Size);
			}
		}

		public char Char
		{
			get { return (Value as CharValue).Value; }
		}

		public BigInteger Integer
		{
			get { return (Value as IntegerValue).Value; }
		}

		public double Double
		{
			get { return (Value as DoubleValue).Value; }
		}

		public double Float
		{
			get { return (Value as FloatValue).Value; }
		}

		public double CDouble
		{
			get { return Value.Double; }
		}

		public string String
		{
			get { return (Value as StringValue).Value; }
		}

		public bool Bool
		{
			get { return (Value as BooleanValue).Value; }
		}

		public override x86DataLocationType DataType
		{
			get { return x86DataLocationType.None; }
		}

		public x86ConstLocation(x86Architecture Arch, ConstValue Value, Identifier Type, int Offset, int Size)
			: base(Arch, Offset, Size)
		{
			this.Value = Value;
			this.Type = Type;
		}

		public x86ConstLocation(x86Architecture Arch, ConstExpressionNode Node, int Offset, int Size)
			: base(Arch, Offset, Size)
		{
			this.Value = Node.Value;
			this.Type = Node.Type;
		}

#warning WARNING
		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			/*
			if (Offset >= (Type.RealId as Type).Size)
			{
				var Global = Type.Container.GlobalContainer;
				var MemberType = Global.CommonIds.GetIdentifier<UnsignedType>(Size);
				return new x86ConstLocation(Arch, new ZeroValue(), MemberType, 0, Size);
			}
			*/
			if (Type.RealId is StructType)
			{
				var StructuredType = Type.RealId as StructType;
				var Member = StructuredType.GetMemberAt(Offset, Size);
				if (Member == null) return x86DataLocations.GetZeroData(Arch, Type.Container, Size);

				var SValue = Value as StructuredValue;
				var NewOffset = Offset - Member.Offset;
				var Index = StructuredType.StructuredScope.IdentifierList.IndexOf(Member);
                var MemberType = Member.TypeOfSelf.RealId as Type;

				if (SValue == null && Value is ZeroValue)
                    return new x86ConstLocation(Arch, new ZeroValue(), MemberType, NewOffset, Size);

                return new x86ConstLocation(Arch, SValue.Members[Index], MemberType, NewOffset, Size);
			}
			else if (Type.RealId is NonrefArrayType)
			{
				var ArrayType = Type.RealId as NonrefArrayType;
				var TypeOfVals = ArrayType.TypeOfValues;

				var SValue = Value as StructuredValue;
				var MemberOffset = Offset / TypeOfVals.Size * TypeOfVals.Size;
				var NewOffset = Offset - MemberOffset;
				var Index = Offset / TypeOfVals.Size;

				if (NewOffset + Size > TypeOfVals.Size)
					return x86DataLocations.GetZeroData(Arch, Type.Container, Size);

				if (SValue == null && Value is ZeroValue)
					return new x86ConstLocation(Arch, new ZeroValue(), TypeOfVals, NewOffset, Size);

				if (SValue.Members.Count <= Index) 
					return x86DataLocations.GetZeroData(Arch, Type.Container, Size);

				return new x86ConstLocation(Arch, SValue.Members[Index], TypeOfVals, NewOffset, Size);
			}

			return new x86ConstLocation(Arch, Value, Type, this.Offset + Offset, Size);
		}

		public override bool HasPart(int Offset, int Size)
		{
			var StructuredType = Type.RealId as StructuredType;
			if (StructuredType != null)
				return StructuredType.GetMemberAt(Offset, Size) != null;

			return true;
		}

		public override string ToString()
		{
			if (Type.RealId is SignedType) return Signed.ToString();
			else return Unsigned.ToString();

			/*if (Value is BoolValue) return (Value as BoolValue).Value ? "1" : "0";
			if (Value is CharValue) return ((int)(Value as CharValue).Value).ToString();
			return Value.ToString();*/
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var ConstPos = Loc as x86ConstLocation;
			if (ConstPos == null) return false;

			return ConstPos.Value.IsEqual(Value) && base.CompareSingle(Loc, Mode);
		}
	}

	public class x86GRegLocation : x86DataLocation
	{
		public int Offset, Index;

		public x86GRegLocation(x86Architecture Arch, int Index, x86RegisterMask Mask)
			: this(Arch, Index, Mask.Offset, Mask.Size)
		{
		}

		public x86GRegLocation(x86Architecture Arch, int Index, int Offset, int Size)
			: base(Arch, Size)
		{
			if (Index < 0 || Index >= Arch.RegCount) throw new ArgumentOutOfRangeException("Index");
			if (Offset != 0 && Offset != 1) throw new ArgumentOutOfRangeException("Offset");
			if (Size < 0 || Size > Arch.RegSize) throw new ArgumentOutOfRangeException("Size");
			if (!Arch.IsGRegisterExists(Index, Offset, Size)) throw new ApplicationException("Register does not exists");

			this.Index = Index;
			this.Offset = Offset;
		}

		public x86GRegLocation(x86Architecture Arch, int Index, int Size)
			: base(Arch, Size)
		{
			if (Index < 0 || Index >= Arch.RegCount) throw new ArgumentOutOfRangeException("Index");
			if (Size < 0 || Size > Arch.RegSize) throw new ArgumentOutOfRangeException("Size");
			this.Index = Index;
		}

		public override x86DataLocationType DataType
		{
			get
			{
				var Ret = x86DataLocationType.General;
				if (HasPart(0, 1)) Ret |= x86DataLocationType.OneByte;
				return Ret;
			}
		}

		public x86RegisterMask Mask
		{
			get { return new x86RegisterMask(Offset, Size); }
		}

		public override string ToString()
		{
			return x86Architecture.GetGRegisterName(Index, Offset, Size);
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var RegPos = Loc as x86GRegLocation;
			if (RegPos == null) return false;

			if (RegPos.Index != Index) return false;
			if (this.Size == 1 && RegPos.Size == 1)
			{
				if (Offset != RegPos.Offset) return false;
			}
			else if (Mode == x86OverlappingMode.Whole)
			{
				if (RegPos.Size != this.Size) return false;
				if (RegPos.Offset != Offset) return false;
			}

			return true;
		}

		public override x86GRegisterList GetRegs(bool AddressRegs = false)
		{
			var Ret = new x86GRegisterList(Arch.RegCount);
			Ret.SetUsed(this);
			return Ret;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			if (!HasPart(Offset, Size)) return null;

			var NewOffset = this.Offset + Offset;
			return new x86GRegLocation(Arch, Index, NewOffset, Size);
		}

		public override bool HasPart(int Offset, int Size)
		{
			if (this.Size < Offset + Size) return false;

			var NewOffset = this.Offset + Offset;
			return Arch.IsGRegisterExists(Index, NewOffset, Size);
		}

		public bool Verify(x86GRegisterList CantBe)
		{
			return !CantBe.Initialized || CantBe.IsFree(this);
		}
	}

	public abstract class x86LabelPosition : x86DataLocation
	{
		public x86LabelPosition(x86Architecture Arch)
			: base(Arch, Arch.RegSize)
		{
		}

		public override x86DataLocationType DataType
		{
			get { return x86DataLocationType.None; }
		}

		public override bool HasPart(int Offset, int Size)
		{
			return Offset == 0 && this.Size == Size;
		}
	}

	public class x86IndexedLabelLocation : x86LabelPosition
	{
		public int Label;

		public x86IndexedLabelLocation(x86Architecture Arch, int Label)
			: base(Arch)
		{
			this.Label = Label;
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var IPos = Loc as x86IndexedLabelLocation;
			if (IPos == null) return false;

			return IPos.Label == Label;
		}

		public override string ToString()
		{
			return "_" + Label;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			if (!HasPart(Offset, Size)) return null;
			return new x86IndexedLabelLocation(Arch, Label);
		}

	}

	public class x86NamedLabelPosition : x86LabelPosition
	{
		public string Label;

		public x86NamedLabelPosition(x86Architecture Arch, string Label)
			: base(Arch)
		{
			this.Label = Label;
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var NPos = Loc as x86NamedLabelPosition;
			if (NPos == null) return false;

			return NPos.Label == Label;
		}

		public override string ToString()
		{
			return Label;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			if (!HasPart(Offset, Size)) return null;
			return new x86NamedLabelPosition(Arch, Label);
		}
	}

	public class x86IndexLocation : x86MemoryLocation
	{
		public AutoAllocatedList<x86MoveStruct> Moves;

		public x86IndexLocation(x86Architecture Arch, int Offset, int Size, x86DataLocation Displacement,
			x86GRegLocation Base, x86GRegLocation Index, byte Scale = 1)
			: base(Arch, Offset, Size, Displacement, Base, Index, Scale)
		{
		}

		public x86IndexLocation(x86Architecture Arch, int Offset, int Size, x86DataLocation DisplacementOrBase,
			x86GRegLocation Index = null, byte Scale = 1)
			: base(Arch, Offset, Size, DisplacementOrBase, Index, Scale)
		{
		}

		public x86IndexLocation(x86Architecture Arch, int Offset, int Size, int RegIndex, int RegSize = -1)
			: base(Arch, Offset, Size, RegIndex, RegSize)
		{
		}

		public void AddMove(x86DataLocation Dst, x86DataLocation Src)
		{
			var StoredDataType = new x86StoredDataType(x86TypeKind.Unsigned, Dst.Size);
			Moves.Add(new x86MoveStruct(Dst, Src, new x86TemporaryData(),
				x86ExecutorType.General, StoredDataType));
		}

		public void AddMovesWithSrcs(x86DataLocation Dst, x86DataLocation Src)
		{
			var IndexSrc = Src as x86IndexLocation;
			if (IndexSrc != null)
				Moves.AddRange(IndexSrc.Moves);

			var StoredDataType = new x86StoredDataType(x86TypeKind.Unsigned, Dst.Size);
			Moves.Add(new x86MoveStruct(Dst, Src, new x86TemporaryData(), 
				x86ExecutorType.General, StoredDataType));
		}

		public override bool Add(x86MemoryLocation Location, x86GRegLocation TempGReg, byte Scale = 1)
		{
			if (TempGReg != null)
			{
				AddMovesWithSrcs(TempGReg, Location);
				Add(TempGReg, Scale);
				return true;
			}

			return false;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;

			if (!HasPart(Offset, Size)) return null;
			var Ret = new x86IndexLocation(Arch, this.Offset + Offset, 
				Size, Displacement, Base, Index, Scale);

			Ret.Moves = Moves.Copy();
			return Ret;
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var IndexLoc = Loc as x86IndexLocation;
			if (IndexLoc == null) return false;

			if (IndexLoc.Moves.Count != Moves.Count)
				return false;

			for (var i = 0; i < Moves.Count; i++)
			{
				if (!Moves[i].Src.Compare(IndexLoc.Moves[i].Src))
					return false;
			}

			return base.CompareSingle(Loc, Mode);
		}
	}

	public class x86MemoryLocation : x86SplittableLocation
	{
		public x86DataLocation Displacement;
		public x86GRegLocation Base;
		public x86GRegLocation Index;
		public byte Scale = 1;
		public int Align = int.MaxValue;

		public x86MemoryLocation(x86Architecture Arch, int Offset, int Size, x86DataLocation Displacement,
			x86GRegLocation Base, x86GRegLocation Index, byte Scale = 1)
			: base(Arch, Offset, Size)
		{
			if (Scale != 1 && Index == null) throw new ApplicationException();
			if (!(Displacement == null || Displacement is x86LabelPosition || Displacement is x86ConstLocation))
				throw new ApplicationException();

			if (Base == null && Index != null && Scale == 1)
			{
				Base = Index;
				Index = null;
			}

			this.Displacement = Displacement;
			this.Base = Base;
			this.Index = Index;
			this.Scale = Scale;
		}

		public x86MemoryLocation(x86Architecture Arch, int Offset, int Size, x86DataLocation DisplacementOrBase,
			x86GRegLocation Index = null, byte Scale = 1)
			: base(Arch, Offset, Size)
		{
			if (DisplacementOrBase != null)
			{
				if (DisplacementOrBase is x86GRegLocation) Base = DisplacementOrBase as x86GRegLocation;
				else if (DisplacementOrBase is x86LabelPosition || DisplacementOrBase is x86ConstLocation)
					Displacement = DisplacementOrBase;
				else throw new ApplicationException();
			}

			this.Index = Index;
			this.Scale = Scale;
		}

		public x86MemoryLocation(x86Architecture Arch, int Offset, int Size, int RegIndex, int RegSize = -1)
			: this(Arch, Offset, Size, new x86GRegLocation(Arch, RegIndex, RegSize == -1 ? Arch.RegSize : RegSize))
		{
		}

		public override x86DataLocationType DataType
		{
			get { return x86DataLocationType.Memory; }
		}

		public virtual x86DataLocation GetAddress()
		{
			if (AllOffset == 0)
			{
				if (Displacement != null)
				{
					if (Base == null && Index == null)
						return Displacement;
				}
				else if (Base != null)
				{
					if (Index == null && Displacement == null)
						return Base;
				}
				else if (Index != null)
				{
					if (Base == null && Displacement == null && Scale == 1)
						return Index;
				}
			}

			return null;
		}

		public void Add(x86DataLocation Position, byte Scale = 1)
		{
			if (Position is x86ConstLocation)
			{
				var ConstPos = Position as x86ConstLocation;
				Offset += (int)ConstPos.Signed * Scale;
			}
			else if (Position is x86LabelPosition)
			{
				if (Displacement != null || Scale != 1)
					throw new ApplicationException();

				Displacement = Position;
			}
			else if (Position is x86GRegLocation)
			{
				var RegPos = Position as x86GRegLocation;
				if (Base == null && Scale == 1)
				{
					Base = RegPos;
				}
				else if (Index == null)
				{
					Index = RegPos;
					this.Scale = Scale;
				}
				else
				{
					throw new ApplicationException();
				}
			}
			else
			{
				throw new ApplicationException();
			}
		}

		public virtual bool Add(x86MemoryLocation Location, x86GRegLocation TempGReg, byte Scale = 1)
		{
			return false;
		}

		public bool Add(x86DataLocation Location, x86GRegLocation TempGReg, byte Scale = 1)
		{
			var MemPosition = Location as x86MemoryLocation;
			if (MemPosition == null)
			{
				Add(Location, Scale);
				return true;
			}
			else
			{
				return Add(MemPosition, TempGReg, Scale);
			}
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var M = Loc as x86MemoryLocation;
			if (M == null) return false;

			if ((Displacement == null) != (M.Displacement == null)) return false;
			if (Displacement != null && !Displacement.Compare(M.Displacement)) return false;

			if ((Base == null) != (M.Base == null)) return false;
			if (Base != null && !Base.Compare(M.Base)) return false;

			if ((Index == null) != (M.Index == null)) return false;
			if (Index != null && (!Index.Compare(M.Index) || Scale != M.Scale)) return false;
			return base.CompareSingle(Loc, Mode);
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;

			if (!HasPart(Offset, Size)) return null;
			return new x86MemoryLocation(Arch, this.Offset + Offset, Size, 
				Displacement, Base, Index, Scale);
		}

		public override bool HasPart(int Offset, int Size)
		{
			return Offset + Size <= this.Size;
		}

		public override bool IsMemory(x86OverlappingMode Mode = x86OverlappingMode.Partial)
		{
			return true;
		}

		public override string ToString()
		{
			var Ret = (string)null;
			if (Displacement != null) Ret += Displacement.ToString();
			if (Base != null) Ret += Ret == null ? Base.ToString() : " + " + Base;
			if (Index != null) Ret += Ret == null ? Index.ToString() : " + " + Index;
			if (Scale > 1) Ret += Ret == null ? Scale.ToString() : " * " + Scale;

			var Offset = AllOffset;
			if (Offset > 0) Ret += Ret == null ? Offset.ToString() : " + " + Offset;
			else if (Offset < 0) Ret += Ret == null ? Offset.ToString() : " - " + (-Offset);
			return x86Architecture.GetTypeString(Size) + "[" + Ret + "]";
		}

		public override x86GRegisterList GetRegs(bool AddressRegs = false)
		{
			if (AddressRegs)
			{
				var Ret = new x86GRegisterList(Arch.RegCount);
				if (Base != null) Ret.SetUsed(Base);
				if (Index != null) Ret.SetUsed(Index);
				return Ret;
			}

			return new x86GRegisterList();
		}
	}

	public class x86StackLocation : x86MemoryLocation//x86IndexLocation
	{
		public FunctionScope FuncScope;
		public x86FuncScopeData Data;
		public bool FuncParam;

		public override int AllOffset
		{
			get { return base.AllOffset + StackOffset; }
		}

		public int StackOffset
		{
			get
			{
				if ((Data.Flags & x86FuncScopeFlags.StackLocationsValid) == 0)
					throw new ApplicationException("Stack locations are not valid");

				if (FuncParam & (Data.Flags & x86FuncScopeFlags.SaveParameterPointer) != 0)
					return Data.PushedRegisters + 4;

				if ((Data.Flags & x86FuncScopeFlags.SaveFramePointer) != 0)
				{
					return FuncParam ? Data.PushedRegisters + 4 : -Data.SubractedFromESP;
				}
				else
				{
					if (FuncParam) return Data.CallParameters + Data.PushedRegisters + Data.SubractedFromESP + 4;
					else return Data.UnallocatedSpace > 0 ? -Data.UnallocatedSpace : Data.CallParameters;
				}
			}
		}

		public static x86GRegLocation GetBaseRegister(x86FuncScopeData Data, bool Parameter)
		{
			if (Parameter && (Data.Flags & x86FuncScopeFlags.SaveParameterPointer) != 0)
				return Data.ParameterPointer;

			return (Data.Flags & x86FuncScopeFlags.SaveFramePointer) != 0 ?
				Data.FramePointer : Data.StackPointer;
		}

		public x86StackLocation(x86Architecture Arch, FunctionScope FuncScope, int Offset, int Size, bool FuncParam)
			: base(Arch, Offset, Size, null)
		{
			this.FuncScope = FuncScope;
			this.FuncParam = FuncParam;

			Data = FuncScope.Data.Get<x86FuncScopeData>();
			Base = GetBaseRegister(Data, FuncParam);
		}

        public void UpdateBaseRegister()
		{
			Base = GetBaseRegister(Data, FuncParam);
        }

		public override bool HasPart(int Offset, int Size)
		{
			return Offset + Size <= this.Size;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;

			if (!HasPart(Offset, Size)) return null;
			return new x86StackLocation(Arch, FuncScope, this.Offset + Offset, Size, FuncParam);
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			var StackPos = Loc as x86StackLocation;
			if (StackPos == null) return false;

			return StackPos.FuncParam == FuncParam && base.CompareSingle(Loc, Mode);
		}

        public override string ToString()
		{
			if (!Base.Compare(GetBaseRegister(Data, FuncParam)))
				throw new ApplicationException();

            return base.ToString();
        }
	}

	public class x86UnknownMemory : x86MemoryLocation
	{
		public x86UnknownMemory(x86Architecture Arch, int Offset, int Size)
			: base(Arch, Offset, Size, null)
		{
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			return false;
		}

		public override string ToString()
		{
			throw new InvalidOperationException();
		}

		public override bool HasPart(int Offset, int Size)
		{
			return this.Size >= Offset + Size;
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;
			if (!HasPart(Offset, Size)) return null;

			return new x86UnknownMemory(Arch, 0, Size);
		}
	}

	public class x86MultiLocation : x86SplittableLocation
	{
		public x86DataLocation[] Locations;

		public x86MultiLocation(x86Architecture Arch, params int[] Regs)
			: base(Arch, 0, Regs.Length * Arch.RegSize)
		{
			var RegSize = Arch.RegSize;
			Locations = new x86DataLocation[Regs.Length];
			for (var i = 0; i < Locations.Length; i++)
				Locations[i] = new x86GRegLocation(Arch, Regs[i], RegSize);
		}

		public override x86DataLocationType DataType
		{
			get { return x86DataLocationType.None; }
		}

		public bool AllPartsTypeSame
		{
			get
			{
				if (Locations.Length == 0)
					return true;

				var Type = Locations[0].DataType;
				if (Type == x86DataLocationType.None)
					return false;

				for (var i = 1; i < Locations.Length; i++)
					if (Locations[i].DataType != Type) return false;

				return true;
			}
		}

		public bool AllPartsSizeSame
		{
			get
			{
				if (Locations.Length == 0)
					return true;

				var Size = Locations[0].Size;
				for (var i = 1; i < Locations.Length; i++)
					if (Locations[i].Size != Size) return false;

				return true;
			}
		}

		public x86MultiLocation(x86Architecture Arch, int Size, x86DataLocation[] Positions)
			: base(Arch, 0, Size)
		{
			this.Locations = Positions;
		}

		public void GetPartHelper(int Offset, int Size, Action<x86DataLocation, int, int> Func)
		{
			var CurrentOffset = 0;
			var SizeLeft = Size;
			var OffsetLeft = Offset;

			for (var i = 0; i < Locations.Length; i++)
			{
				var Part = Locations[i];
				if (CurrentOffset + Part.Size > OffsetLeft)
				{
					var RetPartOffset = OffsetLeft - CurrentOffset;
					var RetPartSize = Math.Min(Part.Size - RetPartOffset, SizeLeft);
					Func(Part, RetPartOffset, RetPartSize);

					SizeLeft -= RetPartSize;
					OffsetLeft += RetPartSize;
					if (SizeLeft == 0) break;
				}

				CurrentOffset += Part.Size;
			}
		}

		public override x86DataLocation GetPart(int Offset, int Size = -1)
		{
			if (Size == -1) Size = this.Size - Offset;

			var Failed = false;
			x86DataLocation OnlyRetValue = null;
			List<x86DataLocation> RetLocations = null;

			GetPartHelper(Offset, Size, (Part, PartOffset, PartSize) =>
			{
				var RetPart = Part.GetPart(PartOffset, PartSize);
				if (RetPart == null || Failed)
				{
					Failed = true; 
					return;
				}

				if (PartSize == Size)
				{
					OnlyRetValue = RetPart;
				}
				else
				{
					if (RetLocations == null)
						RetLocations = new List<x86DataLocation>();

					RetLocations.Add(RetPart);
				}
			});

			if (Failed) return null;
			if (OnlyRetValue != null) return OnlyRetValue;
			return new x86MultiLocation(Arch, Size, RetLocations.ToArray());
		}

		public override bool HasPart(int Offset, int Size)
		{
			var Failed = false;
			GetPartHelper(Offset, Size, (Part, PartOffset, PartSize) =>
			{
				var RetPart = Part.GetPart(PartOffset, PartSize);
				if (RetPart == null || Failed)
				{
					Failed = true;
					return;
				}
			});

			return !Failed;
		}

		protected override bool CompareSingle(x86DataLocation Loc, x86OverlappingMode Mode = x86OverlappingMode.Whole)
		{
			throw new ApplicationException();
		}

		public override string ToString()
		{
			return "{" + string.Join<x86DataLocation>(", ", Locations) + "}";
		}

		public override bool IsMemory(x86OverlappingMode Mode = x86OverlappingMode.Partial)
		{
			for (var i = 0; i < Locations.Length; i++)
			{
				if (Locations[i] is x86MemoryLocation)
				{
					if (Mode == x86OverlappingMode.Partial)
						return true;
				}
				else
				{
					if (Mode == x86OverlappingMode.Whole)
						return false;
				}
			}

			return Mode == x86OverlappingMode.Whole;
		}

		public override x86GRegisterList GetRegs(bool AddressRegs = false)
		{
			var Ret = new x86GRegisterList(Arch.RegCount);
			for (var i = 0; i < Locations.Length; i++)
			{
				var Pos = Locations[i];
				if (Pos is x86GRegLocation)
				{
					Ret.SetUsed(Pos as x86GRegLocation);
				}
				else if (Pos is x86MultiLocation)
				{
					var MPos = Pos as x86MultiLocation;
					var Regs = MPos.GetRegs();
					if (Regs.Initialized) Ret.SetUsed(Regs);
				}
			}

			return Ret;
		}
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer
Hungary Hungary
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions