InsertBefore() 공개 메소드

Inserts an instruction before the current instruction.
public InsertBefore ( ) : Context
리턴 Context
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Cmp"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void Cmp(Context context)
        {
            Operand left = context.Operand1;
            Operand right = context.Operand2;

            if (left.IsConstant)
            {
                Operand ecx = AllocateVirtualRegister(left.Type);
                Context before = context.InsertBefore();

                before.AppendInstruction(X86.Mov, ecx, left);
                context.Operand1 = ecx;
            }

            if (right.IsConstant && (left.IsChar || left.IsShort || left.IsByte))
            {
                Operand edx = AllocateVirtualRegister(TypeSystem.BuiltIn.I4);
                Context before = context.InsertBefore();

                if (left.IsSigned)
                {
                    before.AppendInstruction(X86.Movsx, edx, left);
                }
                else
                {
                    before.AppendInstruction(X86.Movzx, edx, left);
                }
                context.Operand1 = edx;
            }
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Cmp"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Cmp(Context context)
        {
            Operand left = context.Operand1;
            Operand right = context.Operand2;

            if (left.IsConstant)
            {
                Operand v1 = AllocateVirtualRegister(left.Type);
                Context before = context.InsertBefore();

                before.AppendInstruction(X86.Mov, v1, left);
                context.Operand1 = v1;
            }

            if (right.IsConstant && (left.IsChar || left.IsShort || left.IsByte))
            {
                Operand v2 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4);
                InstructionSize size = left.IsByte ? InstructionSize.Size8 : InstructionSize.Size16;

                if (left.IsSigned)
                {
                    context.InsertBefore().AppendInstruction(X86.Movsx, size, v2, left);
                }
                else
                {
                    context.InsertBefore().AppendInstruction(X86.Movzx, size, v2, left);
                }

                context.Operand1 = v2;
            }
        }
        /// <summary>
        /// Converts the given instruction from three address format to a two address format.
        /// </summary>
        /// <param name="ctx">The conversion context.</param>
        private static void ThreeTwoAddressConversion(Context ctx)
        {
            if (!(ctx.Instruction is BaseIRInstruction))
                return;

            if (ctx.Instruction is IntegerCompare
                || ctx.Instruction is FloatCompare
                || ctx.Instruction is Load
                || ctx.Instruction is Store
                || ctx.Instruction is Call
                || ctx.Instruction is ZeroExtendedMove
                || ctx.Instruction is SignExtendedMove)
                return;

            Operand result = ctx.Result;
            Operand op1 = ctx.Operand1;
            Operand op2 = ctx.Operand2;

            // Create registers for different data types
            RegisterOperand eax = new RegisterOperand(op1.Type, op1.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX);
            RegisterOperand storeOperand = new RegisterOperand(result.Type, result.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX);

            ctx.Result = storeOperand;
            ctx.Operand1 = op2;
            ctx.Operand2 = null;
            ctx.OperandCount = 1;

            if (op1.StackType != StackTypeCode.F)
            {
                if (IsSigned(op1) && !(op1 is ConstantOperand))
                    ctx.InsertBefore().SetInstruction(IRInstruction.SignExtendedMove, eax, op1);
                else if (IsUnsigned(op1) && !(op1 is ConstantOperand))
                    ctx.InsertBefore().SetInstruction(IRInstruction.ZeroExtendedMove, eax, op1);
                else
                    ctx.InsertBefore().SetInstruction(X86.Mov, eax, op1);
            }
            else
            {
                if (op1.Type.Type == CilElementType.R4)
                {
                    if (op1 is ConstantOperand)
                    {
                        Context before = ctx.InsertBefore();
                        before.SetInstruction(X86.Mov, eax, op1);
                        before.AppendInstruction(X86.Cvtss2sd, eax, eax);
                    }
                    else
                    {
                        ctx.InsertBefore().SetInstruction(X86.Cvtss2sd, eax, op1);
                    }
                }
                else
                {
                    ctx.InsertBefore().SetInstruction(X86.Mov, eax, op1);
                }
            }

            ctx.AppendInstruction(X86.Mov, result, eax);
        }
        private Operand InsertLoadBeforeInstruction(Context context, string symbolName, SigType type)
        {
            Context before = context.InsertBefore();
            Operand result = this.methodCompiler.CreateTemporary(type);
            Operand op = new SymbolOperand(type, symbolName);

            before.SetInstruction(Instruction.Get(OpCode.Ldc_i4), result, op);

            return result;
        }
예제 #5
0
        private void LoadFirstOperandIntoRegister(Context context)
        {
            // load into a register
            Operand operand = context.Operand1;

            Operand register = AllocateVirtualRegister(operand.Type);
            context.Operand1 = register;

            context.InsertBefore().SetInstruction(GetMove(register, operand), register, operand);
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.In"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public void In(Context context)
        {
            var size = context.Size;

            if (size == InstructionSize.Size32)
                return;

            Debug.Assert(context.Result.Register == GeneralPurposeRegister.EAX);

            // NOTE: Other option is to use Movzx after IN instruction
            context.InsertBefore().SetInstruction(X86.Mov, context.Result, ConstantZero);
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Cmp"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Cmp(Context context)
        {
            Operand left = context.Operand1;

            if (left.IsConstant)
            {
                Operand v1 = AllocateVirtualRegister(left.Type);

                context.InsertBefore().AppendInstruction(X86.Mov, v1, left);
                context.Operand1 = v1;
            }
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.In"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void In(Context context)
        {
            var size = context.Size;

            if (size == InstructionSize.Size32)
                return;

            Debug.Assert(context.Result.Register == GeneralPurposeRegister.EAX);

            // NOTE: Other option is to use Movzx after IN instruction
            context.InsertBefore().SetInstruction(X86.Mov, context.Result, Operand.CreateConstant(TypeSystem, 0));
        }
        public void In(Context context)
        {
            var size = context.Size;

            // Mov can not use ESI or EDI registers for 8/16bit values
            if (!(size == InstructionSize.Size16 || size == InstructionSize.Size8))
                return;

            Debug.Assert(context.Result.Register == GeneralPurposeRegister.EAX);

            // NOTE: Other option is to use Movzx after IN instruction
            context.InsertBefore().SetInstruction(X86.Mov, context.Result, ConstantZero);
        }
예제 #10
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(this.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));

            context.SetInstruction(IR.Instruction.MoveInstruction, destination, source);
        }
예제 #11
0
        /// <summary>
        /// Converts the given instruction from three address format to a two address format.
        /// </summary>
        /// <param name="context">The conversion context.</param>
        private void ThreeTwoAddressConversion(Context context)
        {
            if (!(context.Instruction is X86Instruction))
                return;

            if (!(context.OperandCount >= 1 && context.ResultCount >= 1 && context.Result != context.Operand1))
                return;

            Operand result = context.Result;
            Operand operand1 = context.Operand1;

            context.Operand1 = result;

            context.InsertBefore().SetInstruction(GetMove(result, operand1), result, operand1);

            return;
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Call"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Call(Context context)
        {
            // FIXME: Result operand should be used instead of Operand1 for the result
            // FIXME: Move to FixedRegisterAssignmentStage
            Operand destinationOperand = context.Operand1;

            if (destinationOperand == null || destinationOperand.IsSymbol)
                return;

            if (!destinationOperand.IsRegister)
            {
                Context before = context.InsertBefore();
                Operand eax = AllocateVirtualRegister(destinationOperand.Type);

                before.SetInstruction(X86.Mov, eax, destinationOperand);
                context.Operand1 = eax;
            }
        }
 /// <summary>
 /// Visitation function for SubSInstruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void IR.IIRVisitor.SubSInstruction(Context context)
 {
     if (IsInt64(context.Operand1))
     {
         ExpandSub(context);
     }
     else
     {
         if (context.Operand2 is ConstantOperand && context.Operand1.Type.Type == CilElementType.Char)
         {
             RegisterOperand r10 = new RegisterOperand(context.Operand1.Type, GeneralPurposeRegister.R10);
             context.InsertBefore().SetInstruction(Instruction.MovInstruction, r10, context.Operand2);
             context.Operand2 = r10;
         }
     }
 }
예제 #14
0
        private void HandleMemoryToMemoryOperation(Context ctx)
        {
            Operand destination = ctx.Result;
            Operand source = ctx.Operand1;

            Debug.Assert(destination is MemoryOperand && source is MemoryOperand);

            SigType destinationSigType = destination.Type;

            if (this.RequiresSseOperation(destinationSigType))
            {
                IInstruction moveInstruction = this.GetMoveInstruction(destinationSigType);
                RegisterOperand destinationRegister = this.AllocateRegister(destinationSigType);

                ctx.Result = destinationRegister;
                ctx.AppendInstruction(moveInstruction, destination, destinationRegister);
            }
            else
            {
                SigType sourceSigType = ctx.Operand1.Type;
                IInstruction moveInstruction = this.GetMoveInstruction(sourceSigType);
                RegisterOperand sourceRegister = this.AllocateRegister(sourceSigType);

                ctx.Operand1 = sourceRegister;

                ctx.InsertBefore().SetInstruction(moveInstruction, sourceRegister, source);
            }
        }
        private void HandleMemoryToMemoryOperation2(Context ctx)
        {
            Operand destination = ctx.Operand1;
            Operand source = ctx.Operand2;

            Debug.Assert(destination.IsMemoryAddress && source.IsMemoryAddress);

            SigType destinationSigType = destination.Type;

            if (RequiresSseOperation(destinationSigType))
            {
                BaseInstruction moveInstruction = GetMoveInstruction(destinationSigType);
                Operand destinationRegister = AllocateRegister(destinationSigType);

                ctx.Operand1 = destinationRegister;
                ctx.AppendInstruction(moveInstruction, destination, destinationRegister);
            }
            else
            {
                SigType sourceSigType = source.Type;
                BaseInstruction moveInstruction = GetMoveInstruction(sourceSigType);
                Operand sourceRegister = AllocateRegister(sourceSigType);

                ctx.Operand2 = sourceRegister;
                ctx.InsertBefore().SetInstruction(moveInstruction, sourceRegister, source);
            }
        }
 /// <summary>
 /// Visitation function for SubSInstruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void IIRVisitor.SubSigned(Context context)
 {
     if (IsInt64(context.Operand1))
     {
         ExpandSub(context);
     }
     else
     {
         if (context.Operand2.IsConstant && context.Operand1.Type.Type == CilElementType.Char)
         {
             Operand r10 = Operand.CreateCPURegister(context.Operand1.Type, GeneralPurposeRegister.R10);
             context.InsertBefore().SetInstruction(AVR32.Mov, r10, context.Operand2);
             context.Operand2 = r10;
         }
     }
 }
        /// <summary>
        /// Visitation function for StoreInstruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IIRVisitor.Store(Context context)
        {
            Operand baseOperand = context.Operand1;
            Operand offsetOperand = context.Operand2;
            Operand value = context.Operand3;

            MosaType storeType = context.MosaType;
            var type = baseOperand.Type;
            var size = context.Size;

            if (value.IsR8 && type.IsR4) //&& size == InstructionSize.Size32)
            {
                Operand xmm1 = AllocateVirtualRegister(TypeSystem.BuiltIn.R4);
                context.InsertBefore().AppendInstruction(X86.Cvtsd2ss, size, xmm1, value);
                value = xmm1;
            }
            else if (value.IsMemoryAddress)
            {
                Operand v2 = AllocateVirtualRegister(value.Type);
                context.InsertBefore().AppendInstruction(X86.Mov, size, v2, value);
                value = v2;
            }

            if (offsetOperand.IsConstant)
            {
                if (baseOperand.IsField)
                {
                    Debug.Assert(offsetOperand.IsConstantZero);
                    Debug.Assert(baseOperand.Field.IsStatic);

                    context.SetInstruction(GetMove(baseOperand, value), size, baseOperand, value);
                }
                else
                {
                    var mem = Operand.CreateMemoryAddress(storeType, baseOperand, offsetOperand.ConstantSignedLongInteger);
                    context.SetInstruction(GetMove(mem, value), size, mem, value);
                }
            }
            else
            {
                if (type.IsUnmanagedPointer)
                    type = storeType.ToUnmanagedPointer();
                else if (type.IsManagedPointer)
                    type = storeType.ToManagedPointer();

                Operand v1 = AllocateVirtualRegister(type);
                Operand mem = Operand.CreateMemoryAddress(storeType, v1, 0);

                context.SetInstruction(X86.Mov, v1, baseOperand);
                context.AppendInstruction(X86.Add, v1, v1, offsetOperand);
                context.AppendInstruction(GetMove(mem, value), size, mem, value);
            }
        }
예제 #18
0
        /// <summary>
        /// Floating point compare instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IIRVisitor.FloatCompare(Context context)
        {
            EmitFloatingPointConstants(context);

            Operand result = context.Result;
            Operand left = context.Operand1;
            Operand right = context.Operand2;
            ConditionCode condition = context.ConditionCode;

            // normalize condition
            switch (condition)
            {
                case ConditionCode.Equal: break;
                case ConditionCode.NotEqual: break;
                case ConditionCode.UnsignedGreaterOrEqual: condition = ConditionCode.GreaterOrEqual; break;
                case ConditionCode.UnsignedGreaterThan: condition = ConditionCode.GreaterThan; break;
                case ConditionCode.UnsignedLessOrEqual: condition = ConditionCode.LessOrEqual; break;
                case ConditionCode.UnsignedLessThan: condition = ConditionCode.LessThan; break;
            }

            // TODO - Move the following to its own pre-IR decomposition stage for this instruction
            // Swap, if necessary, the operands to place register operand first than memory operand
            // otherwise the memory operand will have to be loaded into a register
            if ((condition == ConditionCode.Equal || condition == ConditionCode.NotEqual) && left.IsMemoryAddress && !right.IsMemoryAddress)
            {
                // swap order of operands to move
                var t = left;
                left = right;
                right = t;
            }

            Context before = context.InsertBefore();

            // Compare using the smallest precision
            if (left.IsR4 && right.IsR8)
            {
                Operand rop = AllocateVirtualRegister(TypeSystem.BuiltIn.R4);
                before.SetInstruction(X86.Cvtsd2ss, rop, right);
                right = rop;
            }
            if (left.IsR8 && right.IsR4)
            {
                Operand rop = AllocateVirtualRegister(TypeSystem.BuiltIn.R4);
                before.SetInstruction(X86.Cvtsd2ss, rop, left);
                left = rop;
            }

            X86Instruction instruction = null;
            if (left.IsR4)
            {
                instruction = X86.Ucomiss;
            }
            else
            {
                instruction = X86.Ucomisd;
            }

            switch (condition)
            {
                case ConditionCode.Equal:
                    {
                        //  a==b
                        //	mov	eax, 1
                        //	ucomisd	xmm0, xmm1
                        //	jp	L3
                        //	jne	L3
                        //	ret
                        //L3:
                        //	mov	eax, 0

                        Context[] newBlocks = CreateNewBlocksWithContexts(2);
                        Context nextBlock = Split(context);

                        context.SetInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 1));
                        context.AppendInstruction(instruction, null, left, right);
                        context.AppendInstruction(X86.Branch, ConditionCode.Parity, newBlocks[1].BasicBlock);
                        context.AppendInstruction(X86.Jmp, newBlocks[0].BasicBlock);
                        LinkBlocks(context, newBlocks[0], newBlocks[1]);

                        newBlocks[0].AppendInstruction(X86.Branch, ConditionCode.NotEqual, newBlocks[1].BasicBlock);
                        newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.BasicBlock);
                        LinkBlocks(newBlocks[0], newBlocks[1], nextBlock);

                        newBlocks[1].AppendInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 0));
                        newBlocks[1].AppendInstruction(X86.Jmp, nextBlock.BasicBlock);
                        LinkBlocks(newBlocks[1], nextBlock);

                        break;
                    }
                case ConditionCode.NotEqual:
                    {
                        //  a!=b
                        //	mov	eax, 1
                        //	ucomisd	xmm0, xmm1
                        //	jp	L5
                        //	setne	al
                        //	movzx	eax, al
                        //L5:

                        Context[] newBlocks = CreateNewBlocksWithContexts(1);
                        Context nextBlock = Split(context);

                        context.SetInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 1));
                        context.AppendInstruction(instruction, null, left, right);
                        context.AppendInstruction(X86.Branch, ConditionCode.Parity, nextBlock.BasicBlock);
                        context.AppendInstruction(X86.Jmp, newBlocks[0].BasicBlock);
                        LinkBlocks(context, nextBlock, newBlocks[0]);

                        newBlocks[0].AppendInstruction(X86.Setcc, ConditionCode.NotEqual, result);
                        newBlocks[0].AppendInstruction(X86.Movzx, result, result);
                        newBlocks[0].AppendInstruction(X86.Jmp, newBlocks[0].BasicBlock);
                        LinkBlocks(newBlocks[0], newBlocks[0]);

                        break;
                    }

                case ConditionCode.LessThan:
                    {
                        //	a>b and a<b
                        //	mov	eax, 0
                        //	ucomisd	xmm1, xmm0
                        //	seta	al

                        context.SetInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 0));
                        context.AppendInstruction(instruction, null, right, left);
                        context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result);
                        break;
                    }
                case ConditionCode.GreaterThan:
                    {
                        //	a>b and a<b
                        //	mov	eax, 0
                        //	ucomisd	xmm0, xmm1
                        //	seta	al

                        context.SetInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 0));
                        context.AppendInstruction(instruction, null, left, right);
                        context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result);
                        break;
                    }
                case ConditionCode.LessOrEqual:
                    {
                        //	a<=b and a>=b
                        //	mov	eax, 0
                        //	ucomisd	xmm1, xmm0
                        //	setae	al

                        context.SetInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 0));
                        context.AppendInstruction(instruction, null, left, right);
                        context.AppendInstruction(X86.Setcc, ConditionCode.NoCarry, result);
                        break;
                    }
                case ConditionCode.GreaterOrEqual:
                    {
                        //	a<=b and a>=b
                        //	mov	eax, 0
                        //	ucomisd	xmm0, xmm1
                        //	setae	al

                        context.SetInstruction(X86.Mov, result, Operand.CreateConstantSignedInt(TypeSystem, 0));
                        context.AppendInstruction(instruction, null, right, left);
                        context.AppendInstruction(X86.Setcc, ConditionCode.NoCarry, result);
                        break;
                    }
            }
        }
예제 #19
0
        /// <summary>
        /// Visitation function for DivUInstruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IIRVisitor.DivUnsigned(Context context)
        {
            context.ReplaceInstructionOnly(X86.Div);

            Operand edx = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EDX);
            Context before = context.InsertBefore();
            before.SetInstruction(X86.Xor, edx, edx);

            if (context.Operand1.IsConstant)
            {
                Operand ecx = Operand.CreateCPURegister(context.Operand1.Type, GeneralPurposeRegister.ECX);
                before.AppendInstruction(X86.Mov, ecx, context.Operand1);
                context.Operand1 = ecx;
            }
        }
예제 #20
0
        /// <summary>
        /// Visitation function for StoreInstruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IIRVisitor.Store(Context context)
        {
            Operand baseOperand = context.Operand1;
            Operand offsetOperand = context.Operand2;
            Operand value = context.Operand3;
            MosaType storeType = context.MosaType;

            //if (value.IsR4 || storeType.IsR4) // <--- this one is right
            if (value.IsR8 && (storeType ?? value.Type).IsR4)
            {
                Operand xmm1 = AllocateVirtualRegister(TypeSystem.BuiltIn.R4);
                context.InsertBefore().AppendInstruction(X86.Cvtsd2ss, xmm1, value);
                value = xmm1;
            }
            else
            {
                Operand v2 = AllocateVirtualRegister(value.Type);
                context.InsertBefore().AppendInstruction(X86.Mov, v2, value);
                value = v2;
            }

            MosaType type = baseOperand.Type;
            if (storeType != null)
            {
                if (baseOperand.Type.IsUnmanagedPointer)
                    type = storeType.ToUnmanagedPointer();

                else if (baseOperand.Type.IsManagedPointer)
                    type = storeType.ToManagedPointer();
            }

            if (offsetOperand.IsConstant)
            {
                Operand mem = Operand.CreateMemoryAddress(type, baseOperand, offsetOperand.ConstantSignedInteger);

                context.SetInstruction(GetMove(mem, value), mem, value);
            }
            else
            {
                Operand v1 = AllocateVirtualRegister(type);
                Operand mem = Operand.CreateMemoryAddress(type, v1, 0);

                context.SetInstruction(X86.Mov, v1, baseOperand);
                context.AppendInstruction(X86.Add, v1, v1, offsetOperand);
                context.AppendInstruction(GetMove(mem, value), mem, value);
            }
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Shr"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        void IX86Visitor.Shr(Context context)
        {
            if (context.Operand1.IsConstant)
                return;

            Operand ecx = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.ECX);
            Context before = context.InsertBefore();
            before.SetInstruction(X86.Mov, ecx, context.Operand1);
            context.Operand1 = context.Result;
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.IDiv"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        void IX86Visitor.IDiv(Context context)
        {
            Context before = context.InsertBefore();
            before.SetInstruction(X86.Cdq);

            if (context.Operand1.IsConstant)
            {
                Operand ecx = Operand.CreateCPURegister(context.Operand1.Type, GeneralPurposeRegister.ECX);
                before.AppendInstruction(X86.Mov, ecx, context.Operand1);
                context.Operand1 = ecx;
            }
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Shl"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        void IX86Visitor.Shl(Context context)
        {
            if (context.Operand1 is ConstantOperand)
                return;

            RegisterOperand ecx = new RegisterOperand(BuiltInSigType.IntPtr, GeneralPurposeRegister.ECX);
            Context before = context.InsertBefore();
            before.SetInstruction(X86.Mov, ecx, context.Operand1);
            context.Operand1 = context.Result;
        }
        /// <summary>
        /// Creates the outgoing moves.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="operandStack">The operand stack.</param>
        /// <param name="joinStack">The join stack.</param>
        private void CreateOutgoingMoves(BasicBlock block, Stack<Operand> operandStack, Stack<Operand> joinStack)
        {
            var context = new Context(instructionSet, block);

            while (!context.EndOfInstruction && !(context.Instruction is IBranchInstruction))
            {
                context.GotoNext();
            }

            while (operandStack.Count > 0)
            {
                var operand = operandStack.Pop();
                var destination = joinStack.Pop();
                context.InsertBefore().SetInstruction(IR.Instruction.MoveInstruction, destination, operand);
            }
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Cmp"/> instructions.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IX86Visitor.Cmp(Context ctx)
        {
            Operand left = ctx.Operand1;
            Operand right = ctx.Operand2;

            if (left.IsConstant)
            {
                Operand ecx = Operand.CreateCPURegister(left.Type, GeneralPurposeRegister.ECX);
                Context before = ctx.InsertBefore();
                before.SetInstruction(X86.Push, null, ecx);
                before.AppendInstruction(X86.Mov, ecx, left);
                ctx.Operand1 = ecx;
                ctx.AppendInstruction(X86.Pop, ecx);
            }
            if (right.IsConstant && !Is32Bit(left))
            {
                Operand edx = Operand.CreateCPURegister(BuiltInSigType.Int32, GeneralPurposeRegister.EBX);
                Context before = ctx.InsertBefore();
                before.SetInstruction(X86.Push, null, edx);
                if (IsSigned(left))
                    before.AppendInstruction(X86.Movsx, edx, left);
                else
                    before.AppendInstruction(X86.Movzx, edx, left);
                ctx.Operand1 = edx;
                ctx.AppendInstruction(X86.Pop, edx);
            }
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.IMul" /> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        public void IMul(Context context)
        {
            if (!context.Operand2.IsConstant)
                return;

            Operand v1 = AllocateVirtualRegister(context.Operand2.Type);
            Operand operand2 = context.Operand2;

            context.Operand2 = v1;
            context.InsertBefore().SetInstruction(X86.Mov, v1, operand2);
        }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Mul"/> instructions.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IX86Visitor.Mul(Context ctx)
        {
            if (ctx.Operand1.IsConstant)
            {
                Operand ecx = Operand.CreateCPURegister(ctx.Operand1.Type, GeneralPurposeRegister.ECX);
                Context before = ctx.InsertBefore();
                before.SetInstruction(X86.Push, null, ecx);
                before.AppendInstruction(X86.Mov, ecx, ctx.Operand1);

                ctx.Operand1 = ecx;
                ctx.AppendInstruction(X86.Pop, ecx);
            }
        }
 /// <summary>
 /// Visitation function for SubSInstruction.
 /// </summary>
 /// <param name="context">The context.</param>
 void IIRVisitor.SubSigned(Context context)
 {
     if (IsInt64(context.Operand1))
     {
         ExpandSub(context);
     }
     else
     {
         //FIXME: Move to IRTransformationStage
         if (context.Operand2 is ConstantOperand && context.Operand1.Type.Type == CilElementType.Char)
         {
             RegisterOperand ecx = new RegisterOperand(context.Operand1.Type, GeneralPurposeRegister.ECX);
             context.InsertBefore().SetInstruction(X86.Mov, ecx, context.Operand2);
             context.Operand2 = ecx;
         }
     }
 }
        /// <summary>
        /// Visitation function for <see cref="IX86Visitor.Call"/> instructions.
        /// </summary>
        /// <param name="context">The context.</param>
        void IX86Visitor.Call(Context context)
        {
            Operand destinationOperand = context.Operand1;

            if (destinationOperand == null || destinationOperand.IsSymbol)
                return;

            if (!(destinationOperand.IsRegister))
            {
                Context before = context.InsertBefore();
                Operand eax = Operand.CreateCPURegister(BuiltInSigType.IntPtr, GeneralPurposeRegister.EAX);

                before.SetInstruction(X86.Mov, eax, destinationOperand);
                context.Operand1 = eax;
            }
        }
예제 #30
0
        /// <summary>
        /// Extends to r8.
        /// </summary>
        /// <param name="context">The context.</param>
        private static void ExtendToR8(Context context)
        {
            Operand xmm5 = Operand.CreateCPURegister(BuiltInSigType.Double, SSE2Register.XMM5);
            Operand xmm6 = Operand.CreateCPURegister(BuiltInSigType.Double, SSE2Register.XMM6);
            Context before = context.InsertBefore();

            if (context.Result.Type.Type == CilElementType.R4)
            {
                before.SetInstruction(X86.Cvtss2sd, xmm5, context.Result);
                context.Result = xmm5;
            }

            if (context.Operand1.Type.Type == CilElementType.R4)
            {
                before.SetInstruction(X86.Cvtss2sd, xmm6, context.Operand1);
                context.Operand1 = xmm6;
            }
        }