private static void EmitFrecps(AILEmitterCtx Context, int Index, bool Scalar)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

            int SizeF = Op.Size & 1;

            if (SizeF == 0)
            {
                Context.EmitLdc_R4(2);
            }
            else /* if (SizeF == 1) */
            {
                Context.EmitLdc_R8(2);
            }

            EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
            EmitVectorExtractF(Context, Op.Rm, Index, SizeF);

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

            if (Scalar)
            {
                EmitVectorZeroAll(Context, Op.Rd);
            }

            EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
        }
Esempio n. 2
0
        private static void EmitFcmp(AILEmitterCtx Context, OpCode ILOp, int Index, bool Scalar)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int SizeF = Op.Size & 1;

            ulong SzMask = ulong.MaxValue >> (64 - (32 << SizeF));

            EmitVectorExtractF(Context, Op.Rn, Index, SizeF);

            if (Op is AOpCodeSimdReg BinOp)
            {
                EmitVectorExtractF(Context, BinOp.Rm, Index, SizeF);
            }
            else if (SizeF == 0)
            {
                Context.EmitLdc_R4(0);
            }
            else /* if (SizeF == 1) */
            {
                Context.EmitLdc_R8(0);
            }

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

            Context.Emit(ILOp, LblTrue);

            if (Scalar)
            {
                EmitVectorZeroAll(Context, Op.Rd);
            }
            else
            {
                EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, 0);
            }

            Context.Emit(OpCodes.Br_S, LblEnd);

            Context.MarkLabel(LblTrue);

            if (Scalar)
            {
                EmitVectorInsert(Context, Op.Rd, Index, 3, (long)SzMask);

                EmitVectorZeroUpper(Context, Op.Rd);
            }
            else
            {
                EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, (long)SzMask);
            }

            Context.MarkLabel(LblEnd);
        }
Esempio n. 3
0
 private static void EmitLdcImmF(AILEmitterCtx Context, double ImmF, int Size)
 {
     if (Size == 0)
     {
         Context.EmitLdc_R4((float)ImmF);
     }
     else if (Size == 1)
     {
         Context.EmitLdc_R8(ImmF);
     }
     else
     {
         throw new ArgumentOutOfRangeException(nameof(Size));
     }
 }
Esempio n. 4
0
        private static void EmitI2fFBitsMul(AILEmitterCtx Context, int Size, int FBits)
        {
            if (FBits != 0)
            {
                if (Size == 0)
                {
                    Context.EmitLdc_R4(1f / MathF.Pow(2, FBits));
                }
                else if (Size == 1)
                {
                    Context.EmitLdc_R8(1 / Math.Pow(2, FBits));
                }
                else
                {
                    throw new ArgumentOutOfRangeException(nameof(Size));
                }

                Context.Emit(OpCodes.Mul);
            }
        }
Esempio n. 5
0
        public static void Fcmp_S(AILEmitterCtx Context)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

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

            //Handle NaN case.
            //If any number is NaN, then NZCV = 0011.
            if (CmpWithZero)
            {
                EmitNaNCheck(Context, Op.Rn);
            }
            else
            {
                EmitNaNCheck(Context, Op.Rn);
                EmitNaNCheck(Context, Op.Rm);

                Context.Emit(OpCodes.Or);
            }

            AILLabel LblNaN = new AILLabel();
            AILLabel LblEnd = new AILLabel();

            Context.Emit(OpCodes.Brtrue_S, LblNaN);

            void EmitLoadOpers()
            {
                EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);

                if (CmpWithZero)
                {
                    if (Op.Size == 0)
                    {
                        Context.EmitLdc_R4(0);
                    }
                    else /* if (SizeF == 1) */
                    {
                        Context.EmitLdc_R8(0);
                    }
                }
                else
                {
                    EmitVectorExtractF(Context, Op.Rm, 0, Op.Size);
                }
            }

            //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);

            //V = 0
            Context.EmitLdc_I4(0);

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

            Context.Emit(OpCodes.Br_S, LblEnd);

            Context.MarkLabel(LblNaN);

            EmitSetNZCV(Context, 0b0011);

            Context.MarkLabel(LblEnd);
        }