public static void Vminnm_V(ArmEmitterContext context)
 {
     EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMinNumFpscr, SoftFloat64.FPMinNumFpscr, op1, op2));
 }
示例#2
0
 public static void EmitNZFlagsCheck(ArmEmitterContext context, Operand d)
 {
     SetFlag(context, PState.NFlag, context.ICompareLess(d, Const(d.Type, 0)));
     SetFlag(context, PState.ZFlag, context.ICompareEqual(d, Const(d.Type, 0)));
 }
示例#3
0
 private static void SetCarryMLsb(ArmEmitterContext context, Operand m)
 {
     SetFlag(context, PState.CFlag, context.BitwiseAnd(m, Const(1)));
 }
 public static void Vmls_I(ArmEmitterContext context)
 {
     EmitVectorTernaryOpZx32(context, (op1, op2, op3) => context.Subtract(op1, context.Multiply(op2, op3)));
 }
        public static void Vmull_1(ArmEmitterContext context)
        {
            OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp;

            EmitVectorByScalarLongOpI32(context, (op1, op2) => context.Multiply(op1, op2), !op.U);
        }
示例#6
0
 public static void Svc(ArmEmitterContext context)
 {
     EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall));
 }
 public static void Vmovn(ArmEmitterContext context)
 {
     EmitVectorUnaryNarrowOp32(context, (op1) => op1);
 }
示例#8
0
 public static void Cmlt_S(ArmEmitterContext context)
 {
     EmitCmpOp(context, (op1, op2) => context.ICompareLess(op1, op2), scalar: true);
 }
示例#9
0
 public static void Cmtst_S(ArmEmitterContext context)
 {
     EmitCmtstOp(context, scalar: true);
 }
 public static void Vsub_I(ArmEmitterContext context)
 {
     EmitVectorBinaryOpZx32(context, (op1, op2) => context.Subtract(op1, op2));
 }
 public static void Vadd_I(ArmEmitterContext context)
 {
     EmitVectorBinaryOpZx32(context, (op1, op2) => context.Add(op1, op2));
 }
 public static void Vsub_S(ArmEmitterContext context)
 {
     EmitScalarBinaryOpF32(context, (op1, op2) => context.Subtract(op1, op2));
 }
        public static void Vpadd_I(ArmEmitterContext context)
        {
            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;

            EmitVectorPairwiseOpI32(context, (op1, op2) => context.Add(op1, op2), !op.U);
        }
 public static void Vpadd_V(ArmEmitterContext context)
 {
     EmitVectorPairwiseOpF32(context, (op1, op2) => context.Add(op1, op2));
 }
 public static void EmitVectorTernaryOpZx32(ArmEmitterContext context, Func3I emit)
 {
     EmitVectorTernaryOpI32(context, emit, false);
 }
示例#16
0
 public static void Cmtst_V(ArmEmitterContext context)
 {
     EmitCmtstOp(context, scalar: false);
 }
 public static Operand ExtractElement(ArmEmitterContext context, int reg, int size, bool signed)
 {
     return(EmitVectorExtract32(context, reg >> (4 - size), reg & ((16 >> size) - 1), size, signed));
 }
示例#18
0
 public static void Fccmp_S(ArmEmitterContext context)
 {
     EmitFccmpOrFccmpe(context, signalNaNs: false);
 }
示例#19
0
 public static void Trap(ArmEmitterContext context)
 {
     EmitExceptionCall(context, nameof(NativeInterface.Break));
 }
示例#20
0
 public static void Fcmpe_S(ArmEmitterContext context)
 {
     EmitFcmpOrFcmpe(context, signalNaNs: true);
 }
        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)));
        }
示例#22
0
        private static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs)
        {
            OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;

            const int cmpOrdered = 7;

            bool cmpWithZero = !(op is OpCodeSimdFcond) ? op.Bit3 : false;

            if (Optimizations.FastFP && Optimizations.UseSse2)
            {
                Operand n = GetVec(op.Rn);
                Operand m = cmpWithZero ? context.VectorZero() : GetVec(op.Rm);

                Operand lblNaN = Label();
                Operand lblEnd = Label();

                if (op.Size == 0)
                {
                    Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpss, n, m, Const(cmpOrdered));

                    Operand isOrdered = context.VectorExtract16(ordMask, 0);

                    context.BranchIfFalse(lblNaN, isOrdered);

                    Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comissge, n, m);
                    Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisseq, n, m);
                    Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisslt, n, m);

                    SetFlag(context, PState.VFlag, Const(0));
                    SetFlag(context, PState.CFlag, cf);
                    SetFlag(context, PState.ZFlag, zf);
                    SetFlag(context, PState.NFlag, nf);
                }
                else /* if (op.Size == 1) */
                {
                    Operand ordMask = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, m, Const(cmpOrdered));

                    Operand isOrdered = context.VectorExtract16(ordMask, 0);

                    context.BranchIfFalse(lblNaN, isOrdered);

                    Operand cf = context.AddIntrinsicInt(Intrinsic.X86Comisdge, n, m);
                    Operand zf = context.AddIntrinsicInt(Intrinsic.X86Comisdeq, n, m);
                    Operand nf = context.AddIntrinsicInt(Intrinsic.X86Comisdlt, n, m);

                    SetFlag(context, PState.VFlag, Const(0));
                    SetFlag(context, PState.CFlag, cf);
                    SetFlag(context, PState.ZFlag, zf);
                    SetFlag(context, PState.NFlag, nf);
                }

                context.Branch(lblEnd);

                context.MarkLabel(lblNaN);

                SetFlag(context, PState.VFlag, Const(1));
                SetFlag(context, PState.CFlag, Const(1));
                SetFlag(context, PState.ZFlag, Const(0));
                SetFlag(context, PState.NFlag, Const(0));

                context.MarkLabel(lblEnd);
            }
            else
            {
                OperandType type = op.Size != 0 ? OperandType.FP64 : OperandType.FP32;

                Operand ne = context.VectorExtract(type, GetVec(op.Rn), 0);
                Operand me;

                if (cmpWithZero)
                {
                    me = op.Size == 0 ? ConstF(0f) : ConstF(0d);
                }
                else
                {
                    me = context.VectorExtract(type, GetVec(op.Rm), 0);
                }

                Delegate dlg = op.Size != 0
                    ? (Delegate) new _S32_F64_F64_Bool(SoftFloat64.FPCompare)
                    : (Delegate) new _S32_F32_F32_Bool(SoftFloat32.FPCompare);

                Operand nzcv = context.Call(dlg, ne, me, Const(signalNaNs));

                EmitSetNzcv(context, nzcv);
            }
        }
        public static void Vmlsl_I(ArmEmitterContext context)
        {
            OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;

            EmitVectorTernaryLongOpI32(context, (opD, op1, op2) => context.Subtract(opD, context.Multiply(op1, op2)), !op.U);
        }
示例#24
0
 public static void Cmge_S(ArmEmitterContext context)
 {
     EmitCmpOp(context, (op1, op2) => context.ICompareGreaterOrEqual(op1, op2), scalar: true);
 }
示例#25
0
        public static Operand GetAluM(ArmEmitterContext context, bool setCarry = true)
        {
            switch (context.CurrOp)
            {
            // ARM32.
            case OpCode32AluImm op:
            {
                if (op.SetFlags && op.IsRotated)
                {
                    SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31));
                }

                return(Const(op.Immediate));
            }

            case OpCode32AluRsImm op: return(GetMShiftedByImmediate(context, op, setCarry));

            case OpCodeT16AluImm8 op: return(Const(op.Immediate));

            // ARM64.
            case IOpCodeAluImm op:
            {
                if (op.GetOperandType() == OperandType.I32)
                {
                    return(Const((int)op.Immediate));
                }
                else
                {
                    return(Const(op.Immediate));
                }
            }

            case IOpCodeAluRs op:
            {
                Operand value = GetIntOrZR(context, op.Rm);

                switch (op.ShiftType)
                {
                case ShiftType.Lsl: value = context.ShiftLeft(value, Const(op.Shift)); break;

                case ShiftType.Lsr: value = context.ShiftRightUI(value, Const(op.Shift)); break;

                case ShiftType.Asr: value = context.ShiftRightSI(value, Const(op.Shift)); break;

                case ShiftType.Ror: value = context.RotateRight(value, Const(op.Shift)); break;
                }

                return(value);
            }

            case IOpCodeAluRx op:
            {
                Operand value = GetExtendedM(context, op.Rm, op.IntType);

                value = context.ShiftLeft(value, Const(op.Shift));

                return(value);
            }

            default: throw InvalidOpCodeType(context.CurrOp);
            }
        }
 public static Operand EmitVectorExtractZx32(ArmEmitterContext context, int reg, int index, int size)
 {
     return(EmitVectorExtract32(context, reg, index, size, false));
 }
示例#27
0
 public static void EmitAddsCCheck(ArmEmitterContext context, Operand n, Operand d)
 {
     // C = Rd < Rn
     SetFlag(context, PState.CFlag, context.ICompareLessUI(d, n));
 }
 public static void EmitVectorBinaryOpSx32(ArmEmitterContext context, Func2I emit)
 {
     EmitVectorBinaryOpI32(context, emit, true);
 }
示例#29
0
 private static void SetCarryMMsb(ArmEmitterContext context, Operand m)
 {
     SetFlag(context, PState.CFlag, context.ShiftRightUI(m, Const(31)));
 }
 public static void Vminnm_S(ArmEmitterContext context)
 {
     EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2));
 }