Esempio n. 1
0
        /// <summary>
        /// Visitation function for <see cref="CIL.ICILVisitor.BinaryBranch"/>.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void CIL.ICILVisitor.BinaryBranch(Context ctx)
        {
            bool    swap   = ctx.Operand1 is ConstantOperand;
            IBranch branch = ctx.Branch;

            IR.ConditionCode conditionCode = ConvertCondition((ctx.Instruction as CIL.BinaryBranchInstruction).OpCode);

            if (swap)
            {
                ctx.SetInstruction(CPUx86.Instruction.CmpInstruction, ctx.Operand2, ctx.Operand1);
                ctx.AppendInstruction(CPUx86.Instruction.BranchInstruction, GetOppositeConditionCode(conditionCode));
            }
            else
            {
                ctx.SetInstruction(CPUx86.Instruction.CmpInstruction, ctx.Operand1, ctx.Operand2);
                ctx.AppendInstruction(CPUx86.Instruction.BranchInstruction, conditionCode);
            }

            ctx.SetBranch(branch.Targets[0]);
        }
Esempio n. 2
0
        /// <summary>
        /// Visitation function for <see cref="IR.IIRVisitor.IntegerCompareInstruction"/> instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IR.IIRVisitor.IntegerCompareInstruction(Context ctx)
        {
            EmitOperandConstants(ctx);

            IR.ConditionCode condition = ctx.ConditionCode;

            ctx.SetInstruction(CPUx86.Instruction.CmpInstruction, ctx.Result, ctx.Operand1);

            if (IsUnsigned(ctx.Operand1) || IsUnsigned(ctx.Result))
            {
                ctx.AppendInstruction(CPUx86.Instruction.SetccInstruction, GetUnsignedConditionCode(condition), ctx.Result);
            }
            else
            {
                ctx.AppendInstruction(CPUx86.Instruction.SetccInstruction, condition, ctx.Result);
            }

            if (ctx.Result is RegisterOperand)
            {
                RegisterOperand rop = new RegisterOperand(new SigType(CilElementType.U1), ((RegisterOperand)ctx.Result).Register);
                ctx.AppendInstruction(CPUx86.Instruction.MovzxInstruction, rop, rop);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Floatings the point compare instruction.
        /// </summary>
        /// <param name="ctx">The context.</param>
        void IR.IIRVisitor.FloatingPointCompareInstruction(Context ctx)
        {
            Operand op0   = ctx.Result;
            Operand left  = EmitConstant(ctx.Operand1);
            Operand right = EmitConstant(ctx.Operand2);

            //ctx.Remove();
            ctx.Operand1 = left;
            ctx.Operand2 = right;


            // Swap the operands if necessary...
            if (left is MemoryOperand && right is RegisterOperand)
            {
                SwapComparisonOperands(ctx);
                left  = ctx.Operand1;
                right = ctx.Operand2;
            }

            IR.ConditionCode setcc = IR.ConditionCode.Equal;
            IR.ConditionCode code  = ctx.ConditionCode;

            ctx.SetInstruction(CPUx86.Instruction.NopInstruction);

            // x86 is messed up :(
            switch (code)
            {
            case IR.ConditionCode.Equal:
                break;

            case IR.ConditionCode.NotEqual:
                break;

            case IR.ConditionCode.UnsignedGreaterOrEqual:
                setcc = IR.ConditionCode.GreaterOrEqual;
                break;

            case IR.ConditionCode.UnsignedGreaterThan:
                setcc = IR.ConditionCode.GreaterThan;
                break;

            case IR.ConditionCode.UnsignedLessOrEqual:
                setcc = IR.ConditionCode.LessOrEqual;
                break;

            case IR.ConditionCode.UnsignedLessThan:
                setcc = IR.ConditionCode.LessThan;
                break;

            case IR.ConditionCode.GreaterOrEqual:
                setcc = IR.ConditionCode.UnsignedGreaterOrEqual;
                break;

            case IR.ConditionCode.GreaterThan:
                setcc = IR.ConditionCode.UnsignedGreaterThan;
                break;

            case IR.ConditionCode.LessOrEqual:
                setcc = IR.ConditionCode.UnsignedLessOrEqual;
                break;

            case IR.ConditionCode.LessThan:
                setcc = IR.ConditionCode.UnsignedLessThan;
                break;
            }

            if (!(left is RegisterOperand))
            {
                RegisterOperand xmm2 = new RegisterOperand(left.Type, SSE2Register.XMM2);
                if (left.Type.Type == CilElementType.R4)
                {
                    ctx.AppendInstruction(CPUx86.Instruction.MovssInstruction, xmm2, left);
                }
                else
                {
                    ctx.AppendInstruction(CPUx86.Instruction.MovsdInstruction, xmm2, left);
                }
                left = xmm2;
            }

            // Compare using the smallest precision
            if (left.Type.Type == CilElementType.R4 && right.Type.Type == CilElementType.R8)
            {
                RegisterOperand rop = new RegisterOperand(new SigType(CilElementType.R4), SSE2Register.XMM4);
                ctx.AppendInstruction(CPUx86.Instruction.Cvtsd2ssInstruction, rop, right);
                right = rop;
            }
            if (left.Type.Type == CilElementType.R8 && right.Type.Type == CilElementType.R4)
            {
                RegisterOperand rop = new RegisterOperand(new SigType(CilElementType.R4), SSE2Register.XMM3);
                ctx.AppendInstruction(CPUx86.Instruction.Cvtsd2ssInstruction, rop, left);
                left = rop;
            }

            if (left.Type.Type == CilElementType.R4)
            {
                switch (code)
                {
                case IR.ConditionCode.Equal:
                    ctx.AppendInstruction(CPUx86.Instruction.UcomissInstruction, left, right);
                    break;

                case IR.ConditionCode.NotEqual:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedGreaterOrEqual:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedGreaterThan:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedLessOrEqual:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedLessThan:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.GreaterOrEqual:
                    ctx.AppendInstruction(CPUx86.Instruction.ComissInstruction, left, right);
                    break;

                case IR.ConditionCode.GreaterThan:
                    goto case IR.ConditionCode.GreaterOrEqual;

                case IR.ConditionCode.LessOrEqual:
                    goto case IR.ConditionCode.GreaterOrEqual;

                case IR.ConditionCode.LessThan:
                    goto case IR.ConditionCode.GreaterOrEqual;
                }
            }


            else
            {
                switch (code)
                {
                case IR.ConditionCode.Equal:
                    ctx.AppendInstruction(CPUx86.Instruction.UcomisdInstruction, left, right);
                    break;

                case IR.ConditionCode.NotEqual:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedGreaterOrEqual:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedGreaterThan:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedLessOrEqual:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.UnsignedLessThan:
                    goto case IR.ConditionCode.Equal;

                case IR.ConditionCode.GreaterOrEqual:
                    ctx.AppendInstruction(CPUx86.Instruction.ComisdInstruction, left, right);
                    break;

                case IR.ConditionCode.GreaterThan:
                    goto case IR.ConditionCode.GreaterOrEqual;

                case IR.ConditionCode.LessOrEqual:
                    goto case IR.ConditionCode.GreaterOrEqual;

                case IR.ConditionCode.LessThan:
                    goto case IR.ConditionCode.GreaterOrEqual;
                }
            }

            // Determine the result
            ctx.AppendInstruction(CPUx86.Instruction.SetccInstruction, setcc, op0);

            // Extend this to the full register, if we're storing it in a register
            if (op0 is RegisterOperand)
            {
                RegisterOperand rop = new RegisterOperand(new SigType(CilElementType.U1), ((RegisterOperand)op0).Register);
                ctx.AppendInstruction(CPUx86.Instruction.MovzxInstruction, op0, rop);
            }
        }