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); }
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); }
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); }
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); }
public static void Fmov_S(AILEmitterCtx Context) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; Context.EmitLdvecsf(Op.Rn); Context.EmitStvecsf(Op.Rd); }
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); }
private static void EmitMathOp2(AILEmitterCtx Context, string Name) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; Context.EmitLdvecsf(Op.Rn); EmitMathOpCall(Context, Name); Context.EmitStvecsf(Op.Rd); }
public static void Fcvt_S(AILEmitterCtx Context) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; Context.EmitLdvecsf(Op.Rn); EmitFloatCast(Context, Op.Opc); Context.EmitStvecsf(Op.Rd); }
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); }
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); }
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); }
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(); } }
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); }
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); }