public static void Fmov_Itof1(ILEmitterCtx context) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; context.EmitLdintzr(op.Rn); EmitIntZeroUpperIfNeeded(context); EmitVectorInsert(context, op.Rd, 1, 3); }
public static void Fmov_Ftoi1(ILEmitterCtx context) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; EmitVectorExtractZx(context, op.Rn, 1, 3); EmitIntZeroUpperIfNeeded(context); context.EmitStintzr(op.Rd); }
public static void Scvtf_Gp(ILEmitterCtx context) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; context.EmitLdintzr(op.Rn); if (context.CurrOp.RegisterSize == RegisterSize.Int32) { context.Emit(OpCodes.Conv_U4); } EmitFloatCast(context, op.Size); EmitScalarSetF(context, op.Rd, op.Size); }
public static void Ucvtf_Gp_Fixed(ILEmitterCtx context) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; context.EmitLdintzr(op.Rn); if (context.CurrOp.RegisterSize == RegisterSize.Int32) { context.Emit(OpCodes.Conv_U4); } context.Emit(OpCodes.Conv_R_Un); EmitFloatCast(context, op.Size); EmitI2fFBitsMul(context, op.Size, op.FBits); EmitScalarSetF(context, op.Rd, op.Size); }
private static void EmitFcvtz__Gp_Fixed(ILEmitterCtx context, bool signed) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; EmitVectorExtractF(context, op.Rn, 0, op.Size); if (signed) { EmitScalarFcvts(context, op.Size, op.FBits); } else { EmitScalarFcvtu(context, op.Size, op.FBits); } if (context.CurrOp.RegisterSize == RegisterSize.Int32) { context.Emit(OpCodes.Conv_U8); } context.EmitStintzr(op.Rd); }
private static void EmitSse41Fcvt_Signed_Gp(ILEmitterCtx context, RoundMode roundMode, bool isFixed) { OpCodeSimdCvt64 op = (OpCodeSimdCvt64)context.CurrOp; if (op.Size == 0) { Type[] typesCmpMul = new Type[] { typeof(Vector128 <float>), typeof(Vector128 <float>) }; Type[] typesAnd = new Type[] { typeof(Vector128 <long>), typeof(Vector128 <long>) }; Type[] typesRndCvt = new Type[] { typeof(Vector128 <float>) }; Type[] typesCvt = new Type[] { typeof(Vector128 <int>) }; Type[] typesSav = new Type[] { typeof(int) }; //string nameCvt; int fpMaxVal; if (op.RegisterSize == RegisterSize.Int32) { //nameCvt = nameof(Sse.ConvertToInt32); fpMaxVal = 0x4F000000; // 2.14748365E9f (2147483648) } else { //nameCvt = nameof(Sse.ConvertToInt64); fpMaxVal = 0x5F000000; // 9.223372E18f (9223372036854775808) } context.EmitLdvec(op.Rn); context.EmitLdvec(op.Rn); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareOrdered), typesCmpMul)); context.EmitLdvec(op.Rn); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAnd)); if (isFixed) { // BitConverter.Int32BitsToSingle(fpScaled) == MathF.Pow(2f, op.FBits) int fpScaled = 0x40000000 + (op.FBits - 1) * 0x800000; context.EmitLdc_I4(fpScaled); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesCmpMul)); } context.EmitCall(typeof(Sse41).GetMethod(GetSse41NameRnd(roundMode), typesRndCvt)); context.EmitStvectmp(); context.EmitLdvectmp(); // TODO: Use Sse.ConvertToInt64 once it is fixed (in .NET Core 3.0), // remove the following if/else and uncomment the code. //context.EmitCall(typeof(Sse).GetMethod(nameCvt, typesRndCvt)); if (op.RegisterSize == RegisterSize.Int32) { context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.ConvertToInt32), typesRndCvt)); } else { context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Double), typesRndCvt)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt64), new Type[] { typeof(Vector128 <double>) })); } context.EmitLdvectmp(); context.EmitLdc_I4(fpMaxVal); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.CompareGreaterThanOrEqual), typesCmpMul)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt32), typesCvt)); if (op.RegisterSize == RegisterSize.Int32) { context.Emit(OpCodes.Xor); context.Emit(OpCodes.Conv_U8); } else { context.Emit(OpCodes.Conv_I8); context.Emit(OpCodes.Xor); } context.EmitStintzr(op.Rd); } else /* if (op.Size == 1) */ { Type[] typesCmpMul = new Type[] { typeof(Vector128 <double>), typeof(Vector128 <double>) }; Type[] typesAnd = new Type[] { typeof(Vector128 <long>), typeof(Vector128 <long>) }; Type[] typesRndCvt = new Type[] { typeof(Vector128 <double>) }; Type[] typesCvt = new Type[] { typeof(Vector128 <int>) }; Type[] typesSav = new Type[] { typeof(long) }; string nameCvt; long fpMaxVal; if (op.RegisterSize == RegisterSize.Int32) { nameCvt = nameof(Sse2.ConvertToInt32); fpMaxVal = 0x41E0000000000000L; // 2147483648.0000000d (2147483648) } else { nameCvt = nameof(Sse2.ConvertToInt64); fpMaxVal = 0x43E0000000000000L; // 9.2233720368547760E18d (9223372036854775808) } context.EmitLdvec(op.Rn); context.EmitLdvec(op.Rn); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareOrdered), typesCmpMul)); context.EmitLdvec(op.Rn); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesAnd)); if (isFixed) { // BitConverter.Int64BitsToDouble(fpScaled) == Math.Pow(2d, op.FBits) long fpScaled = 0x4000000000000000L + (op.FBits - 1) * 0x10000000000000L; context.EmitLdc_I8(fpScaled); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesCmpMul)); } context.EmitCall(typeof(Sse41).GetMethod(GetSse41NameRnd(roundMode), typesRndCvt)); context.EmitStvectmp(); context.EmitLdvectmp(); context.EmitCall(typeof(Sse2).GetMethod(nameCvt, typesRndCvt)); context.EmitLdvectmp(); context.EmitLdc_I8(fpMaxVal); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqual), typesCmpMul)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToInt32), typesCvt)); if (op.RegisterSize == RegisterSize.Int32) { context.Emit(OpCodes.Xor); context.Emit(OpCodes.Conv_U8); } else { context.Emit(OpCodes.Conv_I8); context.Emit(OpCodes.Xor); } context.EmitStintzr(op.Rd); } }