/// <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);
 }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        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;
        }
Beispiel #8
0
 /// <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);
            }
        }
Beispiel #11
0
 /// <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;
 }
Beispiel #12
0
 /// <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);
 }
Beispiel #21
0
 /// <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);
 }
Beispiel #23
0
        /// <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);
            }
        }