diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-07-06 08:40:31 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-06 13:40:31 +0200 |
| commit | f7ef6364b79ba04af5c7bf0f5ec77fbb6b4aae29 (patch) | |
| tree | 21cb107e245c3bb788a9110b1b625735920478bc /ARMeilleure/Instructions/InstEmitSimdCvt.cs | |
| parent | b46b63e06a36845175f68331edb5ddeeb34de27b (diff) | |
Implement CPU FCVT Half <-> Double conversion variants (#3439)
* Half <-> Double conversion support
* Add tests, fast path and deduplicate SoftFloat code
* PPTC version
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSimdCvt.cs')
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSimdCvt.cs | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt.cs b/ARMeilleure/Instructions/InstEmitSimdCvt.cs index 84d81fac..6994643e 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt.cs @@ -105,11 +105,48 @@ namespace ARMeilleure.Instructions } else if (op.Size == 1 && op.Opc == 3) // Double -> Half. { - throw new NotImplementedException("Double-precision to half-precision."); + if (Optimizations.UseF16c) + { + Debug.Assert(!Optimizations.ForceLegacySse); + + Operand n = GetVec(op.Rn); + + Operand res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), n); + res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest))); + + context.Copy(GetVec(op.Rd), res); + } + else + { + Operand ne = context.VectorExtract(OperandType.FP64, GetVec(op.Rn), 0); + + Operand res = context.Call(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)), ne); + + res = context.ZeroExtend16(OperandType.I64, res); + + context.Copy(GetVec(op.Rd), EmitVectorInsert(context, context.VectorZero(), res, 0, 1)); + } } - else if (op.Size == 3 && op.Opc == 1) // Double -> Half. + else if (op.Size == 3 && op.Opc == 1) // Half -> Double. { - throw new NotImplementedException("Half-precision to double-precision."); + if (Optimizations.UseF16c) + { + Operand n = GetVec(op.Rn); + + Operand res = context.AddIntrinsic(Intrinsic.X86Vcvtph2ps, GetVec(op.Rn)); + res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res); + res = context.VectorZeroUpper64(res); + + context.Copy(GetVec(op.Rd), res); + } + else + { + Operand ne = EmitVectorExtractZx(context, op.Rn, 0, 1); + + Operand res = context.Call(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)), ne); + + context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); + } } else // Invalid encoding. { |
