Esempio n. 1
0
        public static void EmitSseOrSse2CallF(AILEmitterCtx Context, string Name)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int SizeF = Op.Size & 1;

            void Ldvec(int Reg)
            {
                Context.EmitLdvec(Reg);

                if (SizeF == 1)
                {
                    AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorSingleToDouble));
                }
            }

            Ldvec(Op.Rn);

            Type Type;
            Type BaseType;

            if (SizeF == 0)
            {
                Type     = typeof(Sse);
                BaseType = typeof(Vector128 <float>);
            }
            else /* if (SizeF == 1) */
            {
                Type     = typeof(Sse2);
                BaseType = typeof(Vector128 <double>);
            }

            if (Op is AOpCodeSimdReg BinOp)
            {
                Ldvec(BinOp.Rm);

                Context.EmitCall(Type.GetMethod(Name, new Type[] { BaseType, BaseType }));
            }
            else
            {
                Context.EmitCall(Type.GetMethod(Name, new Type[] { BaseType }));
            }

            if (SizeF == 1)
            {
                AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorDoubleToSingle));
            }

            Context.EmitStvec(Op.Rd);

            if (Op.RegisterSize == ARegisterSize.SIMD64)
            {
                EmitVectorZeroUpper(Context, Op.Rd);
            }
        }
Esempio n. 2
0
        public static void Bsl_V(AILEmitterCtx Context)
        {
            if (AOptimizations.UseSse2)
            {
                AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

                Type[] Types = new Type[]
                {
                    VectorUIntTypesPerSizeLog2[Op.Size],
                    VectorUIntTypesPerSizeLog2[Op.Size]
                };

                EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size);
                EmitLdvecWithUnsignedCast(Context, Op.Rm, Op.Size);

                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), Types));

                EmitLdvecWithUnsignedCast(Context, Op.Rd, Op.Size);

                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), Types));

                EmitLdvecWithUnsignedCast(Context, Op.Rm, Op.Size);

                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), Types));

                EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size);

                if (Op.RegisterSize == ARegisterSize.SIMD64)
                {
                    EmitVectorZeroUpper(Context, Op.Rd);
                }
            }
            else
            {
                EmitVectorTernaryOpZx(Context, () =>
                {
                    Context.EmitSttmp();
                    Context.EmitLdtmp();

                    Context.Emit(OpCodes.Xor);
                    Context.Emit(OpCodes.And);

                    Context.EmitLdtmp();

                    Context.Emit(OpCodes.Xor);
                });
            }
        }
Esempio n. 3
0
        public static void Fcvtl_V(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int SizeF = Op.Size & 1;

            int Elems = 4 >> SizeF;

            int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;

            for (int Index = 0; Index < Elems; Index++)
            {
                if (SizeF == 0)
                {
                    EmitVectorExtractZx(Context, Op.Rn, Part + Index, 1);
                    Context.Emit(OpCodes.Conv_U2);

                    Context.EmitLdarg(ATranslatedSub.StateArgIdx);

                    Context.EmitCall(typeof(ASoftFloat16_32), nameof(ASoftFloat16_32.FPConvert));
                }
                else /* if (SizeF == 1) */
                {
                    EmitVectorExtractF(Context, Op.Rn, Part + Index, 0);

                    Context.Emit(OpCodes.Conv_R8);
                }

                EmitVectorInsertTmpF(Context, Index, SizeF);
            }

            Context.EmitLdvectmp();
            Context.EmitStvec(Op.Rd);
        }
Esempio n. 4
0
        public static void EmitWriteCall(AILEmitterCtx Context, int Size)
        {
            if (Size < 0 || Size > 4)
            {
                throw new ArgumentOutOfRangeException(nameof(Size));
            }

            if (Size < 3)
            {
                Context.Emit(OpCodes.Conv_I4);
            }

            string Name = null;

            switch (Size)
            {
            case 0: Name = nameof(AMemory.WriteByte);      break;

            case 1: Name = nameof(AMemory.WriteUInt16);    break;

            case 2: Name = nameof(AMemory.WriteUInt32);    break;

            case 3: Name = nameof(AMemory.WriteUInt64);    break;

            case 4: Name = nameof(AMemory.WriteVector128); break;
            }

            Context.EmitCall(typeof(AMemory), Name);
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        public static void Und(AILEmitterCtx Context)
        {
            AOpCode Op = Context.CurrOp;

            Context.EmitStoreState();

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            Context.EmitLdc_I8(Op.Position);
            Context.EmitLdc_I4(Op.RawOpCode);

            string MthdName = nameof(AThreadState.OnUndefined);

            MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);

            Context.EmitCall(MthdInfo);

            if (Context.CurrBlock.Next != null)
            {
                Context.EmitLoadState(Context.CurrBlock.Next);
            }
            else
            {
                Context.EmitLdc_I8(Op.Position + 4);

                Context.Emit(OpCodes.Ret);
            }
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
        public static void Fcvtl_V(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int SizeF = Op.Size & 1;

            int Elems = 4 >> SizeF;

            int Part = Context.CurrOp.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0;

            for (int Index = 0; Index < Elems; Index++)
            {
                if (SizeF == 0)
                {
                    EmitVectorExtractZx(Context, Op.Rn, Part + Index, 1);
                    Context.Emit(OpCodes.Conv_U2);

                    Context.EmitCall(typeof(ASoftFloat), nameof(ASoftFloat.ConvertHalfToSingle));
                }
                else /* if (SizeF == 1) */
                {
                    EmitVectorExtractF(Context, Op.Rn, Part + Index, 0);

                    Context.Emit(OpCodes.Conv_R8);
                }

                EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
            }
        }
Esempio n. 9
0
        public static void Ushr_V(AILEmitterCtx Context)
        {
            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;

            if (AOptimizations.UseSse2 && Op.Size > 0)
            {
                Type[] TypesSrl = new Type[] { VectorUIntTypesPerSizeLog2[Op.Size], typeof(byte) };

                EmitLdvecWithUnsignedCast(Context, Op.Rn, Op.Size);

                Context.EmitLdc_I4(GetImmShr(Op));
                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), TypesSrl));

                EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size);

                if (Op.RegisterSize == ARegisterSize.SIMD64)
                {
                    EmitVectorZeroUpper(Context, Op.Rd);
                }
            }
            else
            {
                EmitShrImmOp(Context, ShrImmFlags.VectorZx);
            }
        }
Esempio n. 10
0
        public static void Sbc(AILEmitterCtx Context)
        {
            EmitDataLoadOpers(Context);

            Context.Emit(OpCodes.Sub);

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

            Type[] MthdTypes = new Type[] { typeof(bool) };

            MethodInfo MthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), MthdTypes);

            Context.EmitCall(MthdInfo);

            Context.EmitLdc_I4(1);

            Context.Emit(OpCodes.Xor);

            if (Context.CurrOp.RegisterSize != ARegisterSize.Int32)
            {
                Context.Emit(OpCodes.Conv_I8);
            }

            Context.Emit(OpCodes.Sub);

            EmitDataStore(Context);
        }
Esempio n. 11
0
        private static void EmitSbc(AILEmitterCtx Context, bool SetFlags)
        {
            EmitDataLoadOpers(Context);

            Context.Emit(OpCodes.Sub);

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

            Type[] MthdTypes = new Type[] { typeof(bool) };

            MethodInfo MthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), MthdTypes);

            Context.EmitCall(MthdInfo);

            Context.EmitLdc_I4(1);

            Context.Emit(OpCodes.Xor);

            if (Context.CurrOp.RegisterSize != ARegisterSize.Int32)
            {
                Context.Emit(OpCodes.Conv_U8);
            }

            Context.Emit(OpCodes.Sub);

            if (SetFlags)
            {
                Context.EmitZNFlagCheck();

                EmitSbcsCCheck(Context);
                EmitSubsVCheck(Context);
            }

            EmitDataStore(Context);
        }
Esempio n. 12
0
        public static void EmitRoundMathCall(AILEmitterCtx Context, MidpointRounding RoundMode)
        {
            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;

            int SizeF = Op.Size & 1;

            Context.EmitLdc_I4((int)RoundMode);

            MethodInfo MthdInfo;

            Type[] Types = new Type[] { null, typeof(MidpointRounding) };

            Types[0] = SizeF == 0
                ? typeof(float)
                : typeof(double);

            if (SizeF == 0)
            {
                MthdInfo = typeof(MathF).GetMethod(nameof(MathF.Round), Types);
            }
            else /* if (SizeF == 1) */
            {
                MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types);
            }

            Context.EmitCall(MthdInfo);
        }
Esempio n. 13
0
 private static void EmitBarrier(AILEmitterCtx Context)
 {
     //Note: This barrier is most likely not necessary, and probably
     //doesn't make any difference since we need to do a ton of stuff
     //(software MMU emulation) to read or write anything anyway.
     Context.EmitCall(typeof(Thread), nameof(Thread.MemoryBarrier));
 }
Esempio n. 14
0
        public static void EmitRoundMathCall(AILEmitterCtx Context, MidpointRounding RoundMode)
        {
            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;

            Context.EmitLdc_I4((int)RoundMode);

            MethodInfo MthdInfo;

            Type[] Types = new Type[] { null, typeof(MidpointRounding) };

            Types[0] = Op.Size == 0
                ? typeof(float)
                : typeof(double);

            if (Op.Size == 0)
            {
                MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types);
            }
            else if (Op.Size == 1)
            {
                MthdInfo = typeof(Math).GetMethod(nameof(Math.Round), Types);
            }
            else
            {
                throw new InvalidOperationException();
            }

            Context.EmitCall(MthdInfo);
        }
Esempio n. 15
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);
        }
Esempio n. 16
0
        public static void Fcvt_S(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            if (AOptimizations.UseSse2)
            {
                if (Op.Size == 1 && Op.Opc == 0)
                {
                    //Double -> Single.
                    AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorSingleZero));

                    EmitLdvecWithCastToDouble(Context, Op.Rn);

                    Type[] Types = new Type[] { typeof(Vector128 <float>), typeof(Vector128 <double>) };

                    Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Single), Types));

                    Context.EmitStvec(Op.Rd);
                }
                else if (Op.Size == 0 && Op.Opc == 1)
                {
                    //Single -> Double.
                    AVectorHelper.EmitCall(Context, nameof(AVectorHelper.VectorDoubleZero));

                    Context.EmitLdvec(Op.Rn);

                    Type[] Types = new Type[] { typeof(Vector128 <double>), typeof(Vector128 <float>) };

                    Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Double), Types));

                    EmitStvecWithCastFromDouble(Context, Op.Rd);
                }
                else
                {
                    //Invalid encoding.
                    throw new InvalidOperationException();
                }
            }
            else
            {
                EmitVectorExtractF(Context, Op.Rn, 0, Op.Size);

                EmitFloatCast(Context, Op.Opc);

                EmitScalarSetF(Context, Op.Rd, Op.Opc);
            }
        }
Esempio n. 17
0
        public static void Fmadd_S(AILEmitterCtx Context)
        {
            if (AOptimizations.UseSse2)
            {
                AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

                if (Op.Size == 0)
                {
                    Context.EmitLdvec(Op.Ra);
                    Context.EmitLdvec(Op.Rn);
                    Context.EmitLdvec(Op.Rm);

                    Type[] Types = new Type[] { typeof(Vector128 <float>), typeof(Vector128 <float>) };

                    Context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MultiplyScalar), Types));
                    Context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AddScalar), Types));

                    Context.EmitStvec(Op.Rd);

                    EmitVectorZero32_128(Context, Op.Rd);
                }
                else /* if (Op.Size == 1) */
                {
                    EmitLdvecWithCastToDouble(Context, Op.Ra);
                    EmitLdvecWithCastToDouble(Context, Op.Rn);
                    EmitLdvecWithCastToDouble(Context, Op.Rm);

                    Type[] Types = new Type[] { typeof(Vector128 <double>), typeof(Vector128 <double>) };

                    Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), Types));
                    Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), Types));

                    EmitStvecWithCastFromDouble(Context, Op.Rd);

                    EmitVectorZeroUpper(Context, Op.Rd);
                }
            }
            else
            {
                EmitScalarTernaryRaOpF(Context, () =>
                {
                    Context.Emit(OpCodes.Mul);
                    Context.Emit(OpCodes.Add);
                });
            }
        }
Esempio n. 18
0
        private static void EmitVectorSmax(AILEmitterCtx Context)
        {
            Type[] Types = new Type[] { typeof(long), typeof(long) };

            MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Max), Types);

            EmitVectorBinarySx(Context, () => Context.EmitCall(MthdInfo));
        }
Esempio n. 19
0
        public static void Smin_V(AILEmitterCtx Context)
        {
            Type[] Types = new Type[] { typeof(long), typeof(long) };

            MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Min), Types);

            EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo));
        }
Esempio n. 20
0
        public static void Uminp_V(AILEmitterCtx Context)
        {
            Type[] Types = new Type[] { typeof(ulong), typeof(ulong) };

            MethodInfo MthdInfo = typeof(Math).GetMethod(nameof(Math.Min), Types);

            EmitVectorPairwiseOpZx(Context, () => Context.EmitCall(MthdInfo));
        }
        private static void EmitAbd(AILEmitterCtx Context)
        {
            Context.Emit(OpCodes.Sub);

            Type[] Types = new Type[] { typeof(long) };

            Context.EmitCall(typeof(Math).GetMethod(nameof(Math.Abs), Types));
        }
Esempio n. 22
0
        public static void Srsra_V(AILEmitterCtx Context)
        {
            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;

            if (AOptimizations.UseSse2 && Op.Size > 0 &&
                Op.Size < 3)
            {
                Type[] TypesShs = new Type[] { VectorIntTypesPerSizeLog2[Op.Size], typeof(byte) };
                Type[] TypesAdd = new Type[] { VectorIntTypesPerSizeLog2[Op.Size], VectorIntTypesPerSizeLog2[Op.Size] };

                int Shift = GetImmShr(Op);
                int ESize = 8 << Op.Size;

                EmitLdvecWithSignedCast(Context, Op.Rd, Op.Size);
                EmitLdvecWithSignedCast(Context, Op.Rn, Op.Size);

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

                Context.EmitLdc_I4(ESize - Shift);
                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), TypesShs));

                Context.EmitLdc_I4(ESize - 1);
                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), TypesShs));

                Context.EmitLdvectmp();

                Context.EmitLdc_I4(Shift);
                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), TypesShs));

                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), TypesAdd));
                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), TypesAdd));

                EmitStvecWithSignedCast(Context, Op.Rd, Op.Size);

                if (Op.RegisterSize == ARegisterSize.SIMD64)
                {
                    EmitVectorZeroUpper(Context, Op.Rd);
                }
            }
            else
            {
                EmitVectorShrImmOpSx(Context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
            }
        }
Esempio n. 23
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();
            }
        }
Esempio n. 24
0
        private static void EmitNaNCheck(AILEmitterCtx Context, int Reg)
        {
            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;

            EmitVectorExtractF(Context, Reg, 0, Op.Size);

            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();
            }
        }
Esempio n. 25
0
        private static void EmitSse42Crc32(AILEmitterCtx Context, Type TCrc, Type TData)
        {
            AOpCodeAluRs Op = (AOpCodeAluRs)Context.CurrOp;

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

            Context.EmitCall(typeof(Sse42).GetMethod(nameof(Sse42.Crc32), new Type[] { TCrc, TData }));

            Context.EmitStintzr(Op.Rd);
        }
Esempio n. 26
0
        public static void EmitSoftFloatCall(AILEmitterCtx Context, string Name)
        {
            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;

            Type Type = (Op.Size & 1) == 0
                ? typeof(ASoftFloat_32)
                : typeof(ASoftFloat_64);

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            Context.EmitCall(Type, Name);
        }
Esempio n. 27
0
        private static void EmitMemoryCall(AILEmitterCtx Context, string Name, int Rn = -1)
        {
            Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            if (Rn != -1)
            {
                Context.EmitLdint(Rn);
            }

            Context.EmitCall(typeof(AMemory), Name);
        }
Esempio n. 28
0
        public static void EmitWriteCall(AILEmitterCtx Context, int Size)
        {
            bool IsSimd = GetIsSimd(Context);

            string Name = null;

            if (Size < 0 || Size > (IsSimd ? 4 : 3))
            {
                throw new ArgumentOutOfRangeException(nameof(Size));
            }

            if (Size < 3 && !IsSimd)
            {
                Context.Emit(OpCodes.Conv_I4);
            }

            if (IsSimd)
            {
                switch (Size)
                {
                case 0: Name = nameof(AMemory.WriteVector8);   break;

                case 1: Name = nameof(AMemory.WriteVector16);  break;

                case 2: Name = nameof(AMemory.WriteVector32);  break;

                case 3: Name = nameof(AMemory.WriteVector64);  break;

                case 4: Name = nameof(AMemory.WriteVector128); break;
                }
            }
            else
            {
                switch (Size)
                {
                case 0: Name = nameof(AMemory.WriteByte);   break;

                case 1: Name = nameof(AMemory.WriteUInt16); break;

                case 2: Name = nameof(AMemory.WriteUInt32); break;

                case 3: Name = nameof(AMemory.WriteUInt64); break;
                }
            }

            Context.EmitCall(typeof(AMemory), Name);
        }
Esempio n. 29
0
        public static void Dup_Gp(AILEmitterCtx Context)
        {
            AOpCodeSimdIns Op = (AOpCodeSimdIns)Context.CurrOp;

            if (AOptimizations.UseSse2)
            {
                Context.EmitLdintzr(Op.Rn);

                switch (Op.Size)
                {
                case 0: Context.Emit(OpCodes.Conv_U1); break;

                case 1: Context.Emit(OpCodes.Conv_U2); break;

                case 2: Context.Emit(OpCodes.Conv_U4); break;
                }

                Type[] Types = new Type[] { UIntTypesPerSizeLog2[Op.Size] };

                Context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), Types));

                EmitStvecWithUnsignedCast(Context, Op.Rd, Op.Size);

                if (Op.RegisterSize == ARegisterSize.SIMD64)
                {
                    EmitVectorZeroUpper(Context, Op.Rd);
                }
            }
            else
            {
                int Bytes = Op.GetBitsCount() >> 3;
                int Elems = Bytes >> Op.Size;

                for (int Index = 0; Index < Elems; Index++)
                {
                    Context.EmitLdintzr(Op.Rn);

                    EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
                }

                if (Op.RegisterSize == ARegisterSize.SIMD64)
                {
                    EmitVectorZeroUpper(Context, Op.Rd);
                }
            }
        }
Esempio n. 30
0
        public static void Svc(AILEmitterCtx Context)
        {
            AOpCodeException Op = (AOpCodeException)Context.CurrOp;

            Context.EmitStoreState();

            Context.EmitLdarg(ATranslatedSub.RegistersArgIdx);

            Context.EmitLdc_I4(Op.Id);

            Context.EmitCall(typeof(ARegisters), nameof(ARegisters.OnSvcCall));

            if (Context.CurrBlock.Next != null)
            {
                Context.EmitLoadState(Context.CurrBlock.Next);
            }
        }