// VCVT: convert vector elements (32-bit) between floating-point and fixed point public static void Vcvt_V2(ArmEmitterContext context) { OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp; var toFixed = op.Opc == 1; int fracBits = op.Fbits; var unsigned = op.U; // Sign of I32 (destination/source) if (toFixed) // F32 to S32 or U32 (fixed) { EmitVectorUnaryOpF32(context, (op1) => { var a = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits))); var rounded = EmitUnaryMathCall(context, nameof(MathF.Truncate), a); MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32)); return(context.Call(info, rounded)); }); } else // S32 or U32 (fixed) to F32 { EmitVectorUnaryOpI32(context, (op1) => { var f = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1); return(context.Multiply(f, ConstF(1f / MathF.Pow(2f, fracBits)))); }, !unsigned); } }
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed) { Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); if (signed) { return(context.ConvertToFP(type, value)); } else { return(context.ConvertToFPUI(type, value)); } }
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed) { Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64); Debug.Assert((uint)size < 2); OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64; if (signed) { return(context.ConvertToFP(type, value)); } else { return(context.ConvertToFPUI(type, value)); } }