/// <summary> /// Determines whether the specified operand is 32 bits. /// </summary> /// <param name="operand">The operand.</param> /// <returns></returns> protected static bool Is32Bit(Operand operand) { return (operand.Type.Type == CilElementType.U4) || (operand.Type.Type == CilElementType.I4) || IsPointer(operand) || IsObject(operand); }
/// <summary> /// Compares with the given operand for equality. /// </summary> /// <param name="other">The other operand to compare with.</param> /// <returns> /// The return value is true if the operands are equal; false if not. /// </returns> public override bool Equals(Operand other) { if (!(other is StringOperand)) return false; var stringOp = other as StringOperand; return String.Equals(stringOp.String); }
/// <summary> /// Determines whether [contains] [the specified CTX]. /// </summary> /// <param name="ctx">The context.</param> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if [contains] [the specified CTX]; otherwise, <c>false</c>. /// </returns> public static bool Contains(Context ctx, Operand operand) { PhiData phiData = ctx.Other as PhiData; if (phiData == null) return false; List<Operand> operands = phiData.Operands as List<Operand>; return operands.Contains(operand); }
/// <summary> /// Adds the value. /// </summary> /// <param name="ctx">The context.</param> /// <param name="edge">The edge.</param> /// <param name="op">The op.</param> public static void AddValue(Context ctx, BasicBlock edge, Operand op) { PhiData phiData = ctx.Other as PhiData; if (phiData == null) { phiData = new PhiData(); ctx.Other = phiData; } List<BasicBlock> blocks = phiData.Blocks as List<BasicBlock>; Debug.Assert(blocks.Count < 255, @"Maximum number of operands in PHI exceeded."); blocks.Add(edge); phiData.Operands.Add(op); }
/// <summary> /// Inserts the copy statement. /// </summary> /// <param name="predecessor">The predecessor.</param> /// <param name="result">The result.</param> /// <param name="operand">The operand.</param> private void InsertCopyStatement(BasicBlock predecessor, Operand result, Operand operand) { var context = new Context(instructionSet, predecessor); while (!context.EndOfInstruction && IsBranchInstruction(context)) context.GotoNext(); if (context.Index != -1) context = context.InsertBefore(); var source = operand is SsaOperand ? (operand as SsaOperand).Operand : operand; var destination = result is SsaOperand ? (result as SsaOperand).Operand : result; Debug.Assert(!(source is SsaOperand)); Debug.Assert(!(destination is SsaOperand)); if (destination != source) context.SetInstruction(IR.IRInstruction.Move, destination, source); }
public SsaOperand CreateSsaOperand(Operand operand, int version) { SsaOperand[] ssaArray; SsaOperand ssaOperand; if (!ssaOperands.TryGetValue(operand, out ssaArray)) { ssaArray = new SsaOperand[Math.Max(4, version + 1)]; ssaOperand = new SsaOperand(operand, version); ssaArray[version] = ssaOperand; ssaOperands.Add(operand, ssaArray); } else { if (version >= ssaArray.Length) { ssaOperand = new SsaOperand(operand, version); SsaOperand[] newSsaArray = new SsaOperand[ssaArray.Length * ssaArray.Length]; ssaArray.CopyTo(newSsaArray, 0); newSsaArray[version] = ssaOperand; ssaOperands.Remove(operand); ssaOperands.Add(operand, newSsaArray); } else { ssaOperand = ssaArray[version]; if (ssaOperand == null) { ssaOperand = new SsaOperand(operand, version); ssaArray[version] = ssaOperand; } } } return ssaOperand; }
/// <summary> /// Inserts the phi instruction. /// </summary> /// <param name="block">The block.</param> /// <param name="variable">The variable.</param> private void InsertPhiInstruction(BasicBlock block, Operand variable) { var context = new Context(instructionSet, block).InsertBefore(); context.SetInstruction(IRInstruction.Phi, variable); for (var i = 0; i < block.PreviousBlocks.Count; ++i) context.SetOperand(i, variable); context.OperandCount = (byte)block.PreviousBlocks.Count; }
/// <summary> /// Compares with the given operand for equality. /// </summary> /// <param name="other">The other operand to compare with.</param> /// <returns>The return value is true if the operands are equal; false if not.</returns> public override bool Equals(Operand other) { RegisterOperand rop = other as RegisterOperand; return (null != rop && ReferenceEquals(rop.Register, Register)); }
/// <summary> /// Adds to assignments. /// </summary> /// <param name="operand">The operand.</param> /// <param name="block">The block.</param> private void AddToAssignments(Operand operand, BasicBlock block) { List<BasicBlock> blocks; if (!assignments.TryGetValue(operand, out blocks)) { blocks = new List<BasicBlock>(); assignments.Add(operand, blocks); } blocks.AddIfNew(block); }
/// <summary> /// Processes a method call instruction. /// </summary> /// <param name="context">The transformation context.</param> /// <param name="destinationOperand">The operand, which holds the call destination.</param> /// <param name="resultOperand"></param> /// <param name="operands"></param> private void ProcessInvokeInstruction(Context context, Operand destinationOperand, Operand resultOperand, List<Operand> operands) { context.SetInstruction(IRInstruction.Call, (byte)(operands.Count + 1), (byte)(resultOperand == null ? 0 : 1)); if (resultOperand != null) context.SetResult(resultOperand); int operandIndex = 0; context.SetOperand(operandIndex++, destinationOperand); foreach (Operand op in operands) { context.SetOperand(operandIndex++, op); } }
/// <summary> /// Initializes a new instance of the <see cref="AEBinExp"/> struct. /// </summary> /// <param name="pos">The pos.</param> /// <param name="op1">The op1.</param> /// <param name="opr">The opr.</param> /// <param name="op2">The op2.</param> /// <param name="var">The var.</param> public AEBinExp(int pos, Operand op1, Operation opr, Operand op2, Operand var) { Position = pos; Operand1 = op1; Operator = opr; Operand2 = op2; Var = var; }
/// <summary> /// Gets the base operand. /// </summary> /// <param name="operand">The operand.</param> /// <returns></returns> private Operand GetBaseOperand(Operand operand) { if (operand is SsaOperand) return (operand as SsaOperand).Operand; else return operand; }
/// <summary> /// Determines whether the specified operand is char. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if the specified operand is char; otherwise, <c>false</c>. /// </returns> private static bool IsChar(Operand operand) { return (operand.Type.Type == CilElementType.Char || IsUShort(operand)); }
/// <summary> /// Determines whether the specified operand is signed. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if the specified operand is signed; otherwise, <c>false</c>. /// </returns> protected static bool IsSigned(Operand operand) { return IsSByte(operand) || IsSShort(operand) || IsInt(operand) || IsPointer(operand); }
/// <summary> /// Initializes a new instance of <see cref="TwoOperandInstruction"/>. /// </summary> /// <param name="op">The unary operand of this instruction.</param> public OneOperandInstruction(Operand op) : base(1, 0) { }
/// <summary> /// Determines if a store is silently truncating the value. /// </summary> /// <param name="dest">The destination operand.</param> /// <param name="source">The source operand.</param> /// <returns>True if the store is truncating, otherwise false.</returns> private static bool IsTruncating(Operand dest, Operand source) { CilElementType cetDest = dest.Type.Type; CilElementType cetSource = source.Type.Type; if (cetDest == CilElementType.I4 || cetDest == CilElementType.U4) { return (cetSource == CilElementType.I8 || cetSource == CilElementType.U8); } if (cetDest == CilElementType.I2 || cetDest == CilElementType.U2 || cetDest == CilElementType.Char) { return (cetSource == CilElementType.I8 || cetSource == CilElementType.U8 || cetSource == CilElementType.I4 || cetSource == CilElementType.U4); } if (cetDest == CilElementType.I1 || cetDest == CilElementType.U1) { return (cetSource == CilElementType.I8 || cetSource == CilElementType.U8 || cetSource == CilElementType.I4 || cetSource == CilElementType.U4 || cetSource == CilElementType.I2 || cetSource == CilElementType.U2 || cetSource == CilElementType.U2); } return false; }
private static bool IsUnsigned(Operand operand) { CilElementType type = operand.Type.Type; return type == CilElementType.U || type == CilElementType.U1 || type == CilElementType.U2 || type == CilElementType.U4 || type == CilElementType.U8; }
/// <summary> /// Determines whether the specified operand is unsigned. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if the specified operand is unsigned; otherwise, <c>false</c>. /// </returns> protected static bool IsUnsigned(Operand operand) { return IsUByte(operand) || IsUShort(operand) || IsUInt(operand) || IsChar(operand); }
/// <summary> /// Compares with the given operand for equality. /// </summary> /// <param name="other">The other operand to compare with.</param> /// <returns>The return value is true if the operands are equal; false if not.</returns> public override bool Equals(Operand other) { StackOperand sop = other as StackOperand; return (sop != null && sop.Type == this.Type && sop.Offset == this.Offset && sop.Base == this.Base && sop.Version == this.Version); }
/// <summary> /// Determines whether the specified operand is int. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if the specified operand is int; otherwise, <c>false</c>. /// </returns> private static bool IsInt(Operand operand) { return (operand.Type.Type == CilElementType.I4); }
/// <summary> /// Compares with the given operand for equality. /// </summary> /// <param name="other">The other operand to compare with.</param> /// <returns>The return value is true if the operands are equal; false if not.</returns> public override bool Equals(Operand other) { MemoryOperand mop = other as MemoryOperand; return (null != mop && mop.Type == Type && mop.Offset == Offset && mop.Base == Base); }
/// <summary> /// Determines whether [is U short] [the specified operand]. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if [is U short] [the specified operand]; otherwise, <c>false</c>. /// </returns> private static bool IsUShort(Operand operand) { return (operand.Type.Type == CilElementType.U2); }
/// <summary> /// Adds the context result to work list. /// </summary> /// <param name="operand">The operand.</param> void AddOperandUsageToWorkList(Operand operand) { foreach (int index in operand.Uses) { AddToWorkList(index); } foreach (int index in operand.Definitions) { AddToWorkList(index); } }
private Operand LoadArrayBaseAddress(Context context, SZArraySigType arraySignatureType, Operand arrayOperand) { Operand arrayAddress = methodCompiler.CreateVirtualRegister(new PtrSigType(arraySignatureType.ElementType)); Operand fixedOffset = new ConstantOperand(BuiltInSigType.Int32, 12); context.SetInstruction(IRInstruction.AddS, arrayAddress, arrayOperand, fixedOffset); return arrayAddress; }
/// <summary> /// Determines if the load should sign extend the given source operand. /// </summary> /// <param name="source">The source operand to determine sign extension for.</param> /// <returns>True if the given operand should be loaded with its sign extended.</returns> private static bool IsZeroExtending(Operand source) { return MustZeroExtendOnLoad(source.Type.Type); }
/// <summary> /// Determines whether the specified operand is byte. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// <c>true</c> if the specified operand is byte; otherwise, <c>false</c>. /// </returns> private static bool IsByte(Operand operand) { return IsSByte(operand) || IsUByte(operand); }
/// <summary> /// Loads the signed integer. /// </summary> /// <param name="operand">The operand.</param> /// <returns></returns> private int LoadSignedInteger(Operand operand) { var cop = operand as ConstantOperand; if (cop.Value is int) return (int)(operand as ConstantOperand).Value; if (cop.Value is short) return (int)(short)(operand as ConstantOperand).Value; if (cop.Value is sbyte) return (int)(sbyte)(operand as ConstantOperand).Value; return 0; }
private Operand CalculateArrayElementOffset(Context context, SZArraySigType arraySignatureType, Operand arrayIndexOperand) { int elementSizeInBytes = 0, alignment = 0; architecture.GetTypeRequirements(arraySignatureType.ElementType, out elementSizeInBytes, out alignment); // // The sequence we're emitting is: // // offset = arrayIndexOperand * elementSize // temp = offset + 12 // result = *(arrayOperand * temp) // // The array data starts at offset 12 from the array object itself. The 12 is a hardcoded assumption // of x86, which might change for other platforms. We need to refactor this into some helper classes. // Operand elementOffset = methodCompiler.CreateVirtualRegister(BuiltInSigType.Int32); Operand elementSizeOperand = new ConstantOperand(BuiltInSigType.Int32, elementSizeInBytes); context.AppendInstruction(IRInstruction.MulS, elementOffset, arrayIndexOperand, elementSizeOperand); return elementOffset; }
/// <summary> /// Compares with the given operand for equality. /// </summary> /// <param name="other">The other operand to compare with.</param> /// <returns>The return value is true if the operands are equal; false if not.</returns> public override bool Equals(Operand other) { VirtualRegisterOperand vop = other as VirtualRegisterOperand; return (null != vop && (vop.index == this.index)); }
private void CheckAndConvertInstruction(Context context, Operand destinationOperand, Operand sourceOperand) { ConvType ctDest = ConvTypeFromCilType(destinationOperand.Type.Type); ConvType ctSrc = ConvTypeFromCilType(sourceOperand.Type.Type); BaseIRInstruction type = s_convTable[(int)ctDest][(int)ctSrc]; if (type == null) throw new NotSupportedException(); uint mask = 0xFFFFFFFF; IInstruction instruction = ComputeExtensionTypeAndMask(ctDest, ref mask); if (type == IRInstruction.LogicalAnd && mask != 0) { if (sourceOperand.Type.Type == CilElementType.I8 || sourceOperand.Type.Type == CilElementType.U8) { context.SetInstruction(IRInstruction.Move, destinationOperand, sourceOperand); context.AppendInstruction(type, destinationOperand, sourceOperand, new ConstantOperand(BuiltInSigType.UInt32, mask)); } else { context.SetInstruction(type, destinationOperand, sourceOperand, new ConstantOperand(BuiltInSigType.UInt32, mask)); } } else { context.SetInstruction(type, destinationOperand, sourceOperand); } }