示例#1
0
        private static Operand EmitUnsignedShlRegOp(ArmEmitterContext context, Operand op, Operand shiftLsB, int size)
        {
            Debug.Assert(op.Type == OperandType.I64);
            Debug.Assert(shiftLsB.Type == OperandType.I32);
            Debug.Assert((uint)size < 4u);

            Operand negShiftLsB = context.Negate(shiftLsB);

            Operand isPositive = context.ICompareGreaterOrEqual(shiftLsB, Const(0));

            Operand shl = context.ShiftLeft(op, shiftLsB);
            Operand shr = context.ShiftRightUI(op, negShiftLsB);

            Operand res = context.ConditionalSelect(isPositive, shl, shr);

            Operand isOutOfRange = context.BitwiseOr(
                context.ICompareGreaterOrEqual(shiftLsB, Const(8 << size)),
                context.ICompareGreaterOrEqual(negShiftLsB, Const(8 << size)));

            return(context.ConditionalSelect(isOutOfRange, Const(0UL), res));
        }
示例#2
0
        private static Operand EmitShlRegOp(ArmEmitterContext context, Operand op, Operand shiftLsB, int size, bool unsigned)
        {
            if (shiftLsB.Type == OperandType.I64)
            {
                shiftLsB = context.ConvertI64ToI32(shiftLsB);
            }

            shiftLsB = context.SignExtend8(OperandType.I32, shiftLsB);
            Debug.Assert((uint)size < 4u);

            Operand negShiftLsB = context.Negate(shiftLsB);

            Operand isPositive = context.ICompareGreaterOrEqual(shiftLsB, Const(0));

            Operand shl = context.ShiftLeft(op, shiftLsB);
            Operand shr = unsigned ? context.ShiftRightUI(op, negShiftLsB) : context.ShiftRightSI(op, negShiftLsB);

            Operand res = context.ConditionalSelect(isPositive, shl, shr);

            if (unsigned)
            {
                Operand isOutOfRange = context.BitwiseOr(
                    context.ICompareGreaterOrEqual(shiftLsB, Const(8 << size)),
                    context.ICompareGreaterOrEqual(negShiftLsB, Const(8 << size)));

                return(context.ConditionalSelect(isOutOfRange, Const(op.Type, 0), res));
            }
            else
            {
                Operand isOutOfRange0 = context.ICompareGreaterOrEqual(shiftLsB, Const(8 << size));
                Operand isOutOfRangeN = context.ICompareGreaterOrEqual(negShiftLsB, Const(8 << size));

                // Also zero if shift is too negative, but value was positive.
                isOutOfRange0 = context.BitwiseOr(isOutOfRange0, context.BitwiseAnd(isOutOfRangeN, context.ICompareGreaterOrEqual(op, Const(op.Type, 0))));

                Operand min = (op.Type == OperandType.I64) ? Const(-1L) : Const(-1);

                return(context.ConditionalSelect(isOutOfRange0, Const(op.Type, 0), context.ConditionalSelect(isOutOfRangeN, min, res)));
            }
        }
示例#3
0
        private static Operand EmitShlRegOp(ArmEmitterContext context, Operand op, Operand shiftLsB, int size, bool signed)
        {
            Debug.Assert(op.Type == OperandType.I64);
            Debug.Assert(shiftLsB.Type == OperandType.I32);
            Debug.Assert((uint)size < 4u);

            Operand negShiftLsB = context.Negate(shiftLsB);

            Operand isInRange = context.BitwiseAnd(
                context.ICompareLess(shiftLsB, Const(8 << size)),
                context.ICompareLess(negShiftLsB, Const(8 << size)));

            Operand isPositive = context.ICompareGreaterOrEqual(shiftLsB, Const(0));

            Operand shl = context.ShiftLeft(op, shiftLsB);

            Operand sarOrShr = signed
                ? context.ShiftRightSI(op, negShiftLsB)
                : context.ShiftRightUI(op, negShiftLsB);

            Operand res = context.ConditionalSelect(isPositive, shl, sarOrShr);

            if (signed)
            {
                Operand isPositive2 = context.ICompareGreaterOrEqual(op, Const(0L));

                Operand res2 = context.ConditionalSelect(isPositive2, Const(0L), Const(-1L));
                res2 = context.ConditionalSelect(isPositive, Const(0L), res2);

                return(context.ConditionalSelect(isInRange, res, res2));
            }
            else
            {
                return(context.ConditionalSelect(isInRange, res, Const(0UL)));
            }
        }
示例#4
0
        public static Operand EmitLsrC(ArmEmitterContext context, Operand m, bool setCarry, Operand shift, Operand shiftIsZero)
        {
            Debug.Assert(m.Type == OperandType.I32 && shift.Type == OperandType.I32 && shiftIsZero.Type == OperandType.I32);

            Operand shiftLarge = context.ICompareGreaterOrEqual(shift, Const(32));
            Operand result     = context.ShiftRightUI(m, shift);

            if (setCarry)
            {
                EmitIfHelper(context, shiftIsZero, () =>
                {
                    Operand cOut = context.ShiftRightUI(m, context.Subtract(shift, Const(1)));

                    cOut = context.BitwiseAnd(cOut, Const(1));
                    cOut = context.ConditionalSelect(context.ICompareGreater(shift, Const(32)), Const(0), cOut);

                    SetFlag(context, PState.CFlag, cOut);
                }, false);
            }

            return(context.ConditionalSelect(shiftLarge, Const(0), result));
        }
示例#5
0
        public static void Cmge_V(ArmEmitterContext context)
        {
            if (Optimizations.UseSse42)
            {
                OpCodeSimd op = (OpCodeSimd)context.CurrOp;

                Operand n = GetVec(op.Rn);
                Operand m;

                if (op is OpCodeSimdReg binOp)
                {
                    m = GetVec(binOp.Rm);
                }
                else
                {
                    m = context.VectorZero();
                }

                Intrinsic cmpInst = X86PcmpgtInstruction[op.Size];

                Operand res = context.AddIntrinsic(cmpInst, m, n);

                Operand mask = X86GetAllElements(context, -1L);

                res = context.AddIntrinsic(Intrinsic.X86Pandn, res, mask);

                if (op.RegisterSize == RegisterSize.Simd64)
                {
                    res = context.VectorZeroUpper64(res);
                }

                context.Copy(GetVec(op.Rd), res);
            }
            else
            {
                EmitCmpOp(context, (op1, op2) => context.ICompareGreaterOrEqual(op1, op2), scalar: false);
            }
        }
示例#6
0
 public static void Cmge_S(ArmEmitterContext context)
 {
     EmitCmpOp(context, (op1, op2) => context.ICompareGreaterOrEqual(op1, op2), scalar: true);
 }
示例#7
0
        private static Operand EmitAbs(ArmEmitterContext context, Operand value)
        {
            Operand isPositive = context.ICompareGreaterOrEqual(value, Const(value.Type, 0));

            return(context.ConditionalSelect(isPositive, value, context.Negate(value)));
        }