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"); }
protected Operation(IROpCodes opcode, VirtualRegister target) { if (target == null) throw new ArgumentNullException("target"); else Target = target; this.opcode = opcode; }
protected JumpIfInstruction(VirtualRegister flag) { if (flag == null) throw new ArgumentNullException("flag"); Util.CheckArgumentType(typeof(int), flag.DataType, "flag"); Flag = flag; }
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; }
protected JumpIfInstruction(VirtualRegister flag) { if (flag == null) { throw new ArgumentNullException("flag"); } Util.CheckArgumentType(typeof(int), flag.DataType, "flag"); Flag = flag; }
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); }
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(); } }
protected Operation(IROpCodes opcode, VirtualRegister target) { if (target == null) { throw new ArgumentNullException("target"); } else { Target = target; } this.opcode = opcode; }
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(); } }
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; }
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; } }
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; }
public void AddInitialization(GenericOperand actual, VirtualRegister formal) { code.Add(new UnaryOperation(IROpCodes.MOV, formal, actual)); ReleaseOperand(actual); }
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(); } }
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; }
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; }
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(); } }
public JFInstruction(VirtualRegister flag) : base(flag) { }
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; }
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; }
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; }
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; }
public static VirtualRegister MapOperand(this VirtualRegister operand, Dictionary <VirtualRegister, VirtualRegister> regmap) { return(regmap[operand]); }
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"); }
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()); } }
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; }
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)); }
private void PushByVal(VirtualRegister operand) { stack.Push(new Tuple<Tuple<GenericOperand, bool>, InstructionSelector>( new Tuple<GenericOperand, bool>(operand, false), this)); }