コード例 #1
0
        public MADOperation(VirtualRegister target, GenericOperand mleft, GenericOperand mright, GenericOperand ad) :
            base(IROpCodes.MAD, target)
        {
            if (mleft == null)
            {
                throw new ArgumentNullException("mleft");
            }
            else
            {
                MulLeftOperand = mleft;
            }

            if (mright == null)
            {
                throw new ArgumentNullException("mright");
            }
            else
            {
                MulRightOperand = mright;
            }

            if (ad == null)
            {
                throw new ArgumentNullException("addop");
            }
            else
            {
                AddOperand = ad;
            }

            Util.CheckArgumentType(Util.NumericTypes, target.DataType, "target");
            Util.CheckArgumentType(target.DataType, mleft.DataType, "mleft");
            Util.CheckArgumentType(target.DataType, mright.DataType, "mright");
            Util.CheckArgumentType(target.DataType, ad.DataType, "ad");
        }
コード例 #2
0
		protected Operation(IROpCodes opcode, VirtualRegister target)
		{
			if (target == null)
				throw new ArgumentNullException("target");
			else
				Target = target;
			
			this.opcode = opcode;
		}
コード例 #3
0
		protected JumpIfInstruction(VirtualRegister flag)
		{
			if (flag == null)
				throw new ArgumentNullException("flag");
			
			Util.CheckArgumentType(typeof(int), flag.DataType, "flag");
			
			Flag = flag;
		}
コード例 #4
0
 public LDInstruction(VirtualRegister target, VirtualRegister address) :
     base(address)
 {
     if (target == null)
     {
         throw new ArgumentNullException("target");
     }
     Util.CheckArgumentType(address.UnderlyingType.CompatibleTypes(), target.DataType, "target");
     Target = target;
 }
コード例 #5
0
        protected JumpIfInstruction(VirtualRegister flag)
        {
            if (flag == null)
            {
                throw new ArgumentNullException("flag");
            }

            Util.CheckArgumentType(typeof(int), flag.DataType, "flag");

            Flag = flag;
        }
コード例 #6
0
        private static BasicBlock InlineIR(this BasicBlock bb,
                                           Func <Subprogram, bool> permitInline,
                                           Dictionary <VirtualRegister, VirtualRegister> copyRegMap,
                                           Dictionary <Subprogram, Dictionary <VirtualRegister, VirtualRegister> > inlineRegMaps,
                                           IList <Subprogram> subprograms,
                                           Dictionary <BasicBlock, BasicBlock> basicBlockMap)
        {
            BasicBlock result;

            if (!basicBlockMap.TryGetValue(bb, out result))
            {
                VirtualRegister flag = (bb.Trailer is JumpIfInstruction) ?
                                       (bb.Trailer as JumpIfInstruction).Flag.MapOperand(copyRegMap) : null;

                ControlFlowInstruction trailer;
                switch (bb.Trailer.OpCode)
                {
                case IROpCodes.RET:
                    trailer = new RETInstruction();
                    break;

                case IROpCodes.JMP:
                    trailer = new JMPInstruction();
                    break;

                case IROpCodes.JT:
                    trailer = new JTInstruction(flag);
                    break;

                case IROpCodes.JF:
                    trailer = new JFInstruction(flag);
                    break;

                default:
                    throw new NotSupportedException();
                }

                BasicBlock backend;
                result = bb.Code.InlineIR(trailer, permitInline, copyRegMap, inlineRegMaps, subprograms, out backend);
                basicBlockMap.Add(bb, result);

                if (bb.Successor != null)
                {
                    backend.Successor = bb.Successor.InlineIR(permitInline, copyRegMap, inlineRegMaps, subprograms, basicBlockMap);
                }
                if (bb.Target != null)
                {
                    backend.Target = bb.Target.InlineIR(permitInline, copyRegMap, inlineRegMaps, subprograms, basicBlockMap);
                }
            }

            return(result);
        }
コード例 #7
0
        public UnaryOperation(IROpCodes opcode, VirtualRegister target, GenericOperand operand) :
            base(opcode, target)
        {
            if (operand == null)
            {
                throw new ArgumentNullException("operand");
            }
            else
            {
                Operand = operand;
            }

            switch (opcode)
            {
            case IROpCodes.NEG:
            case IROpCodes.ABS:
                Util.CheckArgumentType(Util.SIntTypes.Concat(Util.RealTypes), target.DataType, "target");
                goto case IROpCodes.MOV;

            case IROpCodes.NOT:
                Util.CheckArgumentType(Util.IntegralTypes, target.DataType, "target");
                goto case IROpCodes.MOV;

            case IROpCodes.SQRT:
            case IROpCodes.RSQRT:
                Util.CheckArgumentType(Util.RealTypes, target.DataType, "target");
                goto case IROpCodes.MOV;

            case IROpCodes.SIN:
            case IROpCodes.COS:
            case IROpCodes.LG2:
            case IROpCodes.EX2:
                Util.CheckArgumentType(typeof(float), target.DataType, "target");
                goto case IROpCodes.MOV;

            case IROpCodes.MOV:
                Util.CheckArgumentType(target.DataType, operand.DataType, "operand");
                break;

            case IROpCodes.CVT:
                if (!(Util.NumericTypes.Contains(operand.DataType) && Util.NumericTypes.Contains(target.DataType)) ||
                    target.DataType == operand.DataType)
                {
                    throw new InvalidCastException(string.Format("There is no conversion from {0} to {1}",
                                                                 operand.DataType.Format(), target.DataType.Format()));
                }
                break;

            default:
                throw new InvalidOperationException();
            }
        }
コード例 #8
0
        protected Operation(IROpCodes opcode, VirtualRegister target)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            else
            {
                Target = target;
            }

            this.opcode = opcode;
        }
コード例 #9
0
		public BinaryOperation(IROpCodes opcode, VirtualRegister target, GenericOperand left, GenericOperand right) :
			base(opcode, target)
		{
			if (left == null)
				throw new ArgumentNullException("left");
			else
				LeftOperand = left;

			if (right == null)
				throw new ArgumentNullException("right");
			else
				RightOperand = right;
			
			switch (opcode)
			{
			case IROpCodes.ADD:
			case IROpCodes.SUB:
			case IROpCodes.MUL:
			case IROpCodes.DIV:
			case IROpCodes.MIN:
			case IROpCodes.MAX:
				Util.CheckArgumentType(Util.NumericTypes, target.DataType, "target");
				Util.CheckArgumentType(target.DataType, left.DataType, "left");
				Util.CheckArgumentType(target.DataType, right.DataType, "right");
				break;
			case IROpCodes.REM:
				Util.CheckArgumentType(Util.IntegralTypes, target.DataType, "target");
				Util.CheckArgumentType(target.DataType, left.DataType, "left");
				Util.CheckArgumentType(target.DataType, right.DataType, "right");
				break;
			case IROpCodes.AND:
			case IROpCodes.OR:
			case IROpCodes.XOR:
				Util.CheckArgumentType(Util.IntegralTypes, target.DataType, "target");
				Util.CheckArgumentType(target.DataType, left.DataType, "left");
				Util.CheckArgumentType(target.DataType, right.DataType, "right");
				break;
			case IROpCodes.EQ:
			case IROpCodes.NE:
			case IROpCodes.GE:
			case IROpCodes.GT:
			case IROpCodes.LE:
			case IROpCodes.LT:
				Util.CheckArgumentType(typeof(int), target.DataType, "target");
				Util.CheckArgumentType(Util.NumericTypes, left.DataType, "left");
				Util.CheckArgumentType(left.DataType, right.DataType, "right");
				break;
			default:
				throw new InvalidOperationException();
			}
		}
コード例 #10
0
        public STInstruction(VirtualRegister address, VirtualRegister source) :
            base(address)
        {
            if (address.StateSpace == StateSpaces.CONSTANT)
            {
                throw new ArgumentException("Writeable state space is required", "address");
            }

            if (source == null)
            {
                throw new ArgumentNullException("value");
            }
            Util.CheckArgumentType(address.UnderlyingType.CompatibleTypes(), source.DataType, "target");
            Source = source;
        }
コード例 #11
0
 protected MemoryAccessInstruction(VirtualRegister address)
 {
     if (address == null)
     {
         throw new ArgumentNullException("address");
     }
     else if (address.StateSpace == StateSpaces.REG)
     {
         throw new ArgumentException("Pointer is required", "address");
     }
     else
     {
         Address = address;
     }
 }
コード例 #12
0
        public BranchStatement(VirtualRegister flag, IEnumerable <TreeStatement> trueBranch, IEnumerable <TreeStatement> falseBranch = null)
        {
            if (flag == null)
            {
                throw new ArgumentNullException("flag");
            }

            Util.CheckArgumentType(typeof(int), flag.DataType, "flag");

            Flag = flag;

            if (trueBranch == falseBranch)
            {
                throw new ArgumentException("Branch targets must be different", "falseBranch");
            }

            TrueBranch  = trueBranch;
            FalseBranch = falseBranch;
        }
コード例 #13
0
		public void AddInitialization(GenericOperand actual, VirtualRegister formal)
		{
			code.Add(new UnaryOperation(IROpCodes.MOV, formal, actual));
			ReleaseOperand(actual);
		}
コード例 #14
0
		public UnaryOperation(IROpCodes opcode, VirtualRegister target, GenericOperand operand) :
			base(opcode, target)
		{
			if (operand == null)
				throw new ArgumentNullException("operand");
			else
				Operand = operand;
			
			switch (opcode)
			{
			case IROpCodes.NEG:
			case IROpCodes.ABS:
				Util.CheckArgumentType(Util.SIntTypes.Concat(Util.RealTypes), target.DataType, "target");
				goto case IROpCodes.MOV;
			case IROpCodes.NOT:
				Util.CheckArgumentType(Util.IntegralTypes, target.DataType, "target");
				goto case IROpCodes.MOV;
			case IROpCodes.SQRT:
			case IROpCodes.RSQRT:
				Util.CheckArgumentType(Util.RealTypes, target.DataType, "target");
				goto case IROpCodes.MOV;
			case IROpCodes.SIN:
			case IROpCodes.COS:
			case IROpCodes.LG2:
			case IROpCodes.EX2:
				Util.CheckArgumentType(typeof(float), target.DataType, "target");
				goto case IROpCodes.MOV;
			case IROpCodes.MOV:
				Util.CheckArgumentType(target.DataType, operand.DataType, "operand");
				break;
			case IROpCodes.CVT:
				if (!(Util.NumericTypes.Contains(operand.DataType) && Util.NumericTypes.Contains(target.DataType)) ||
					target.DataType == operand.DataType)
					throw new InvalidCastException(string.Format("There is no conversion from {0} to {1}",
						operand.DataType.Format(), target.DataType.Format()));
				break;
			default:
				throw new InvalidOperationException();
			}
		}
コード例 #15
0
		private VirtualRegister CalculateAddress(VirtualRegister array, GenericOperand index)
		{
			VirtualRegister address = AllocateRegister(array.UnderlyingType, array.StateSpace);
			index = ConvertOperand(index, array.DataType);
			int elemsize = array.UnderlyingType.SizeOf();
			code.Add(elemsize == 1 ?
				new BinaryOperation(IROpCodes.ADD, address, index, array) as BasicBlockInstruction :
				new MADOperation(address, index, new ImmediateValue(
					(ValueType)Convert.ChangeType(elemsize, array.DataType)), array) as BasicBlockInstruction);
			ReleaseOperand(array);
			ReleaseOperand(index);
			return address;
		}
コード例 #16
0
		protected MemoryAccessInstruction(VirtualRegister address)
		{
			if (address == null)
				throw new ArgumentNullException("address");
			else if (address.StateSpace == StateSpaces.REG)
				throw new ArgumentException("Pointer is required", "address");
			else
				Address = address;
		}
コード例 #17
0
        public BinaryOperation(IROpCodes opcode, VirtualRegister target, GenericOperand left, GenericOperand right) :
            base(opcode, target)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            else
            {
                LeftOperand = left;
            }

            if (right == null)
            {
                throw new ArgumentNullException("right");
            }
            else
            {
                RightOperand = right;
            }

            switch (opcode)
            {
            case IROpCodes.ADD:
            case IROpCodes.SUB:
            case IROpCodes.MUL:
            case IROpCodes.DIV:
            case IROpCodes.MIN:
            case IROpCodes.MAX:
                Util.CheckArgumentType(Util.NumericTypes, target.DataType, "target");
                Util.CheckArgumentType(target.DataType, left.DataType, "left");
                Util.CheckArgumentType(target.DataType, right.DataType, "right");
                break;

            case IROpCodes.REM:
                Util.CheckArgumentType(Util.IntegralTypes, target.DataType, "target");
                Util.CheckArgumentType(target.DataType, left.DataType, "left");
                Util.CheckArgumentType(target.DataType, right.DataType, "right");
                break;

            case IROpCodes.AND:
            case IROpCodes.OR:
            case IROpCodes.XOR:
                Util.CheckArgumentType(Util.IntegralTypes, target.DataType, "target");
                Util.CheckArgumentType(target.DataType, left.DataType, "left");
                Util.CheckArgumentType(target.DataType, right.DataType, "right");
                break;

            case IROpCodes.EQ:
            case IROpCodes.NE:
            case IROpCodes.GE:
            case IROpCodes.GT:
            case IROpCodes.LE:
            case IROpCodes.LT:
                Util.CheckArgumentType(typeof(int), target.DataType, "target");
                Util.CheckArgumentType(Util.NumericTypes, left.DataType, "left");
                Util.CheckArgumentType(left.DataType, right.DataType, "right");
                break;

            default:
                throw new InvalidOperationException();
            }
        }
コード例 #18
0
		public JFInstruction(VirtualRegister flag) :
			base(flag)
		{
		}
コード例 #19
0
		private GenericOperand RetrieveOperand()
		{
			GenericOperand operand = stack.Peek().Item1.Item1;
			bool byref = stack.Peek().Item1.Item2;
			InstructionSelector parent = stack.Peek().Item2;
			stack.Pop();
			
			if (parent != this)
			{
				if (byref)
				{
					arguments.Add(operand);
					return operand;
				}
				else
				{
					VirtualRegister argument = operand as VirtualRegister;
					argument = new VirtualRegister(argument.UnderlyingType, argument.StateSpace);
					parent.AddInitialization(operand, argument);
					arguments.Add(argument);
					return argument;
				}
			}
			else
				return operand;
		}
コード例 #20
0
		public STInstruction(VirtualRegister address, VirtualRegister source) :
			base(address)
		{
			if (address.StateSpace == StateSpaces.CONSTANT)
				throw new ArgumentException("Writeable state space is required", "address");
			
			if (source == null)
				throw new ArgumentNullException("value");
			Util.CheckArgumentType(address.UnderlyingType.CompatibleTypes(), source.DataType, "target");
			Source = source;
		}
コード例 #21
0
		public LDInstruction(VirtualRegister target, VirtualRegister address) :
			base(address)
		{
			if (target == null)
				throw new ArgumentNullException("target");
			Util.CheckArgumentType(address.UnderlyingType.CompatibleTypes(), target.DataType, "target");
			Target = target;
		}
コード例 #22
0
        public CALLInstruction(Subprogram target, IList <GenericOperand> arguments)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            else if (target is Kernel)
            {
                throw new NotSupportedException("Kernels can not be called from device code");
            }
            else
            {
                Target = target;
            }

            if (arguments == null)
            {
                throw new ArgumentNullException("operands");
            }
            else if (arguments.Count != target.FormalParameters.Count)
            {
                throw new ArgumentException(string.Format("{0} has {1} formal parameters but {2} actual parameters are provided",
                                                          target.Name, target.FormalParameters.Count, arguments.Count));
            }
            else
            {
                for (int idx = 0; idx < arguments.Count; idx++)
                {
                    if (arguments[idx] == null)
                    {
                        throw new ArgumentException(string.Format("Argument {0} is null", idx), "operands");
                    }

                    FormalParameter fp = target.FormalParameters[idx];

                    if (arguments[idx] is VirtualRegister)
                    {
                        VirtualRegister vr = arguments[idx] as VirtualRegister;
                        if (vr.StateSpace != fp.StateSpace)
                        {
                            throw new ArgumentException(string.Format("Argument {0} is incompatible with {1} state space", idx,
                                                                      fp.StateSpace.ToString()), "operands");
                        }
                        if (vr.StateSpace != StateSpaces.REG)
                        {
                            if (vr.UnderlyingType != fp.UnderlyingType)
                            {
                                throw new ArgumentException(string.Format("Argument {0} has incompatible underlying type", idx), "operands");
                            }
                        }
                        else
                        {
                            if (vr.DataType != fp.DataType)
                            {
                                throw new ArgumentException(string.Format("Argument {0} has incompatible data type", idx), "operands");
                            }
                        }
                    }
                    else if (arguments[idx] is ImmediateValue)
                    {
                        ImmediateValue iv = arguments[idx] as ImmediateValue;
                        if (fp.StateSpace != StateSpaces.REG)
                        {
                            throw new ArgumentException(string.Format("Argument {0} is incompatible with {1} state space", idx,
                                                                      fp.StateSpace.ToString()), "operands");
                        }
                        if (fp.PassingStyle != PassingStyles.VAL)
                        {
                            throw new ArgumentException(string.Format("Argument {0} can be passed only by value", idx), "operands");
                        }
                        if (iv.DataType != fp.DataType)
                        {
                            throw new ArgumentException(string.Format("Argument {0} has incompatible data type", idx), "operands");
                        }
                    }
                }
            }

            this.arguments = arguments;
        }
コード例 #23
0
 public JFInstruction(VirtualRegister flag) :
     base(flag)
 {
 }
コード例 #24
0
 public static VirtualRegister MapOperand(this VirtualRegister operand,
                                          Dictionary <VirtualRegister, VirtualRegister> regmap)
 {
     return(regmap[operand]);
 }
コード例 #25
0
		public MADOperation(VirtualRegister target, GenericOperand mleft, GenericOperand mright, GenericOperand ad) :
			base(IROpCodes.MAD, target)
		{
			if (mleft == null)
				throw new ArgumentNullException("mleft");
			else
				MulLeftOperand = mleft;

			if (mright == null)
				throw new ArgumentNullException("mright");
			else
				MulRightOperand = mright;
			
			if (ad == null)
				throw new ArgumentNullException("addop");
			else
				AddOperand = ad;
			
			Util.CheckArgumentType(Util.NumericTypes, target.DataType, "target");
			Util.CheckArgumentType(target.DataType, mleft.DataType, "mleft");
			Util.CheckArgumentType(target.DataType, mright.DataType, "mright");
			Util.CheckArgumentType(target.DataType, ad.DataType, "ad");
		}
コード例 #26
0
ファイル: AMDILEmitter.cs プロジェクト: cephdon/gpudotnet
		private static string ToAMDIL(this BasicBlockInstruction bbi,
			LiteralPool literals,
			Dictionary<string, int> functions = null,
			int raw_uav_id = 11,
			int arena_uav_id = 13)
		{
			BinaryOperation bop = bbi as BinaryOperation;
			UnaryOperation uop = bbi as UnaryOperation;

			switch (bbi.OpCode)
			{
			case IROpCodes.ADD:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
				case TypeCode.UInt32:
					return string.Format(
						"iadd {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
				case TypeCode.UInt64:
					return string.Format(
						"i64add {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"add {0}, {1}, {2}",
						bop.Target.ToString(), 
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"dadd {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.SUB:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
				case TypeCode.UInt32:
					return string.Format(
						"inegate r2.x, {2}\n" +
						"iadd {0}, {1}, r2.x",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
				case TypeCode.UInt64:
					return string.Format(
						"i64negate r2.xy, {2}\n" +
						"i64add {0}, {1}, r2.xy",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"sub {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"dadd {0}, {1}, {2}_neg(xyzw)",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.MUL:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
				case TypeCode.UInt32:
					return string.Format(
						"imul {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
				case TypeCode.UInt64:
					return string.Format(
						"i64mul {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"mul_ieee {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"dmul {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.MAD:
				{
					MADOperation mad = bbi as MADOperation;
					
					switch (Type.GetTypeCode(mad.Target.DataType))
					{
					case TypeCode.Int32:
						return string.Format(
							"imad {0}, {1}, {2}, {3}",
							mad.Target.ToString(),
							mad.MulLeftOperand.ToAMDIL(literals),
							mad.MulRightOperand.ToAMDIL(literals),
							mad.AddOperand.ToAMDIL(literals)
						);
					case TypeCode.UInt32:
						return string.Format(
							"umad {0}, {1}, {2}, {3}",
							mad.Target.ToString(),
							mad.MulLeftOperand.ToAMDIL(literals),
							mad.MulRightOperand.ToAMDIL(literals),
							mad.AddOperand.ToAMDIL(literals)
						);
					case TypeCode.Int64:
					case TypeCode.UInt64:
						return string.Format(
							"i64mul r2.xy, {1}, {2}\n" +
							"i64add {0}, r2.xy, {3}",
							mad.Target.ToString(),
							mad.MulLeftOperand.ToAMDIL(literals),
							mad.MulRightOperand.ToAMDIL(literals),
							mad.AddOperand.ToAMDIL(literals)
						);
					case TypeCode.Single:
						return string.Format(
							"mad_ieee {0}, {1}, {2}, {3}",
							mad.Target.ToString(),
							mad.MulLeftOperand.ToAMDIL(literals),
							mad.MulRightOperand.ToAMDIL(literals),
							mad.AddOperand.ToAMDIL(literals)
						);
					case TypeCode.Double:
						return string.Format(
							"dmad {0}, {1}, {2}, {3}",
							mad.Target.ToString(),
							mad.MulLeftOperand.ToAMDIL(literals),
							mad.MulRightOperand.ToAMDIL(literals),
							mad.AddOperand.ToAMDIL(literals)
						);
					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				}
			case IROpCodes.DIV:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
					return string.Format(
						"ilt r2.x, {1}, {3}\n" + // compare left operand with 0, get -1 if negative or 0 otherwise
						"iadd r2.z, {1}, r2.x\n" + // r2.z = abs(left operand), see IROpCodes.ABS case
						"ixor r2.z, r2.z, r2.x\n" +
						"ilt r2.y, {2}, {3}\n" + // compare right operand with 0, get -1 if negative or 0 otherwise
						"iadd r2.w, {2}, r2.y\n" + // r2.w = abs(right operand), see IROpCodes.ABS case
						"ixor r2.w, r2.w, r2.y\n" +
						"udiv {0}, r2.z, r2.w\n" + // perform division with non-negative operands
						"ixor r2.x, r2.x, r2.y\n" + // get result sign factor (-1 if negative or 0 otherwise)
						"iadd {0}, {0}, r2.x\n" + // perform negation if needed
						"ixor {0}, {0}, r2.x",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals),
						literals[(int)0] + ".x");
				case TypeCode.UInt32:
					return string.Format(
						"udiv {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
					return string.Format(
						"i64div {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.UInt64:
					return string.Format(
						"u64div {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"div_zeroop(infinity) {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"ddiv {0}, {1}, {2}",
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.REM:
				{
					VirtualRegister tmp = new VirtualRegister(bop.Target.DataType) { Name = 
						"r3" + SwizzleMask(bop.Target.ToString())};

					return new BinaryOperation(
						IROpCodes.DIV,
						tmp,
						bop.LeftOperand,
						bop.RightOperand
					).ToAMDIL(literals) + "\n" + new BinaryOperation(
						IROpCodes.MUL,
						tmp,
						tmp,
						bop.RightOperand
					).ToAMDIL(literals) + "\n" + new BinaryOperation(
						IROpCodes.SUB,
						bop.Target,
						bop.LeftOperand,
						tmp
					).ToAMDIL(literals);
				}
			case IROpCodes.MIN:
			case IROpCodes.MAX:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
					return string.Format(
						"i{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.UInt32:
					return string.Format(
						"u{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
					return string.Format(
						"i64{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.UInt64:
					return string.Format(
						"u64{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"{0}_ieee {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"d{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.AND:
			case IROpCodes.OR:
			case IROpCodes.XOR:
				return string.Format(
					"i{0} {1}, {2}, {3}",
					bop.OpCode.ToString().ToLower(),
					bop.Target.ToString(),
					bop.LeftOperand.ToAMDIL(literals),
					bop.RightOperand.ToAMDIL(literals)
				);
			case IROpCodes.EQ:
			case IROpCodes.NE:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
				case TypeCode.UInt32:
					return string.Format(
						"i{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
				case TypeCode.UInt64:
					return string.Format(
						"i64{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"d{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.GE:
			case IROpCodes.LT:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Int32:
					return string.Format(
						"i{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.UInt32:
					return string.Format(
						"u{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
					return string.Format(
						"i64{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.UInt64:
					return string.Format(
						"u64{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"d{0} {1}, {2}, {3}",
						bbi.OpCode.ToString().ToLower(),
						bop.Target.ToString(),
						bop.LeftOperand.ToAMDIL(literals),
						bop.RightOperand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.GT:
				return new BinaryOperation(
					IROpCodes.LT,
					bop.Target,
					bop.RightOperand,
					bop.LeftOperand
				).ToAMDIL(literals);
			case IROpCodes.LE:
				return new BinaryOperation(
					IROpCodes.GE,
					bop.Target,
					bop.RightOperand,
					bop.LeftOperand
				).ToAMDIL(literals);
			case IROpCodes.NEG:
				switch (Type.GetTypeCode(uop.Target.DataType))
				{
				case TypeCode.Int32:
					return string.Format(
						"inegate {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				case TypeCode.Int64:
					return string.Format(
						"i64negate {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				case TypeCode.Single:
					return string.Format(
						"mov {0}, {1}_neg(xyzw)",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"dadd {0}, {1}_neg(xyzw), {2}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals),
						literals[(int)0] + ".xy"
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.NOT:
				return string.Format(
					"inot {0}, {1}",
					uop.Target.ToString(),
					uop.Operand.ToAMDIL(literals)
				);
			case IROpCodes.MOV:
				return string.Format(
					"mov {0}, {1}",
					uop.Target.ToString(),
					uop.Operand.ToAMDIL(literals)
				);
			case IROpCodes.ABS:
				switch (Type.GetTypeCode(uop.Target.DataType))
				{
				case TypeCode.Int32:
					return string.Format(
						"ishr r2.x, {1}, {2}\n" + // -1 if negative or 0 otherwise
						"iadd {0}, {1}, r2.x\n" + // substract 1 if negative or keep unchanged otherwise
						"ixor {0}, {0}, r2.x",    // perform a bit-wise one's complement if negative or keep unchanged otherwise
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals),
						literals[(int)31] + ".x"
					);
				case TypeCode.Int64:
					return string.Format(
						"i64shr r2.x, {1}, {2}\n" +  // -1 if negative or 0 otherwise
						"i64add {0}, {1}, r2.xx\n" + // substract 1 if negative or keep unchanged otherwise
						"ixor {0}, {0}, r2.xx",      // perform a bit-wise one's complement if negative or keep unchanged otherwise
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals),
						literals[(int)63] + ".x"
					);
				case TypeCode.Single:
					return string.Format(
						"abs {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"dadd {0}, {1}_abs, {2}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals),
						literals[(int)0] + ".xy"
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.CVT:
				switch (Type.GetTypeCode(uop.Target.DataType))
				{
				case TypeCode.Int32:
					switch (Type.GetTypeCode(uop.Operand.DataType))
					{
					case TypeCode.UInt32:
						return string.Format(
							"mov {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Int64:
					case TypeCode.UInt64:
						return string.Format(
							"mov {0}, {1}",
							uop.Target.ToString(),
							LowerPart(uop.Operand.ToAMDIL(literals))
						);
					case TypeCode.Single:
						return string.Format(
							"ftoi {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Double:
						return string.Format(
							"d2f {0}, {1}\n" +
							"ftoi {0}, {0}",
							uop.Target.ToString(), uop.Operand.ToAMDIL(literals));
					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				case TypeCode.UInt32:
					switch (Type.GetTypeCode(uop.Operand.DataType))
					{
					case TypeCode.Int32:
						return string.Format(
							"mov {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Int64:
					case TypeCode.UInt64:
						return string.Format(
							"mov {0}, {1}",
							uop.Target.ToString(),
							LowerPart(uop.Operand.ToAMDIL(literals))
						);
					case TypeCode.Single:
						return string.Format(
							"ftou {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Double:
						return string.Format(
							"d2f {0}, {1}\n" +
							"ftou {0}, {0}",
							uop.Target.ToString(), uop.Operand.ToAMDIL(literals));
					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				case TypeCode.Int64:
					switch (Type.GetTypeCode(uop.Operand.DataType))
					{
					case TypeCode.Int32:
						return string.Format(
							"ishr r2.y, {1}, {2}\n" + // -1 if negative or 0 otherwise
							"mov r2.x, {1}\n" +       // perform sign extension
							"mov {0}, r2.xy",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals),
							literals[(int)31] + ".x"
						);
					case TypeCode.UInt32:
						return string.Format(
							"mov {0}, {1}0",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.UInt64:
						return string.Format(
							"mov {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Single:

					case TypeCode.Double:

					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				case TypeCode.UInt64:
					switch (Type.GetTypeCode(uop.Operand.DataType))
					{
					case TypeCode.Int32:
						return string.Format(
							"ishr r2.y, {1}, {2}\n" + // -1 if negative or 0 otherwise
							"mov r2.x, {1}\n" + // perform sign extension
							"mov {0}, r2.xy",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals),
							literals[(int)31] + ".x"
						);
					case TypeCode.UInt32:
						return string.Format(
							"mov {0}, {1}0",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Int64:
						return string.Format(
							"mov {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Single:

					case TypeCode.Double:

					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				case TypeCode.Single:
					switch (Type.GetTypeCode(uop.Operand.DataType))
					{
					case TypeCode.Int32:
						return string.Format(
							"itof {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);							
					case TypeCode.UInt32:
						return string.Format(
							"utof {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					case TypeCode.Int64:
						// ugly, i know!!!
						return string.Format(
							"itof {0}, {1}",
							uop.Target.ToString(),
							LowerPart(uop.Operand.ToAMDIL(literals))
						);
					case TypeCode.UInt64:
						// ugly, i know!!!
						return string.Format(
							"utof {0}, {1}",
							uop.Target.ToString(),
							LowerPart(uop.Operand.ToAMDIL(literals))
						);
					case TypeCode.Double:
						return string.Format(
							"d2f {0}, {1}",
							uop.Target.ToString(),
							uop.Operand.ToAMDIL(literals)
						);
					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				case TypeCode.Double:
					switch (Type.GetTypeCode(uop.Operand.DataType))
					{
					case TypeCode.Int32:
						return string.Format(
							"itof r2.x, {1}\n" +
							"f2d {0}, r2.x",
							uop.Target.ToString(), uop.Operand.ToAMDIL(literals));
					case TypeCode.UInt32:
						return string.Format(
							"utof r2.x, {1}\n" +
							"f2d {0}, r2.x",
							uop.Target.ToString(), uop.Operand.ToAMDIL(literals));
					case TypeCode.Int64:
						// ugly, i know!!!
						return string.Format(
							"itof r2.x, {1}\n" +
							"f2d {0}, r2.x",
							uop.Target.ToString(), LowerPart(uop.Operand.ToAMDIL(literals)));
					case TypeCode.UInt64:
						// ugly, i know!!!
						return string.Format(
							"utof r2.x, {1}\n" +
							"f2d {0}, r2.x",
							uop.Target.ToString(), LowerPart(uop.Operand.ToAMDIL(literals)));
					case TypeCode.Single:
						return string.Format(
									"f2d {0}, {1}",
									uop.Target.ToString(),
									uop.Operand.ToAMDIL(literals)
						);
					default:
						throw new NotSupportedException(bop.Target.DataType.Format());
					}
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.LD:
				{
					LDInstruction op = bbi as LDInstruction;
					switch (op.Address.StateSpace)
					{
					case StateSpaces.GLOBAL:
						switch (Type.GetTypeCode(op.Address.UnderlyingType))
						{
						case TypeCode.Boolean:
						case TypeCode.SByte:
						case TypeCode.Byte:
							return string.Format(
								"uav_arena_load_id({3})_size(byte)_cached {0}, {1}\n" +
								"ishl {0}, {0}, {2}\n" +
								"ishr {0}, {0}, {2}",
								op.Target.ToString(),
								op.Address.ToString(),
								literals[(int)24] + ".x",
								arena_uav_id
							);
						case TypeCode.Int16:
						case TypeCode.UInt16:
							return string.Format(
								"uav_arena_load_id({3})_size(short)_cached {0}, {1}\n" +
								"ishl {0}, {0}, {2}\n" +
								"ishr {0}, {0}, {2}",
								op.Target.ToString(),
								op.Address.ToString(),
								literals[(int)16] + ".x",
								arena_uav_id
							);
						case TypeCode.Int32:
						case TypeCode.UInt32:
						case TypeCode.Single:
							return string.Format(
								"uav_raw_load_id({2})_cached {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString(),
								raw_uav_id
							);				
						case TypeCode.Int64:
						case TypeCode.UInt64:
						case TypeCode.Double:
							return string.Format(
								"uav_raw_load_id({2})_cached {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString(),
								raw_uav_id
							);				
						default:
							throw new NotSupportedException(bop.Target.DataType.Format());
						}
					case StateSpaces.SHARED:
						switch (Type.GetTypeCode(op.Address.UnderlyingType))
						{
						case TypeCode.Boolean:
						case TypeCode.SByte:
							return string.Format(
								"lds_load_byte_id(1) {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString()
							);
						case TypeCode.Byte:
							return string.Format(
								"lds_load_ubyte_id(1) {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString()
							);
						case TypeCode.Int16:
							return string.Format(
								"lds_load_short_id(1) {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString()
							);
						case TypeCode.UInt16:
							return string.Format(
								"lds_load_ushort_id(1) {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString()
							);
						case TypeCode.Int32:
						case TypeCode.UInt32:
						case TypeCode.Single:
							return string.Format(
								"lds_load_id(1) {0}, {1}",
								op.Target.ToString(),
								op.Address.ToString()
							);				
						case TypeCode.Int64:
						case TypeCode.UInt64:
						case TypeCode.Double:
							return string.Format(
								"lds_load_vec_id(1) {0}, {1}, {1}",
								op.Target.ToString(),
								op.Address.ToString()
							);
						default:
							throw new NotSupportedException(bop.Target.DataType.Format());
						}
					case StateSpaces.CONSTANT:
					default:
						throw new NotImplementedException();
					}
				}
			case IROpCodes.ST:
				{
					STInstruction op = bbi as STInstruction;
					switch (op.Address.StateSpace)
					{
					case StateSpaces.GLOBAL:
						switch (Type.GetTypeCode(op.Address.UnderlyingType))
						{
						case TypeCode.Boolean:
						case TypeCode.SByte:
						case TypeCode.Byte:
							return string.Format(
								"iand {1}, {1}, {3}\n" +
								"uav_arena_store_id({2})_size(byte) {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString(),
								arena_uav_id,
								literals[(int)255]
							);
						case TypeCode.Int16:
						case TypeCode.UInt16:
							return string.Format(
								"iand {1}, {1}, {3}\n" +
								"uav_arena_store_id({2})_size(short) {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString(),
								arena_uav_id,
								literals[(int)65535]
							);
						case TypeCode.Int32:
						case TypeCode.UInt32:
						case TypeCode.Single:
							return string.Format(
								"uav_raw_store_id({2}) mem0.x, {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString(),
								raw_uav_id
							);
						case TypeCode.Int64:
						case TypeCode.UInt64:
						case TypeCode.Double:
							return string.Format(
								"uav_raw_store_id({2}) mem0.xy, {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString(),
								raw_uav_id
							);
						default:
							throw new NotSupportedException(bop.Target.DataType.Format());
						}
					case StateSpaces.SHARED:
						switch (Type.GetTypeCode(op.Address.UnderlyingType))
						{
						case TypeCode.Boolean:
						case TypeCode.SByte:
						case TypeCode.Byte:
							return string.Format(
								"lds_store_byte_id(1) {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString()
							);
						case TypeCode.Int16:
						case TypeCode.UInt16:
							return string.Format(
								"lds_store_short_id(1) {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString()
							);
						case TypeCode.Int32:
						case TypeCode.UInt32:
						case TypeCode.Single:
							return string.Format(
								"lds_store_id(1) {0}, {1}",
								op.Address.ToString(),
								op.Source.ToString()
							);				
						case TypeCode.Int64:
						case TypeCode.UInt64:
						case TypeCode.Double:
							return string.Format(
								"lds_store_vec_id(1) mem0.xy, {0}, {1}, {1}",
								op.Address.ToString(),
								op.Source.ToString()
							);
						default:
							throw new NotSupportedException(bop.Target.DataType.Format());
						}
					case StateSpaces.CONSTANT:
					default:
						throw new NotImplementedException();
					}
				}
			case IROpCodes.SYNC:
				return "fence_threads_lds_memory";
			case IROpCodes.SQRT:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Single:
					return string.Format(
						"sqrt_vec {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"dsqrt {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.RSQRT:
				switch (Type.GetTypeCode(bop.Target.DataType))
				{
				case TypeCode.Single:
					return string.Format(
						"rsq_vec {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				case TypeCode.Double:
					return string.Format(
						"drsq_zeroop(infinity) {0}, {1}",
						uop.Target.ToString(),
						uop.Operand.ToAMDIL(literals)
					);
				default:
					throw new NotSupportedException(bop.Target.DataType.Format());
				}
			case IROpCodes.SIN:
				return string.Format(
					"sin_vec {0}, {1}",
					uop.Target.ToString(),
					uop.Operand.ToAMDIL(literals)
				);
			case IROpCodes.COS:
				return string.Format(
					"cos_vec {0}, {1}",
					uop.Target.ToString(),
					uop.Operand.ToAMDIL(literals)
				);
			case IROpCodes.LG2:
				return string.Format(
					"log_vec {0}, {1}",
					uop.Target.ToString(),
					uop.Operand.ToAMDIL(literals)
				);
			case IROpCodes.EX2:
				return string.Format(
					"exp_vec {0}, {1}",
					uop.Target.ToString(),
					uop.Operand.ToAMDIL(literals)
				);
			case IROpCodes.CALL:
				{
					CALLInstruction call = bbi as CALLInstruction;
				
					IEnumerable<KeyValuePair<FormalParameter, GenericOperand>> argmap = call.Target.FormalParameters.Zip(
						call.Arguments,
						(fp, ap) => new KeyValuePair<FormalParameter, GenericOperand>(fp, ap)
					);
								
					return string.Join(
						"\n",
						from kvp in argmap where kvp.Key.PassingStyle != PassingStyles.OUT select string.Format(
						"mov {0}, {1}",
						kvp.Key,
						kvp.Value
					)
					) + "\n" + string.Format(
						"call {0}",
						functions[call.Target.Name]
					) + "\n" + string.Join(
						"\n",
						from kvp in argmap where kvp.Key.PassingStyle != PassingStyles.VAL select string.Format(
						"mov {1}, {0}",
						kvp.Key,
						kvp.Value
					)
					);
				}
			default:
				throw new NotSupportedException(bbi.OpCode.ToString());
			}
		}
コード例 #27
0
		public BranchStatement(VirtualRegister flag, IEnumerable<TreeStatement> trueBranch, IEnumerable<TreeStatement> falseBranch = null)
		{
			if (flag == null)
				throw new ArgumentNullException("flag");
			
			Util.CheckArgumentType(typeof(int), flag.DataType, "flag");
			
			Flag = flag;
			
			if (trueBranch == falseBranch)
				throw new ArgumentException("Branch targets must be different", "falseBranch");
			
			TrueBranch = trueBranch;
			FalseBranch = falseBranch;
		}
コード例 #28
0
        private static BasicBlock InlineIR(this CALLInstruction call,
                                           IList <BasicBlockInstruction> preamble,
                                           BasicBlock backend,
                                           Dictionary <Subprogram, Dictionary <VirtualRegister, VirtualRegister> > inlineRegMaps)
        {
            Dictionary <VirtualRegister, VirtualRegister> inlineRegMap;

            if (!inlineRegMaps.TryGetValue(call.Target, out inlineRegMap))
            {
                inlineRegMap = call.Target.LocalVariables.Select(lv =>
                                                                 new KeyValuePair <VirtualRegister, VirtualRegister>(lv, new VirtualRegister(lv.UnderlyingType, lv.StateSpace))).
                               ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                inlineRegMaps.Add(call.Target, inlineRegMap);
            }
            inlineRegMap = inlineRegMap.Concat(call.Target.FormalParameters.Zip(call.Arguments,
                                                                                (formal, actual) => new KeyValuePair <VirtualRegister, VirtualRegister>(formal,
                                                                                                                                                        (actual is VirtualRegister) ? (actual as VirtualRegister) :
                                                                                                                                                        (formal.StateSpace != StateSpaces.REG) ? new VirtualRegister(formal.UnderlyingType, formal.StateSpace) :
                                                                                                                                                        new VirtualRegister(formal.DataType)))).
                           ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            Dictionary <BasicBlock, BasicBlock> cfgmap = call.Target.GetBasicBlocks().Select(bb =>
            {
                VirtualRegister flag = (bb.Trailer is JumpIfInstruction) ?
                                       (bb.Trailer as JumpIfInstruction).Flag.MapOperand(inlineRegMap) : null;

                ControlFlowInstruction trailer;

                switch (bb.Trailer.OpCode)
                {
                case IROpCodes.RET:
                    trailer = new JMPInstruction()
                    {
                        Target = backend
                    };
                    break;

                case IROpCodes.JMP:
                    trailer = new JMPInstruction();
                    break;

                case IROpCodes.JT:
                    trailer = new JTInstruction(flag);
                    break;

                case IROpCodes.JF:
                    trailer = new JFInstruction(flag);
                    break;

                default:
                    throw new NotSupportedException();
                }

                return(new KeyValuePair <BasicBlock, BasicBlock>(bb,
                                                                 new BasicBlock(bb.Code.Select(bbi => bbi.MapInstruction(inlineRegMap)).ToList(), trailer)));
            }).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            foreach (KeyValuePair <BasicBlock, BasicBlock> bbmap in cfgmap)
            {
                if (bbmap.Key.Successor != null)
                {
                    bbmap.Value.Successor = cfgmap[bbmap.Key.Successor];
                }
                if (bbmap.Key.Target != null)
                {
                    bbmap.Value.Target = cfgmap[bbmap.Key.Target];
                }
            }

            BasicBlock root = cfgmap[call.Target.CFGRoot];

            return(new BasicBlock(preamble.Concat(root.Code).ToList(), root.Trailer));
        }
コード例 #29
0
		private void PushByVal(VirtualRegister operand)
		{
			stack.Push(new Tuple<Tuple<GenericOperand, bool>, InstructionSelector>(
				new Tuple<GenericOperand, bool>(operand, false), this));
		}