Пример #1
0
        private static void EmitMathOp3(AILEmitterCtx Context, string Name)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);
            Context.EmitLdvecsf(Op.Rm);

            MethodInfo MthdInfo;

            if (Op.Size == 0)
            {
                MthdInfo = typeof(MathF).GetMethod(Name, new Type[] { typeof(float), typeof(float) });
            }
            else if (Op.Size == 1)
            {
                MthdInfo = typeof(Math).GetMethod(Name, new Type[] { typeof(double), typeof(double) });
            }
            else
            {
                throw new InvalidOperationException();
            }

            Context.EmitCall(MthdInfo);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #2
0
        public static void Fnmul_S(AILEmitterCtx Context)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);
            Context.EmitLdvecsf(Op.Rm);

            Context.Emit(OpCodes.Mul);
            Context.Emit(OpCodes.Neg);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #3
0
        public static void Frintm_S(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            MethodInfo MthdInfo;

            if (Op.Size == 0)
            {
                MthdInfo = typeof(MathF).GetMethod(nameof(MathF.Floor), new Type[] { typeof(float) });
            }
            else if (Op.Size == 1)
            {
                MthdInfo = typeof(Math).GetMethod(nameof(Math.Floor), new Type[] { typeof(double) });
            }
            else
            {
                throw new InvalidOperationException();
            }

            Context.EmitCall(MthdInfo);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #4
0
        public static void Frinta_S(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);
            Context.EmitLdc_I4((int)MidpointRounding.AwayFromZero);

            MethodInfo MthdInfo;

            if (Op.Size == 0)
            {
                Type[] Types = new Type[] { typeof(float), typeof(MidpointRounding) };

                MthdInfo = typeof(MathF).GetMethod(nameof(MathF.Round), Types);
            }
            else if (Op.Size == 1)
            {
                Type[] Types = new Type[] { typeof(double), typeof(MidpointRounding) };

                MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types);
            }
            else
            {
                throw new InvalidOperationException();
            }

            Context.EmitCall(MthdInfo);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #5
0
        public static void Fmov_S(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);
            Context.EmitStvecsf(Op.Rd);
        }
Пример #6
0
        private static void EmitScalarOp(AILEmitterCtx Context, OpCode ILOp)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            //Negate and Not are the only unary operations supported on IL.
            //"Not" doesn't work with floats, so we don't need to compare it.
            if (ILOp != OpCodes.Neg)
            {
                Context.EmitLdvecsf(Op.Rm);
            }

            Context.Emit(ILOp);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #7
0
        private static void EmitMathOp2(AILEmitterCtx Context, string Name)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            EmitMathOpCall(Context, Name);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #8
0
        public static void Fcvt_S(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            EmitFloatCast(Context, Op.Opc);

            Context.EmitStvecsf(Op.Rd);
        }
Пример #9
0
        public static void Fcsel_S(AILEmitterCtx Context)
        {
            AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;

            AILLabel LblTrue = new AILLabel();
            AILLabel LblEnd  = new AILLabel();

            Context.EmitCondBranch(LblTrue, Op.Cond);
            Context.EmitLdvecsf(Op.Rm);
            Context.EmitStvecsf(Op.Rd);

            Context.Emit(OpCodes.Br_S, LblEnd);

            Context.MarkLabel(LblTrue);

            Context.EmitLdvecsf(Op.Rn);
            Context.EmitStvecsf(Op.Rd);

            Context.MarkLabel(LblEnd);
        }
Пример #10
0
        public static void EmitMathOpCvtToInt(AILEmitterCtx Context, string Name)
        {
            AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            EmitMathOpCall(Context, Name);

            EmitCvtToInt(Context, Op.Size);

            Context.EmitStintzr(Op.Rd);
        }
Пример #11
0
        private static void EmitFcvtz_(AILEmitterCtx Context, bool Signed)
        {
            AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            if (Signed)
            {
                EmitCvtToInt(Context, Op.Size);
            }
            else
            {
                EmitCvtToUInt(Context, Op.Size);
            }

            Context.EmitStintzr(Op.Rd);
        }
Пример #12
0
        private static void EmitNaNCheck(AILEmitterCtx Context, int Index)
        {
            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;

            Context.EmitLdvecsf(Index);

            if (Op.Size == 0)
            {
                Context.EmitCall(typeof(float), nameof(float.IsNaN));
            }
            else if (Op.Size == 1)
            {
                Context.EmitCall(typeof(double), nameof(double.IsNaN));
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Пример #13
0
        private static void EmitFcvtz__Fix(AILEmitterCtx Context, bool Signed)
        {
            AOpCodeSimdCvt Op = (AOpCodeSimdCvt)Context.CurrOp;

            Context.EmitLdvecsf(Op.Rn);

            EmitLdcImmF(Context, 1L << Op.FBits, Op.Size);

            Context.Emit(OpCodes.Mul);

            if (Signed)
            {
                EmitCvtToInt(Context, Op.Size);
            }
            else
            {
                EmitCvtToUInt(Context, Op.Size);
            }

            Context.EmitStintzr(Op.Rd);
        }
Пример #14
0
        public static void Fcmp_S(AILEmitterCtx Context)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

            bool CmpWithZero = !(Op is AOpCodeSimdFcond) ? Op.Bit3 : false;

            //todo
            //Context.TryMarkCondWithoutCmp();

            void EmitLoadOpers()
            {
                Context.EmitLdvecsf(Op.Rn);

                if (CmpWithZero)
                {
                    EmitLdcImmF(Context, 0, Op.Size);
                }
                else
                {
                    Context.EmitLdvecsf(Op.Rm);
                }
            }

            //Z = Rn == Rm
            EmitLoadOpers();

            Context.Emit(OpCodes.Ceq);
            Context.Emit(OpCodes.Dup);

            Context.EmitStflg((int)APState.ZBit);

            //C = Rn >= Rm
            EmitLoadOpers();

            Context.Emit(OpCodes.Cgt);
            Context.Emit(OpCodes.Or);

            Context.EmitStflg((int)APState.CBit);

            //N = Rn < Rm
            EmitLoadOpers();

            Context.Emit(OpCodes.Clt);

            Context.EmitStflg((int)APState.NBit);

            //Handle NaN case. If any number is NaN, then NZCV = 0011.
            AILLabel LblNotNaN = new AILLabel();

            if (CmpWithZero)
            {
                EmitNaNCheck(Context, Op.Rn);
            }
            else
            {
                EmitNaNCheck(Context, Op.Rn);
                EmitNaNCheck(Context, Op.Rm);

                Context.Emit(OpCodes.Or);
            }

            Context.Emit(OpCodes.Brfalse_S, LblNotNaN);

            Context.EmitLdc_I4(1);
            Context.EmitLdc_I4(1);

            Context.EmitStflg((int)APState.CBit);
            Context.EmitStflg((int)APState.VBit);

            Context.MarkLabel(LblNotNaN);
        }