Skip to content

[API Proposal]: Expose AVX512 FP16 and AVX F16C ISA #98820

Open
@anthonycanino

Description

Background and motivation

This proposal allows to accelerate FP16 operations through Intel's FP16 ISAs. Both F16c and AVX512 FP16 are covered.

We use System.Half datatype --- the managed implementation of FP16 in .NET --- as the foundational datatype for the FP16 operations. Note that this proposal exposes the API for latter implementation, but it will require some .NET internal rework, particularly around the use of System.Half as a hardware accelerated vectorized data type.

API Proposal

class F16c : Avx2
{
    // vcvtph2ps
    public static Vector128<float> ConvertToVector128Single(Vector128<Half> value);
    public static Vector256<float> ConvertToVector256Single(Vector128<Half> value);

    // vcvtps2ph
    public static Vector128<Half> ConvertToVector128Half(Vector128<float> value, byte control);
    public static Vector128<Half> ConvertToVector128Half(Vector256<float> value, byte control);
}

class Avx512Fp16 : Avx512F
{
    // vaddph
    public static Vector512<Half> Add(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> Add(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vdivph
    public static Vector512<Half> Divide(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> Divide(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vgetexpph
    public static Vector512<Half> GetExponent(Vector512<Half> value);

    // vgetmantph
    public static Vector512<Half> GetMantissa(Vector512<Half> value, byte control);

    // vmaxph
    public static Vector512<Half> Max(Vector512<Half> left, Vector512<Half> right);

    // vminph
    public static Vector512<Half> Min(Vector512<Half> value, Vector512<Half> right);

    // vmulph
    public static Vector512<Half> Multiply(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> Multiply(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vrcpph
    public static Vector512<Half> Reciprocal(Vector512<Half> value);

    // vreduceph
    public static Half Reduce(Vector512<Half> left, byte control);

    // vrndscaleph
    public static Vector512<Half> RoundScale(Vector512<Half> left, byte control);

    // vrsqrtph
    public static Vector512<Half> ReciprocalSqrt(Vector512<Half> value);
    public static Vector512<Half> ReciprocalSqrt(Vector512<Half> value, FloatRoundingMode mode);

    // vscalefph
    public static Vector512<Half> Scale(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> Scale(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vsqrtph
    public static Vector512<Half> Sqrt(Vector512<Half> value);
    public static Vector512<Half> Sqrt(Vector512<Half> value, FloatRoundingMode mode);

    // vsubph
    public static Vector512<Half> Subtract(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> Subtract(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vfcmaddcph
    public static Vector512<Half> FusedComplexMultiplyAdd(Vector512<Half> addend, Vector512<Half> left, Vector512<Half> right);

    // vfmaddcph
    public static Vector512<Half> FusedComplexMultiplyAddConjugate(Vector512<Half> addend, Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> FusedComplexMultiplyAddConjugate(Vector512<Half> addend, Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vfmulcph
    public static Vector512<Half> ComplexMultiply(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> ComplexMultiply(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vfcmulcph
    public static V0ector512<Half> ComplexMultiplyConjugate(Vector512<Half> left, Vector512<Half> right);
    public static V0ector512<Half> ComplexMultiplyConjugate(Vector512<Half> left, Vector512<Half> right, FloatRoundingMode mode);

    // vfmaddsubXXXph
    public static Vector512<Half> FusedMultiplyAddSubtract(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c);
    public static Vector512<Half> FusedMultiplyAddSubtract(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c, FloatRoudingMode mode);

    // vfmsubaddXXXph
    public static Vector512<Half> FusedMultiplySubtractAdd(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c);
    public static Vector512<Half> FusedMultiplySubtractAdd(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c, FloatRoundingMode mode);

    // vfmaddXXXph
    public static Vector512<Half> FusedMultiplyAdd(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c);
    public static Vector512<Half> FusedMultiplyAdd(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c, FloatRoundingMode mode);

    // vfmsubXXXph
    public static Vector512<Half> FusedMultiplySubtract(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c);
    public static Vector512<Half> FusedMultiplySubtract(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c, FloatRoundingMode mode);

    // vfnmaddXXXph
    public static Vector512<Half> FusedMultiplyAddNegated(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c);
    public static Vector512<Half> FusedMultiplyAddNegated(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c, FloatRoundingMode mode);

    // vfnmsubXXXph
    public static Vector512<Half> FusedMultiplySubtractNegated(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c);
    public static Vector512<Half> FusedMultiplySubtractNegated(Vector512<Half> a, Vector512<Half> b, Vector512<Half> c, FloatRoundingMode mode);

    // vcmpph
    public static Vector512<Half> Compare(Vector512<Half> left, Vector512<Half> right, FloatComparisonMode mode);
    public static Vector512<Half> CompareEqual(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareGreaterThan(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareGreaterThanOrEqual(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareLessThan(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareLessThanOrEqual(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareNotEqual(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareNotGreaterThan(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareNotGreaterThanOrEqual(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareNotLessThan(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareNotLessThanOrEqual(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareOrdered(Vector512<Half> left, Vector512<Half> right);
    public static Vector512<Half> CompareUnordered(Vector512<Half> left, Vector512<Half> right);

    // vfpclassph
    public static Vector512<Half> Classify(Vector512<Half> value, byte control);

    // vcvtw2ph
    public static Vector512<Half> ConvertToVector512Half(Vector512<short> value);
    public static Vector512<Half> ConvertToVector512Half(Vector512<short> value, FloatRoundingMode mode);

    // vcvtdq2ph
    public static Vector256<Half> ConvertToVector256Half(Vector512<int> value);
    public static Vector256<Half> ConvertToVector256Half(Vector512<int> value, FloatRoundingMode mode);

    // vcvtqq2ph
    public static Vector128<Half> ConvertToVector128Half(Vector512<long> value);
    public static Vector128<Half> ConvertToVector128Half(Vector512<long> value, FloatRoundingMode mode);

    // vcvtuw2ph
    public static Vector512<Half> ConvertToVector512Half(Vector512<ushort> value);
    public static Vector512<Half> ConvertToVector512Half(Vector512<ushort> value, FloatRoundingMode mode);

    // vcvtudq2ph
    public static Vector256<Half> ConvertToVector256Half(Vector512<uint> value);
    public static Vector256<Half> ConvertToVector256Half(Vector512<uint> value, FloatRoundingMode mode);

    // vcvtuqq2ph
    public static Vector128<Half> ConvertToVector128Half(Vector512<ulong> value);
    public static Vector128<Half> ConvertToVector128Half(Vector512<ulong> value, FloatRoundingMode mode);

    // vcvtps2ph
    public static Vector256<Half> ConvertToVector256Half(Vector512<float> value);
    public static Vector256<Half> ConvertToVector256Half(Vector512<float> value, FloatRoundingMode mode);

    // vcvtpd2ph
    public static Vector128<Half> ConvertToVector128Half(Vector512<double> value);
    public static Vector128<Half> ConvertToVector128Half(Vector512<double> value, FloatRoundingMode mode);

    // vcvtph2w
    public static Vector512<short> ConvertToVector512Int16(Vector512<Half> value);
    public static Vector512<short> ConvertToVector512Int16(Vector512<Half> value, FloatRoundingMode mode)

    // vcvttph2w
    public static Vector512<short> ConvertToVector512Int16WithTruncation(Vector512<Half> value);

    // vcvtph2dq
    public static Vector512<int> ConvertToVector512Int32(Vector256<Half> value);
    public static Vector512<int> ConvertToVector512Int32(Vector256<Half> value, FloatRoundingMode mode);

    // vcvttph2dq
    public static Vector512<int> ConvertToVector512Int32WithTruncation(Vector256<Half> value);

    // vcvtph2qq
    public static Vector512<long> ConvertToVector512Int64(Vector128<Half> value);
    public static Vector512<long> ConvertToVector512Int64(Vector128<Half> value, FloatRoundingMode mode);

    // vcvttph2qq
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector128<Half> value);

    // vcvtph2uw
    public static Vector512<ushort> ConvertToVector512UInt16(Vector512<Half> value);
    public static Vector512<ushort> ConvertToVector512UInt16(Vector512<Half> value, FloatRoundingMode mode);

    // vcvttph2uw
    public static Vector512<ushort> ConvertToVector512UInt16WithTruncation(Vector512<Half> value);

    // vcvtph2udq
    public static Vector512<uint> ConvertToVector512UInt32(Vector256<Half> value);
    public static Vector512<uint> ConvertToVector512UInt32(Vector256<Half> value, FloatRoundingMode mode);

    // vcvttph2udq
    public static Vector512<uint> ConvertToVector512UInt32WithTruncation(Vector256<Half> value);

    // vcvtph2uqq
    public static Vector512<ulong> ConvertToVector512UInt64(Vector128<Half> value);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector128<Half> value, FloatRoundingMode mode);

    // vcvttph2uqq
    public static Vector512<ulong> ConvertToVector512UInt64WithTruncation(Vector128<Half> value);

    // vcvtph2ps
    public static Vector512<float> ConvertToVector512Single(Vector256<Half> value);

    // vcvtph2pd
    public static Vector512<double> ConvertToVector512Double(Vector128<Half> value);
    public static Vector512<double> ConvertToVector512Double(Vector128<Half> value, FloatRoundingMode mode);

    // SCALAR Ops

    // vaddsh
    public static Vector128<Half> AddScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> AddScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vdivsh
    public static Vector128<Half> DivideScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> DivideScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vgetexpss
    public static Vector128<Half> GetExponentScalar(Vector128<Half> value);

    // vgetmantsh
    public static Vector128<Half> GetMantissaScalar(Vector128<Half> value, byte control);

    // vmaxpsh
    public static Vector128<Half> MaxScalar(Vector128<Half> left, Vector128<Half> right);

    // vminsh
    public static Vector128<Half> MinScalar(Vector128<Half> value, Vector128<Half> right);

    // vmulsh
    public static Vector128<Half> MultiplyScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> MultiplyScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vrcpsh
    public static Vector128<Half> ReciprocalScalar(Vector128<Half> value);

    // vreducesh
    public static Half ReduceScalar(Vector128<Half> left, byte control);

    // vrndscalesh
    public static Vector128<Half> RoundScaleScalar(Vector128<Half> left, byte control);

    // vrsqrtsh
    public static Vector128<Half> ReciprocalSqrtScalar(Vector128<Half> value);

    // vscalefsh
    public static Vector128<Half> ScaleScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> ScaleScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vsqrtsh
    public static Vector128<Half> SqrtScalar(Vector128<Half> value);
    public static Vector128<Half> SqrtScalar(Vector128<Half> value, FloatRoundingMode mode);

    // vsubsh
    public static Vector128<Half> SubtractScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> SubtractScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vfmaddcsh
    public static Vector128<Half> FusedComplexMultiplyAddScalar(Vector128<Half> addend, Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> FusedComplexMultiplyAddScalar(Vector128<Half> addend, Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vfcmaddcsh
    public static Vector128<Half> FusedComplexMultiplyAddConjugateScalar(Vector128<Half> addend, Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> FusedComplexMultiplyAddConjugateScalar(Vector128<Half> addend, Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vfmulcsh
    public static Vector128<Half> ComplexMultiplyScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> ComplexMultiplyScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vfcmulcsh
    public static Vector128<Half> ComplexMultiplyConjugateScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> ComplexMultiplyConjugateScalar(Vector128<Half> left, Vector128<Half> right, FloatRoundingMode mode);

    // vfmaddsubXXXsh
    public static Vector128<Half> FusedMultiplyAddSubtractScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);
    public static Vector128<Half> FusedMultiplyAddSubtractScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c, FloatRoundingMode mode);

    // vfmsubaddXXXsh
    public static Vector128<Half> FusedMultiplySubtractAddScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);
    public static Vector128<Half> FusedMultiplySubtractAddScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c, FloatRoundingMode mode);

    // vfmaddXXXsh
    public static Vector128<Half> FusedMultiplyAddScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);
    public static Vector128<Half> FusedMultiplyAddScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c, FloatRoundingMode mode);

    // vfmsubXXXsh
    public static Vector128<Half> FusedMultiplySubtractScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);
    public static Vector128<Half> FusedMultiplySubtractScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c, FloatRoundingMode mode);

    // vfnmaddXXXsh
    public static Vector128<Half> FusedMultiplyAddNegatedScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);
    public static Vector128<Half> FusedMultiplyAddNegatedScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c, FloatRoundingMode mode);

    // vfnmsubXXXsh
    public static Vector128<Half> FusedMultiplySubtractNegatedScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);
    public static Vector128<Half> FusedMultiplySubtractNegatedScalar(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c, FloatRoundingMode mode);

    // vcmpsh
    public static Vector128<Half> CompareScalar(Vector128<Half> left, Vector128<Half> right, FloatComparisonMode mode);
    public static Vector128<Half> CompareEqualScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareGreaterThanScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareGreaterThanOrEqualScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareLessThanScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareLessThanOrEqualScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareNotEqualScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareNotGreaterThanScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareNotGreaterThanOrEqualScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareNotLessThanScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareNotLessThanOrEqualScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareOrderedScalar(Vector128<Half> left, Vector128<Half> right);
    public static Vector128<Half> CompareUnorderedScalar(Vector128<Half> left, Vector128<Half> right);

    // vcomish
    public static bool CompareScalarOrderedEqual(Vector128<Half> left, Vector128<Half> right);
    public static bool CompareScalarOrderedGreaterThan(Vector128<Half> left, Vector128<Half> right);
    public static bool CompareScalarOrderedGreaterThanOrEqual(Vector128<Half> left, Vector128<Half> right);
    public static bool CompareScalarOrderedLessThan(Vector128<Half> left, Vector128<Half> right);
    public static bool CompareScalarOrderedLessThanOrEqual(Vector128<Half> left, Vector128<Half> right);
    public static bool CompareScalarOrderedNotEqual(Vector128<Half> left, Vector128<Half> right);

    // vucomish
    public static bool CompareScalarUnorderedEqual(Vector128<float> left, Vector128<float> right);
    public static bool CompareScalarUnorderedGreaterThan(Vector128<float> left, Vector128<float> right);
    public static bool CompareScalarUnorderedGreaterThanOrEqual(Vector128<float> left, Vector128<float> right);
    public static bool CompareScalarUnorderedLessThan(Vector128<float> left, Vector128<float> right);
    public static bool CompareScalarUnorderedLessThanOrEqual(Vector128<float> left, Vector128<float> right);
    public static bool CompareScalarUnorderedNotEqual(Vector128<float> left, Vector128<float> right);

    // vfpclasssh
    public static Vector128<Half> ClassifyScalar(Vector128<Half> value, byte control);

    // vcvtsi2sh
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, int value);
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, int value, FloatRoundingMode mode);

    // vcvtusi2sh
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, uint value);
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, uint value, FloatRoundingMode mode);

    // vcvtss2sh
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, Vector128<float> value);
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, Vector128<float> value, FloatRoundingMode mode);

    // vcvtsd2sh
    public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, Vector128<double> value);
 public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, Vector128<double> value, FloatRoundingMode mode);

    // vcvtsh2si
    public static int ConvertToInt32(Vector128<Half> value);
    public static int ConvertToInt32(Vector128<Half> value, FloatRoundingMode mode);

    // vcvttsh2si
    public static int ConvertToInt32WithTruncation(Vector128<Half> value);

    // vcvtsh2usi
    public static uint ConvertToUInt32(Vector128<Half> value);
    public static uint ConvertToUInt32(Vector128<Half> value, FloatRoundingMode mode);

    // vcvttsh2usi
    public static uint ConvertToUInt32WithTruncation(Vector128<Half> value);

    // vcvtsh2ss
    public static Vector128<float> ConvertScalarToVector128Single(Vector128<float> upper, Vector128<Half> value);
    public static Vector128<float> ConvertScalarToVector128Single(Vector128<float> upper, Vector128<Half> value, FloatRoundingMode mode);

    // vcvtsh2sd
    public static Vector128<double> ConvertScalarToVector128Double(Vector128<double> upper, Vector128<Half> value);
    public static Vector128<double> ConvertScalarToVector128Double(Vector128<double> upper, Vector128<Half> value, FloatRoundingMode mode);

    class X64 : Avx512F.X64
    {
        // vcvtsi2sh
        public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, long value);

        // vcvtusi2sh
        public static Vector128<Half> ConvertScalarToVector128Half(Vector128<Half> upper, ulong value);

        // vcvtsh2si
        public static long ConvertToInt64(Vector128<Half> value);

        // vcvttsh2si
        public static long ConvertToInt64WithTruncation(Vector128<Half> value);

        // vcvtsh2usi
        public static ulong ConvertToUInt64(Vector128<Half> value);

        // vcvttsh2usi
        public static ulong ConvertToUInt64WithTruncation(Vector128<Half> value);
    }

    class VL : Avx512F.VL
    {
        // vaddph
        public static Vector128<Half> Add(Vector128<Half> left, Vector128<Half> right);

        // vdivph
        public static Vector128<Half> Divide(Vector128<Half> left, Vector128<Half> right);

        // vgetexpph
        public static Vector128<Half> GetExponent(Vector128<Half> value);

        // vgetmantph
        public static Vector128<Half> GetMantissa(Vector128<Half> value, byte control);

        // vmaxph
        public static Vector128<Half> Max(Vector128<Half> left, Vector128<Half> right);

        // vminph
        public static Vector128<Half> Min(Vector128<Half> value, Vector128<Half> right);

        // vmulph
        public static Vector128<Half> Multiply(Vector128<Half> left, Vector128<Half> right);

        // vrcpph
        public static Vector128<Half> Reciprocal(Vector128<Half> value);

        // vreduceph
        public static Half Reduce(Vector128<Half> left, byte control);

        // vrndscaleph
        public static Vector128<Half> RoundScale(Vector128<Half> left, byte control);

        // vrsqrtph
        public static Vector128<Half> ReciprocalSqrt(Vector128<Half> value);

        // vscalefph
        public static Vector128<Half> Scale(Vector128<Half> left, Vector128<Half> right, byte control);

        // vsqrtph
        public static Vector128<Half> Sqrt(Vector128<Half> value);

        // vsubph
        public static Vector128<Half> Subtract(Vector128<Half> left, Vector128<Half> right);

        // vfcmaddcph
        public static Vector128<Half> FusedComplexMultiplyAdd(Vector128<Half> addend, Vector128<Half> left, Vector128<Half> right);

        // vfcmaddcph
        public static Vector128<Half> FusedComplexMultiplyAddConjugate(Vector128<Half> addend, Vector128<Half> left, Vector128<Half> right);

        // vfmulcph
        public static Vector128<Half> ComplexMultiply(Vector128<Half> left, Vector128<Half> right);

        // vfcmulcph
        public static Vector128<Half> ComplexMultiplyConjugate(Vector128<Half> left, Vector128<Half> right);

        // vfmaddsubXXXph
        public static Vector128<Half> FusedMultiplyAddSubtract(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);

        // vfmsubaddXXXph
        public static Vector128<Half> FusedMultiplySubtractAdd(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);

        // vfmaddXXXph
        public static Vector128<Half> FusedMultiplyAdd(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);

        // vfmsubXXXph
        public static Vector128<Half> FusedMultiplySubtract(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);

        // vfnmaddXXXph
        public static Vector128<Half> FusedMultiplyAddNegated(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);

        // vfnmsubXXXph
        public static Vector128<Half> FusedMultiplySubtractNegated(Vector128<Half> a, Vector128<Half> b, Vector128<Half> c);

        // vcmpph
        public static Vector128<Half> Compare(Vector128<Half> left, Vector128<Half> right, FloatComparisonMode mode);
        public static Vector128<Half> CompareEqual(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareGreaterThan(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareGreaterThanOrEqual(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareLessThan(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareLessThanOrEqual(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareNotEqual(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareNotGreaterThan(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareNotGreaterThanOrEqual(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareNotLessThan(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareNotLessThanOrEqual(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareOrdered(Vector128<Half> left, Vector128<Half> right);
        public static Vector128<Half> CompareUnordered(Vector128<Half> left, Vector128<Half> right);

        // vfpclassph
        public static Vector128<Half> Classify(Vector128<Half> value, byte control);

        // vcvtw2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<short> value);

        // vcvtdq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<int> value);

        // vcvtqq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<long> value);

        // vcvtuw2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<ushort> value);

        // vcvtudq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<uint> value);

        // vcvtuqq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<ulong> value);

        // vcvtps2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<float> value);

        // vcvtpd2ph
        public static Vector128<Half> ConvertToVector128Half(Vector128<double> value);

        // vcvtph2w
        public static Vector128<short> ConvertToVector128Int16(Vector128<Half> value);

        // vcvttph2w
        public static Vector128<short> ConvertToVector128Int16WithTruncation(Vector128<Half> value);

        // vcvtph2dq
        public static Vector128<int> ConvertToVector128Int32(Vector128<Half> value);

        // vcvttph2dq
        public static Vector128<int> ConvertToVector128Int32WithTruncation(Vector128<Half> value);

        // vcvtph2qq
        public static Vector128<long> ConvertToVector128Int64(Vector128<Half> value);

        // vcvttph2qq
        public static Vector128<long> ConvertToVector128Int64WithTruncation(Vector128<Half> value);

        // vcvtph2uw
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<Half> value);

        // vcvttph2uw
        public static Vector128<ushort> ConvertToVector128UInt16WithTruncation(Vector128<Half> value);

        // vcvtph2udq
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<Half> value);

        // vcvttph2udq
        public static Vector128<uint> ConvertToVector128UInt32WithTruncation(Vector128<Half> value);

        // vcvtph2uqq
        public static Vector128<ulong> ConvertToVector128UInt64(Vector128<Half> value);

        // vcvttph2uqq
        public static Vector128<ulong> ConvertToVector128UInt64WithTruncation(Vector128<Half> value);

        // vcvtph2ps
        public static Vector128<float> ConvertToVector128Single(Vector128<Half> value);

        // vcvtph2pd
        public static Vector128<double> ConvertToVector128Double(Vector128<Half> value);

        // 256
        // vaddph
        public static Vector256<Half> Add(Vector256<Half> left, Vector256<Half> right);

        // vdivph
        public static Vector256<Half> Divide(Vector256<Half> left, Vector256<Half> right);

        // vgetexpph
        public static Vector256<Half> GetExponent(Vector256<Half> value);

        // vgetmantph
        public static Vector256<Half> GetMantissa(Vector256<Half> value, byte control);

        // vmaxph
        public static Vector256<Half> Max(Vector256<Half> left, Vector256<Half> right);

        // vminph
        public static Vector256<Half> Min(Vector256<Half> value, Vector256<Half> right);

        // vmulph
        public static Vector256<Half> Multiply(Vector256<Half> left, Vector256<Half> right);

        // vrcpph
        public static Vector256<Half> Reciprocal(Vector256<Half> value);

        // vreduceph
        public static Half Reduce(Vector256<Half> left, byte control);

        // vrndscaleph
        public static Vector256<Half> RoundScale(Vector256<Half> left, byte control);

        // vrsqrtph
        public static Vector256<Half> ReciprocalSqrt(Vector256<Half> value);

        // vscalefph
        public static Vector256<Half> Scale(Vector256<Half> left, Vector256<Half> right, byte control);

        // vsqrtph
        public static Vector256<Half> Sqrt(Vector256<Half> value);

        // vsubph
        public static Vector256<Half> Subtract(Vector256<Half> left, Vector256<Half> right);

        // vfmaddcph
        public static Vector256<Half> FusedComplexMultiplyAdd(Vector256<Half> addend, Vector256<Half> left, Vector256<Half> right);

        // vfcaddlcph
        public static Vector256<Half> FusedComplexMultiplyAddConjugate(Vector256<Half> addend, Vector256<Half> left, Vector256<Half> right);

        // vfmulcph
        public static Vector256<Half> ComplexMultiply(Vector256<Half> left, Vector256<Half> right);

        // vfcmulcph
        public static Vector256<Half> ComplexMultiplyConjugate(Vector256<Half> left, Vector256<Half> right);

        // vfmaddsubXXXph
        public static Vector256<Half> FusedMultiplyAddSubtract(Vector256<Half> a, Vector256<Half> b, Vector256<Half> c);

        // vfmsubaddXXXph
        public static Vector256<Half> FusedMultiplySubtractAdd(Vector256<Half> a, Vector256<Half> b, Vector256<Half> c);

        // vfmaddXXXph
        public static Vector256<Half> FusedMultiplyAdd(Vector256<Half> a, Vector256<Half> b, Vector256<Half> c);

        // vfmsubXXXph
        public static Vector256<Half> FusedMultiplySubtract(Vector256<Half> a, Vector256<Half> b, Vector256<Half> c);

        // vfnmaddXXXph
        public static Vector256<Half> FusedMultiplyAddNegated(Vector256<Half> a, Vector256<Half> b, Vector256<Half> c);

        // vfnmsubXXXph
        public static Vector256<Half> FusedMultiplySubtractNegated(Vector256<Half> a, Vector256<Half> b, Vector256<Half> c);

        // vcmpph
        public static Vector256<Half> Compare(Vector256<Half> left, Vector256<Half> right, FloatComparisonMode mode);
        public static Vector256<Half> CompareEqual(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareGreaterThan(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareGreaterThanOrEqual(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareLessThan(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareLessThanOrEqual(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareNotEqual(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareNotGreaterThan(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareNotGreaterThanOrEqual(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareNotLessThan(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareNotLessThanOrEqual(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareOrdered(Vector256<Half> left, Vector256<Half> right);
        public static Vector256<Half> CompareUnordered(Vector256<Half> left, Vector256<Half> right);

        // vfpclassph
        public static Vector256<Half> Classify(Vector256<Half> value, byte control);

        // vcvtw2ph
        public static Vector256<Half> ConvertToVector256Half(Vector256<short> value);

        // vcvtdq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector256<int> value);

        // vcvtqq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector256<long> value);

        // vcvtuw2ph
        public static Vector256<Half> ConvertToVector256Half(Vector256<ushort> value);

        // vcvtudq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector256<uint> value);

        // vcvtuqq2ph
        public static Vector128<Half> ConvertToVector128Half(Vector256<ulong> value);

        // vcvtps2ph
        public static Vector128<Half> ConvertToVector128Half(Vector256<float> value);

        // vcvtpd2ph
        public static Vector128<Half> ConvertToVector128Half(Vector256<double> value);

        // vcvtph2w
        public static Vector256<short> ConvertToVector256Int16(Vector256<Half> value);

        // vcvttph2w
        public static Vector256<short> ConvertToVector256Int16WithTruncation(Vector256<Half> value);

        // vcvtph2dq
        public static Vector256<int> ConvertToVector256Int32(Vector128<Half> value);

        // vcvttph2dq
        public static Vector256<int> ConvertToVector256Int32WithTruncation(Vector128<Half> value);

        // vcvtph2qq
        public static Vector256<long> ConvertToVector256Int64(Vector128<Half> value);

        // vcvttph2qq
        public static Vector256<long> ConvertToVector256Int64WithTruncation(Vector128<Half> value);

        // vcvtph2uw
        public static Vector256<ushort> ConvertToVector256UInt16(Vector256<Half> value);

        // vcvttph2uw
        public static Vector256<ushort> ConvertToVector256UInt16WithTruncation(Vector256<Half> value);

        // vcvtph2udq
        public static Vector256<uint> ConvertToVector256UInt32(Vector128<Half> value);

        // vcvttph2udq
        public static Vector256<uint> ConvertToVector256UInt32WithTruncation(Vector128<Half> value);

        // vcvtph2uqq
        public static Vector256<ulong> ConvertToVector256UInt64(Vector128<Half> value);

        // vcvttph2uqq
        public static Vector256<ulong> ConvertToVector256UInt64WithTruncation(Vector128<Half> value);

        // vcvtph2ps
        public static Vector256<float> ConvertToVector256Single(Vector128<Half> value);

        // vcvtph2pd
        public static Vector256<double> ConvertToVector256Double(Vector128<Half> value);
    }
}

API Usage

N/A

Alternative Designs

N/A

Risks

N/A

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions