Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose System.Runtime.Intrinsics.X86.Avx512F.VL #74813

Closed
Tracked by #77034 ...
tannergooding opened this issue Aug 30, 2022 · 4 comments
Closed
Tracked by #77034 ...

Expose System.Runtime.Intrinsics.X86.Avx512F.VL #74813

tannergooding opened this issue Aug 30, 2022 · 4 comments
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.Intrinsics avx512 Related to the AVX-512 architecture
Milestone

Comments

@tannergooding
Copy link
Member

Summary

In addition to providing 512-bit versions of existing instructions, AVX512 also provides various new instructions that were not available in previous ISAs. It makes 128-bit and 256-bit versions of these instructions available under the AVX512VL ISA.

As described in #73604, AVX512VL is somewhat special in that it is not its own self-contained ISA. Rather, when the CPUID flag is present it extends each other AVX512 ISA with 128-bit and 256-bit instruction support.

Given we don't support multiple inheritance in .NET, the easiest way to model this using our existing semantics is to expose a nested class named VL. Just like with the nested X64 base class, it is only supported when the parent ISA is also supported. Likewise, for derived classes (such as Avx512BW), its own nested class can derive from Avx512F.VL and otherwise flow the normal ISA checks as expected. This also avoids needing to consider complexities for names such as Avx512BW_VL or some variant there-of.

API Proposal

We should expose the Avx512F.VL class as the first part of the AVX512 feature set.

public abstract partial class Avx512F : Avx2
{
    public abstract partial class VL
    {
        public static bool IsSupported { get; }

        // AVX512

        public static Vector256<int> BroadcastToVector256(Vector128<int> value);
        public static Vector256<uint> BroadcastToVector256(Vector128<uint> value);
        public static Vector256<float> BroadcastToVector256(Vector128<float> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<int> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<int> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<long> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<long> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<uint> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<uint> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<ulong> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<ulong> value);

        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<uint> value);
        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<uint> value);

        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<ulong> value);
        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<ulong> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<int> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<int> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<long> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<long> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<uint> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<uint> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<ulong> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<ulong> value);

        public static Vector128<int> ConvertToVector128Int32(Vector256<long> value);
        public static Vector128<int> ConvertToVector128Int32(Vector128<long> value);

        public static Vector128<int> ConvertToVector128Int32(Vector256<ulong> value);
        public static Vector128<int> ConvertToVector128Int32(Vector128<ulong> value);

        public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector256<long> value);
        public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector128<long> value);

        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<int> value);
        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<int> value);

        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<long> value);
        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<long> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<int> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<int> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<long> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<long> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<uint> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<uint> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<ulong> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<ulong> value);

        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<int> value);
        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<int> value);

        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<long> value);
        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<long> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<int> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<int> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<long> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<long> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<uint> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<uint> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<ulong> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<ulong> value);

        public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector256<uint> value);
        public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector128<uint> value);

        public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector256<long> value);
        public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector128<long> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<double> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<float> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<long> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<long> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<ulong> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<ulong> value);

        public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector256<ulong> value);
        public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector128<ulong> value);

        public static Vector256<double> ConvertToVector256Double(Vector128<uint> value);
        public static Vector128<double> ConvertToVector128Double(Vector128<uint> value);

        public static Vector256<float> ConvertToVector256Single(Vector128<uint> value);
        public static Vector128<float> ConvertToVector128Single(Vector128<uint> value);

        public static Vector256<double> Fixup(Vector256<double> left, Vector256<double> right, Vector256<long> table);
        public static Vector128<double> Fixup(Vector128<double> left, Vector128<double> right, Vector128<long> table);

        public static Vector256<float> Fixup(Vector256<float> left, Vector256<float> right, Vector256<int> table);
        public static Vector128<float> Fixup(Vector128<float> left, Vector128<float> right, Vector128<int> table);

        public static Vector256<double> GetExponent(Vector256<double> value);
        public static Vector128<double> GetExponent(Vector128<double> value);

        public static Vector256<float> GetExponent(Vector256<float> value);
        public static Vector128<float> GetExponent(Vector128<float> value);

        public static Vector256<double> GetMantissa(Vector256<double> value, byte interval, byte signControl);
        public static Vector128<double> GetMantissa(Vector128<double> value, byte interval, byte signControl);

        public static Vector256<float> GetMantissa(Vector256<float> value, byte interval, byte signControl);
        public static Vector128<float> GetMantissa(Vector128<float> value, byte interval, byte signControl);

        public static Vector128<double> PermuteVar2x64(Vector128<double> left, Vector128<double> right, Vector128<long> control);

        public static Vector128<long> PermuteVar2x64(Vector128<long> left, Vector128<long> right, Vector128<long> control);
        public static Vector128<ulong> PermuteVar2x64(Vector128<ulong> left, Vector128<ulong> right, Vector128<ulong> control);

        public static Vector128<float> PermuteVar4x32(Vector128<float> left, Vector128<float> right>, Vector128<int> control);

        public static Vector128<int> PermuteVar4x32(Vector128<int> left, Vector128<int> right, Vector128<int> control);
        public static Vector128<uint> PermuteVar4x32(Vector128<uint> left, Vector128<uint> right, Vector128<uint> control);

        public static Vector256<double> PermuteVar4x64(Vector256<double> value, Vector256<long> control);
        public static Vector256<double> PermuteVar4x64(Vector256<double> left, Vector256<double> right, Vector256<long> control);

        public static Vector256<long> PermuteVar4x64(Vector256<long> value, Vector256<long> control);
        public static Vector256<long> PermuteVar4x64(Vector256<long> left, Vector256<long> right, Vector256<long> control);

        public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> value, Vector256<ulong> control);
        public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> left, Vector256<ulong> right, Vector256<ulong> control);

        public static Vector256<float> PermuteVar8x32(Vector256<float> value, Vector256<int> control);
        public static Vector256<float> PermuteVar8x32(Vector256<float> left, Vector256<float> right>, Vector256<int> control);

        public static Vector256<int> PermuteVar8x32(Vector256<int> left, Vector256<int> right, Vector256<int> control);
        public static Vector256<uint> PermuteVar8x32(Vector256<uint> left, Vector256<uint> right, Vector256<uint> control);

        public static Vector256<long> ShiftRightArithmeticVariable(Vector256<long> value, Vector256<ulong> count);
        public static Vector128<long> ShiftRightArithmeticVariable(Vector256<int> value, Vector256<uint> count);

        public static Vector256<int> RotateLeft(Vector256<int> value, byte count);
        public static Vector128<int> RotateLeft(Vector128<int> value, byte count);

        public static Vector256<long> RotateLeft(Vector256<long> value, byte count);
        public static Vector128<long> RotateLeft(Vector128<long> value, byte count);

        public static Vector256<uint> RotateLeft(Vector256<uint> value, byte count);
        public static Vector128<uint> RotateLeft(Vector128<uint> value, byte count);

        public static Vector256<ulong> RotateLeft(Vector256<ulong> value, byte count);
        public static Vector128<ulong> RotateLeft(Vector128<ulong> value, byte count);

        public static Vector256<int> RotateLeftVariable(Vector256<int> value, Vector256<int> count);
        public static Vector128<int> RotateLeftVariable(Vector128<int> value, Vector128<int> count);

        public static Vector256<long> RotateLeftVariable(Vector256<long> value, Vector256<long> count);
        public static Vector128<long> RotateLeftVariable(Vector128<long> value, Vector128<long> count);

        public static Vector256<uint> RotateLeftVariable(Vector256<uint> value, Vector256<uint> count);
        public static Vector128<uint> RotateLeftVariable(Vector128<uint> value, Vector128<uint> count);

        public static Vector256<ulong> RotateLeftVariable(Vector256<ulong> value, Vector256<ulong> count);
        public static Vector128<ulong> RotateLeftVariable(Vector128<ulong> value, Vector128<ulong> count);

        public static Vector256<int> RotateRight(Vector256<int> value, byte count);
        public static Vector128<int> RotateRight(Vector128<int> value, byte count);

        public static Vector256<long> RotateRight(Vector256<long> value, byte count);
        public static Vector128<long> RotateRight(Vector128<long> value, byte count);

        public static Vector256<uint> RotateRight(Vector256<uint> value, byte count);
        public static Vector128<uint> RotateRight(Vector128<uint> value, byte count);

        public static Vector256<ulong> RotateRight(Vector256<ulong> value, byte count);
        public static Vector128<ulong> RotateRight(Vector128<ulong> value, byte count);

        public static Vector256<int> RotateRightVariable(Vector256<int> value, Vector256<int> count);
        public static Vector128<int> RotateRightVariable(Vector128<int> value, Vector128<int> count);

        public static Vector256<long> RotateRightVariable(Vector256<long> value, Vector256<long> count);
        public static Vector128<long> RotateRightVariable(Vector128<long> value, Vector128<long> count);

        public static Vector256<uint> RotateRightVariable(Vector256<uint> value, Vector256<uint> count);
        public static Vector128<uint> RotateRightVariable(Vector128<uint> value, Vector128<uint> count);

        public static Vector256<ulong> RotateRightVariable(Vector256<ulong> value, Vector256<ulong> count);
        public static Vector128<ulong> RotateRightVariable(Vector128<ulong> value, Vector128<ulong> count);

        public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector256<double> value);
        public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector128<double> value);

        public static void Scatter(double* baseAddress, Vector256<double> index, byte scale, Vector256<double> value);
        public static void Scatter(double* baseAddress, Vector128<double> index, byte scale, Vector128<double> value);

        public static void Scatter(int* baseAddress, Vector256<int> index, byte scale, Vector256<int> value);
        public static void Scatter(int* baseAddress, Vector128<int> index, byte scale, Vector128<int> value);

        public static void Scatter(int* baseAddress, Vector256<long> index, byte scale, Vector128<int> value);
        public static void Scatter(int* baseAddress, Vector128<long> index, byte scale, Vector128<int> value);

        public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector256<long> value);
        public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector128<long> value);

        public static void Scatter(long* baseAddress, Vector256<long> index, byte scale, Vector256<long> value);
        public static void Scatter(long* baseAddress, Vector128<long> index, byte scale, Vector128<long> value);

        public static void Scatter(float* baseAddress, Vector256<float> index, byte scale, Vector256<float> value);
        public static void Scatter(float* baseAddress, Vector128<float> index, byte scale, Vector128<float> value);

        public static void Scatter(float* baseAddress, Vector256<long> index, byte scale, Vector128<float> value);
        public static void Scatter(float* baseAddress, Vector128<long> index, byte scale, Vector128<float> value);

        public static Vector256<int> TernaryLogic(Vector256<int> left, Vector256<int> right, byte control);
        public static Vector128<int> TernaryLogic(Vector128<int> left, Vector128<int> right, byte control);

        public static Vector256<long> TernaryLogic(Vector256<long> left, Vector256<long> right, byte control);
        public static Vector128<long> TernaryLogic(Vector128<long> left, Vector128<long> right, byte control);

        public static Vector256<double> Reciprocal14(Vector256<double> value);
        public static Vector128<double> Reciprocal14(Vector128<double> value);

        public static Vector256<float> Reciprocal14(Vector256<float> value);
        public static Vector128<float> Reciprocal14(Vector128<float> value);

        public static Vector256<double> RoundScale(Vector256<double> value, byte scale);
        public static Vector128<double> RoundScale(Vector128<double> value, byte scale);

        public static Vector256<float> RoundScale(Vector256<float> value, byte scale);
        public static Vector128<float> RoundScale(Vector128<float> value, byte scale);

        public static Vector256<double> ReciprocalSqrt14(Vector256<double> value);
        public static Vector128<double> ReciprocalSqrt14(Vector128<double> value);

        public static Vector256<float> ReciprocalSqrt14(Vector256<float> value);
        public static Vector128<float> ReciprocalSqrt14(Vector128<float> value);

        public static Vector256<double> Scale(Vector256<double> value);
        public static Vector128<double> Scale(Vector128<double> value);

        public static Vector256<float> Scale(Vector256<float> value);
        public static Vector128<float> Scale(Vector128<float> value););

        public static Vector256<int> Shuffle(Vector256<int> left, Vector256<int> right, byte control);
    }
}
@tannergooding tannergooding added area-System.Runtime.Intrinsics api-ready-for-review API is ready for review, it is NOT ready for implementation labels Aug 30, 2022
@tannergooding tannergooding added this to the 8.0.0 milestone Aug 30, 2022
@tannergooding
Copy link
Member Author

CC. @anthonycanino

@ghost
Copy link

ghost commented Aug 30, 2022

Tagging subscribers to this area: @dotnet/area-system-runtime-intrinsics
See info in area-owners.md if you want to be subscribed.

Issue Details

Summary

In addition to providing 512-bit versions of existing instructions, AVX512 also provides various new instructions that were not available in previous ISAs. It makes 128-bit and 256-bit versions of these instructions available under the AVX512VL ISA.

As described in #73604, AVX512VL is somewhat special in that it is not its own self-contained ISA. Rather, when the CPUID flag is present it extends each other AVX512 ISA with 128-bit and 256-bit instruction support.

Given we don't support multiple inheritance in .NET, the easiest way to model this using our existing semantics is to expose a nested class named VL. Just like with the nested X64 base class, it is only supported when the parent ISA is also supported. Likewise, for derived classes (such as Avx512BW), its own nested class can derive from Avx512F.VL and otherwise flow the normal ISA checks as expected. This also avoids needing to consider complexities for names such as Avx512BW_VL or some variant there-of.

API Proposal

We should expose the Avx512F.VL class as the first part of the AVX512 feature set.

public abstract partial class Avx512F : Avx2
{
    public abstract partial class VL
    {
        public static bool IsSupported { get; }

        // AVX512

        public static Vector256<int> BroadcastToVector256(Vector128<int> value);
        public static Vector256<uint> BroadcastToVector256(Vector128<uint> value);
        public static Vector256<float> BroadcastToVector256(Vector128<float> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<int> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<int> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<long> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<long> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<uint> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<uint> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<ulong> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<ulong> value);

        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<uint> value);
        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<uint> value);

        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<ulong> value);
        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<ulong> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<int> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<int> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<long> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<long> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<uint> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<uint> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<ulong> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<ulong> value);

        public static Vector128<int> ConvertToVector128Int32(Vector256<long> value);
        public static Vector128<int> ConvertToVector128Int32(Vector128<long> value);

        public static Vector128<int> ConvertToVector128Int32(Vector256<ulong> value);
        public static Vector128<int> ConvertToVector128Int32(Vector128<ulong> value);

        public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector256<long> value);
        public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector128<long> value);

        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<int> value);
        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<int> value);

        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<long> value);
        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<long> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<int> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<int> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<long> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<long> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<uint> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<uint> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<ulong> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<ulong> value);

        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<int> value);
        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<int> value);

        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<long> value);
        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<long> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<int> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<int> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<long> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<long> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<uint> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<uint> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<ulong> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<ulong> value);

        public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector256<uint> value);
        public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector128<uint> value);

        public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector256<long> value);
        public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector128<long> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<double> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<float> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<long> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<long> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<ulong> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<ulong> value);

        public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector256<ulong> value);
        public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector128<ulong> value);

        public static Vector256<double> ConvertToVector256Double(Vector128<uint> value);
        public static Vector128<double> ConvertToVector128Double(Vector128<uint> value);

        public static Vector256<float> ConvertToVector256Single(Vector128<uint> value);
        public static Vector128<float> ConvertToVector128Single(Vector128<uint> value);

        public static Vector256<double> Fixup(Vector256<double> left, Vector256<double> right, Vector256<long> table);
        public static Vector128<double> Fixup(Vector128<double> left, Vector128<double> right, Vector128<long> table);

        public static Vector256<float> Fixup(Vector256<float> left, Vector256<float> right, Vector256<int> table);
        public static Vector128<float> Fixup(Vector128<float> left, Vector128<float> right, Vector128<int> table);

        public static Vector256<double> GetExponent(Vector256<double> value);
        public static Vector128<double> GetExponent(Vector128<double> value);

        public static Vector256<float> GetExponent(Vector256<float> value);
        public static Vector128<float> GetExponent(Vector128<float> value);

        public static Vector256<double> GetMantissa(Vector256<double> value, byte interval, byte signControl);
        public static Vector128<double> GetMantissa(Vector128<double> value, byte interval, byte signControl);

        public static Vector256<float> GetMantissa(Vector256<float> value, byte interval, byte signControl);
        public static Vector128<float> GetMantissa(Vector128<float> value, byte interval, byte signControl);

        public static Vector128<double> PermuteVar2x64(Vector128<double> left, Vector128<double> right, Vector128<long> control);

        public static Vector128<long> PermuteVar2x64(Vector128<long> left, Vector128<long> right, Vector128<long> control);
        public static Vector128<ulong> PermuteVar2x64(Vector128<ulong> left, Vector128<ulong> right, Vector128<ulong> control);

        public static Vector128<float> PermuteVar4x32(Vector128<float> left, Vector128<float> right>, Vector128<int> control);

        public static Vector128<int> PermuteVar4x32(Vector128<int> left, Vector128<int> right, Vector128<int> control);
        public static Vector128<uint> PermuteVar4x32(Vector128<uint> left, Vector128<uint> right, Vector128<uint> control);

        public static Vector256<double> PermuteVar4x64(Vector256<double> value, Vector256<long> control);
        public static Vector256<double> PermuteVar4x64(Vector256<double> left, Vector256<double> right, Vector256<long> control);

        public static Vector256<long> PermuteVar4x64(Vector256<long> value, Vector256<long> control);
        public static Vector256<long> PermuteVar4x64(Vector256<long> left, Vector256<long> right, Vector256<long> control);

        public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> value, Vector256<ulong> control);
        public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> left, Vector256<ulong> right, Vector256<ulong> control);

        public static Vector256<float> PermuteVar8x32(Vector256<float> value, Vector256<int> control);
        public static Vector256<float> PermuteVar8x32(Vector256<float> left, Vector256<float> right>, Vector256<int> control);

        public static Vector256<int> PermuteVar8x32(Vector256<int> left, Vector256<int> right, Vector256<int> control);
        public static Vector256<uint> PermuteVar8x32(Vector256<uint> left, Vector256<uint> right, Vector256<uint> control);

        public static Vector256<long> ShiftRightArithmeticVariable(Vector256<long> value, Vector256<ulong> count);
        public static Vector128<long> ShiftRightArithmeticVariable(Vector256<int> value, Vector256<uint> count);

        public static Vector256<int> RotateLeft(Vector256<int> value, byte count);
        public static Vector128<int> RotateLeft(Vector128<int> value, byte count);

        public static Vector256<long> RotateLeft(Vector256<long> value, byte count);
        public static Vector128<long> RotateLeft(Vector128<long> value, byte count);

        public static Vector256<uint> RotateLeft(Vector256<uint> value, byte count);
        public static Vector128<uint> RotateLeft(Vector128<uint> value, byte count);

        public static Vector256<ulong> RotateLeft(Vector256<ulong> value, byte count);
        public static Vector128<ulong> RotateLeft(Vector128<ulong> value, byte count);

        public static Vector256<int> RotateLeftVariable(Vector256<int> value, Vector256<int> count);
        public static Vector128<int> RotateLeftVariable(Vector128<int> value, Vector128<int> count);

        public static Vector256<long> RotateLeftVariable(Vector256<long> value, Vector256<long> count);
        public static Vector128<long> RotateLeftVariable(Vector128<long> value, Vector128<long> count);

        public static Vector256<uint> RotateLeftVariable(Vector256<uint> value, Vector256<uint> count);
        public static Vector128<uint> RotateLeftVariable(Vector128<uint> value, Vector128<uint> count);

        public static Vector256<ulong> RotateLeftVariable(Vector256<ulong> value, Vector256<ulong> count);
        public static Vector128<ulong> RotateLeftVariable(Vector128<ulong> value, Vector128<ulong> count);

        public static Vector256<int> RotateRight(Vector256<int> value, byte count);
        public static Vector128<int> RotateRight(Vector128<int> value, byte count);

        public static Vector256<long> RotateRight(Vector256<long> value, byte count);
        public static Vector128<long> RotateRight(Vector128<long> value, byte count);

        public static Vector256<uint> RotateRight(Vector256<uint> value, byte count);
        public static Vector128<uint> RotateRight(Vector128<uint> value, byte count);

        public static Vector256<ulong> RotateRight(Vector256<ulong> value, byte count);
        public static Vector128<ulong> RotateRight(Vector128<ulong> value, byte count);

        public static Vector256<int> RotateRightVariable(Vector256<int> value, Vector256<int> count);
        public static Vector128<int> RotateRightVariable(Vector128<int> value, Vector128<int> count);

        public static Vector256<long> RotateRightVariable(Vector256<long> value, Vector256<long> count);
        public static Vector128<long> RotateRightVariable(Vector128<long> value, Vector128<long> count);

        public static Vector256<uint> RotateRightVariable(Vector256<uint> value, Vector256<uint> count);
        public static Vector128<uint> RotateRightVariable(Vector128<uint> value, Vector128<uint> count);

        public static Vector256<ulong> RotateRightVariable(Vector256<ulong> value, Vector256<ulong> count);
        public static Vector128<ulong> RotateRightVariable(Vector128<ulong> value, Vector128<ulong> count);

        public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector256<double> value);
        public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector128<double> value);

        public static void Scatter(double* baseAddress, Vector256<double> index, byte scale, Vector256<double> value);
        public static void Scatter(double* baseAddress, Vector128<double> index, byte scale, Vector128<double> value);

        public static void Scatter(int* baseAddress, Vector256<int> index, byte scale, Vector256<int> value);
        public static void Scatter(int* baseAddress, Vector128<int> index, byte scale, Vector128<int> value);

        public static void Scatter(int* baseAddress, Vector256<long> index, byte scale, Vector128<int> value);
        public static void Scatter(int* baseAddress, Vector128<long> index, byte scale, Vector128<int> value);

        public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector256<long> value);
        public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector128<long> value);

        public static void Scatter(long* baseAddress, Vector256<long> index, byte scale, Vector256<long> value);
        public static void Scatter(long* baseAddress, Vector128<long> index, byte scale, Vector128<long> value);

        public static void Scatter(float* baseAddress, Vector256<float> index, byte scale, Vector256<float> value);
        public static void Scatter(float* baseAddress, Vector128<float> index, byte scale, Vector128<float> value);

        public static void Scatter(float* baseAddress, Vector256<long> index, byte scale, Vector128<float> value);
        public static void Scatter(float* baseAddress, Vector128<long> index, byte scale, Vector128<float> value);

        public static Vector256<int> TernaryLogic(Vector256<int> left, Vector256<int> right, byte control);
        public static Vector128<int> TernaryLogic(Vector128<int> left, Vector128<int> right, byte control);

        public static Vector256<long> TernaryLogic(Vector256<long> left, Vector256<long> right, byte control);
        public static Vector128<long> TernaryLogic(Vector128<long> left, Vector128<long> right, byte control);

        public static Vector256<double> Reciprocal14(Vector256<double> value);
        public static Vector128<double> Reciprocal14(Vector128<double> value);

        public static Vector256<float> Reciprocal14(Vector256<float> value);
        public static Vector128<float> Reciprocal14(Vector128<float> value);

        public static Vector256<double> RoundScale(Vector256<double> value, byte scale);
        public static Vector128<double> RoundScale(Vector128<double> value, byte scale);

        public static Vector256<float> RoundScale(Vector256<float> value, byte scale);
        public static Vector128<float> RoundScale(Vector128<float> value, byte scale);

        public static Vector256<double> ReciprocalSqrt14(Vector256<double> value);
        public static Vector128<double> ReciprocalSqrt14(Vector128<double> value);

        public static Vector256<float> ReciprocalSqrt14(Vector256<float> value);
        public static Vector128<float> ReciprocalSqrt14(Vector128<float> value);

        public static Vector256<double> Scale(Vector256<double> value);
        public static Vector128<double> Scale(Vector128<double> value);

        public static Vector256<float> Scale(Vector256<float> value);
        public static Vector128<float> Scale(Vector128<float> value););

        public static Vector256<int> Shuffle(Vector256<int> left, Vector256<int> right, byte control);
    }
}
Author: tannergooding
Assignees: -
Labels:

area-System.Runtime.Intrinsics, api-ready-for-review

Milestone: 8.0.0

@terrajobst
Copy link
Member

terrajobst commented Oct 25, 2022

Video

  • Looks good as proposed
namespace System.Runtime.Intrinsics.X86;

public abstract partial class Avx512F : Avx2
{
    public abstract partial class VL
    {
        public static bool IsSupported { get; }

        // AVX512

        public static Vector256<int> BroadcastToVector256(Vector128<int> value);
        public static Vector256<uint> BroadcastToVector256(Vector128<uint> value);
        public static Vector256<float> BroadcastToVector256(Vector128<float> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<int> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<int> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<long> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<long> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<uint> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<uint> value);

        public static Vector128<byte> ConvertToVector128Byte(Vector256<ulong> value);
        public static Vector128<byte> ConvertToVector128Byte(Vector128<ulong> value);

        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<uint> value);
        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<uint> value);

        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector256<ulong> value);
        public static Vector128<byte> ConvertToVector128ByteWithSaturation(Vector128<ulong> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<int> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<int> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<long> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<long> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<uint> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<uint> value);

        public static Vector128<short> ConvertToVector128Int16(Vector256<ulong> value);
        public static Vector128<short> ConvertToVector128Int16(Vector128<ulong> value);

        public static Vector128<int> ConvertToVector128Int32(Vector256<long> value);
        public static Vector128<int> ConvertToVector128Int32(Vector128<long> value);

        public static Vector128<int> ConvertToVector128Int32(Vector256<ulong> value);
        public static Vector128<int> ConvertToVector128Int32(Vector128<ulong> value);

        public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector256<long> value);
        public static Vector128<int> ConvertToVector128Int32WithSaturation(Vector128<long> value);

        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<int> value);
        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<int> value);

        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector256<long> value);
        public static Vector128<short> ConvertToVector128Int16WithSaturation(Vector128<long> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<int> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<int> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<long> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<long> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<uint> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<uint> value);

        public static Vector128<sbyte> ConvertToVector128SByte(Vector256<ulong> value);
        public static Vector128<sbyte> ConvertToVector128SByte(Vector128<ulong> value);

        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<int> value);
        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<int> value);

        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector256<long> value);
        public static Vector128<sbyte> ConvertToVector128SByteWithSaturation(Vector128<long> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<int> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<int> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<long> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<long> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<uint> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<uint> value);

        public static Vector128<ushort> ConvertToVector128UInt16(Vector256<ulong> value);
        public static Vector128<ushort> ConvertToVector128UInt16(Vector128<ulong> value);

        public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector256<uint> value);
        public static Vector128<ushort> ConvertToVector128UInt16WithSaturation(Vector128<uint> value);

        public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector256<long> value);
        public static Vector128<short> ConvertToVector128UInt16WithSaturation(Vector128<long> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<double> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<float> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<long> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<long> value);

        public static Vector128<uint> ConvertToVector128UInt32(Vector256<ulong> value);
        public static Vector128<uint> ConvertToVector128UInt32(Vector128<ulong> value);

        public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector256<ulong> value);
        public static Vector128<uint> ConvertToVector128UInt32WithSaturation(Vector128<ulong> value);

        public static Vector256<double> ConvertToVector256Double(Vector128<uint> value);
        public static Vector128<double> ConvertToVector128Double(Vector128<uint> value);

        public static Vector256<float> ConvertToVector256Single(Vector128<uint> value);
        public static Vector128<float> ConvertToVector128Single(Vector128<uint> value);

        public static Vector256<double> Fixup(Vector256<double> left, Vector256<double> right, Vector256<long> table);
        public static Vector128<double> Fixup(Vector128<double> left, Vector128<double> right, Vector128<long> table);

        public static Vector256<float> Fixup(Vector256<float> left, Vector256<float> right, Vector256<int> table);
        public static Vector128<float> Fixup(Vector128<float> left, Vector128<float> right, Vector128<int> table);

        public static Vector256<double> GetExponent(Vector256<double> value);
        public static Vector128<double> GetExponent(Vector128<double> value);

        public static Vector256<float> GetExponent(Vector256<float> value);
        public static Vector128<float> GetExponent(Vector128<float> value);

        public static Vector256<double> GetMantissa(Vector256<double> value, byte interval, byte signControl);
        public static Vector128<double> GetMantissa(Vector128<double> value, byte interval, byte signControl);

        public static Vector256<float> GetMantissa(Vector256<float> value, byte interval, byte signControl);
        public static Vector128<float> GetMantissa(Vector128<float> value, byte interval, byte signControl);

        public static Vector128<double> PermuteVar2x64(Vector128<double> left, Vector128<double> right, Vector128<long> control);

        public static Vector128<long> PermuteVar2x64(Vector128<long> left, Vector128<long> right, Vector128<long> control);
        public static Vector128<ulong> PermuteVar2x64(Vector128<ulong> left, Vector128<ulong> right, Vector128<ulong> control);

        public static Vector128<float> PermuteVar4x32(Vector128<float> left, Vector128<float> right>, Vector128<int> control);

        public static Vector128<int> PermuteVar4x32(Vector128<int> left, Vector128<int> right, Vector128<int> control);
        public static Vector128<uint> PermuteVar4x32(Vector128<uint> left, Vector128<uint> right, Vector128<uint> control);

        public static Vector256<double> PermuteVar4x64(Vector256<double> value, Vector256<long> control);
        public static Vector256<double> PermuteVar4x64(Vector256<double> left, Vector256<double> right, Vector256<long> control);

        public static Vector256<long> PermuteVar4x64(Vector256<long> value, Vector256<long> control);
        public static Vector256<long> PermuteVar4x64(Vector256<long> left, Vector256<long> right, Vector256<long> control);

        public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> value, Vector256<ulong> control);
        public static Vector256<ulong> PermuteVar4x64(Vector256<ulong> left, Vector256<ulong> right, Vector256<ulong> control);

        public static Vector256<float> PermuteVar8x32(Vector256<float> value, Vector256<int> control);
        public static Vector256<float> PermuteVar8x32(Vector256<float> left, Vector256<float> right>, Vector256<int> control);

        public static Vector256<int> PermuteVar8x32(Vector256<int> left, Vector256<int> right, Vector256<int> control);
        public static Vector256<uint> PermuteVar8x32(Vector256<uint> left, Vector256<uint> right, Vector256<uint> control);

        public static Vector256<long> ShiftRightArithmeticVariable(Vector256<long> value, Vector256<ulong> count);
        public static Vector128<long> ShiftRightArithmeticVariable(Vector256<int> value, Vector256<uint> count);

        public static Vector256<int> RotateLeft(Vector256<int> value, byte count);
        public static Vector128<int> RotateLeft(Vector128<int> value, byte count);

        public static Vector256<long> RotateLeft(Vector256<long> value, byte count);
        public static Vector128<long> RotateLeft(Vector128<long> value, byte count);

        public static Vector256<uint> RotateLeft(Vector256<uint> value, byte count);
        public static Vector128<uint> RotateLeft(Vector128<uint> value, byte count);

        public static Vector256<ulong> RotateLeft(Vector256<ulong> value, byte count);
        public static Vector128<ulong> RotateLeft(Vector128<ulong> value, byte count);

        public static Vector256<int> RotateLeftVariable(Vector256<int> value, Vector256<int> count);
        public static Vector128<int> RotateLeftVariable(Vector128<int> value, Vector128<int> count);

        public static Vector256<long> RotateLeftVariable(Vector256<long> value, Vector256<long> count);
        public static Vector128<long> RotateLeftVariable(Vector128<long> value, Vector128<long> count);

        public static Vector256<uint> RotateLeftVariable(Vector256<uint> value, Vector256<uint> count);
        public static Vector128<uint> RotateLeftVariable(Vector128<uint> value, Vector128<uint> count);

        public static Vector256<ulong> RotateLeftVariable(Vector256<ulong> value, Vector256<ulong> count);
        public static Vector128<ulong> RotateLeftVariable(Vector128<ulong> value, Vector128<ulong> count);

        public static Vector256<int> RotateRight(Vector256<int> value, byte count);
        public static Vector128<int> RotateRight(Vector128<int> value, byte count);

        public static Vector256<long> RotateRight(Vector256<long> value, byte count);
        public static Vector128<long> RotateRight(Vector128<long> value, byte count);

        public static Vector256<uint> RotateRight(Vector256<uint> value, byte count);
        public static Vector128<uint> RotateRight(Vector128<uint> value, byte count);

        public static Vector256<ulong> RotateRight(Vector256<ulong> value, byte count);
        public static Vector128<ulong> RotateRight(Vector128<ulong> value, byte count);

        public static Vector256<int> RotateRightVariable(Vector256<int> value, Vector256<int> count);
        public static Vector128<int> RotateRightVariable(Vector128<int> value, Vector128<int> count);

        public static Vector256<long> RotateRightVariable(Vector256<long> value, Vector256<long> count);
        public static Vector128<long> RotateRightVariable(Vector128<long> value, Vector128<long> count);

        public static Vector256<uint> RotateRightVariable(Vector256<uint> value, Vector256<uint> count);
        public static Vector128<uint> RotateRightVariable(Vector128<uint> value, Vector128<uint> count);

        public static Vector256<ulong> RotateRightVariable(Vector256<ulong> value, Vector256<ulong> count);
        public static Vector128<ulong> RotateRightVariable(Vector128<ulong> value, Vector128<ulong> count);

        public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector256<double> value);
        public static void Scatter(double* baseAddress, Vector128<int> index, byte scale, Vector128<double> value);

        public static void Scatter(double* baseAddress, Vector256<double> index, byte scale, Vector256<double> value);
        public static void Scatter(double* baseAddress, Vector128<double> index, byte scale, Vector128<double> value);

        public static void Scatter(int* baseAddress, Vector256<int> index, byte scale, Vector256<int> value);
        public static void Scatter(int* baseAddress, Vector128<int> index, byte scale, Vector128<int> value);

        public static void Scatter(int* baseAddress, Vector256<long> index, byte scale, Vector128<int> value);
        public static void Scatter(int* baseAddress, Vector128<long> index, byte scale, Vector128<int> value);

        public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector256<long> value);
        public static void Scatter(long* baseAddress, Vector128<int> index, byte scale, Vector128<long> value);

        public static void Scatter(long* baseAddress, Vector256<long> index, byte scale, Vector256<long> value);
        public static void Scatter(long* baseAddress, Vector128<long> index, byte scale, Vector128<long> value);

        public static void Scatter(float* baseAddress, Vector256<float> index, byte scale, Vector256<float> value);
        public static void Scatter(float* baseAddress, Vector128<float> index, byte scale, Vector128<float> value);

        public static void Scatter(float* baseAddress, Vector256<long> index, byte scale, Vector128<float> value);
        public static void Scatter(float* baseAddress, Vector128<long> index, byte scale, Vector128<float> value);

        public static Vector256<int> TernaryLogic(Vector256<int> left, Vector256<int> right, byte control);
        public static Vector128<int> TernaryLogic(Vector128<int> left, Vector128<int> right, byte control);

        public static Vector256<long> TernaryLogic(Vector256<long> left, Vector256<long> right, byte control);
        public static Vector128<long> TernaryLogic(Vector128<long> left, Vector128<long> right, byte control);

        public static Vector256<double> Reciprocal14(Vector256<double> value);
        public static Vector128<double> Reciprocal14(Vector128<double> value);

        public static Vector256<float> Reciprocal14(Vector256<float> value);
        public static Vector128<float> Reciprocal14(Vector128<float> value);

        public static Vector256<double> RoundScale(Vector256<double> value, byte scale);
        public static Vector128<double> RoundScale(Vector128<double> value, byte scale);

        public static Vector256<float> RoundScale(Vector256<float> value, byte scale);
        public static Vector128<float> RoundScale(Vector128<float> value, byte scale);

        public static Vector256<double> ReciprocalSqrt14(Vector256<double> value);
        public static Vector128<double> ReciprocalSqrt14(Vector128<double> value);

        public static Vector256<float> ReciprocalSqrt14(Vector256<float> value);
        public static Vector128<float> ReciprocalSqrt14(Vector128<float> value);

        public static Vector256<double> Scale(Vector256<double> value);
        public static Vector128<double> Scale(Vector128<double> value);

        public static Vector256<float> Scale(Vector256<float> value);
        public static Vector128<float> Scale(Vector128<float> value););

        public static Vector256<int> Shuffle(Vector256<int> left, Vector256<int> right, byte control);
    }
}

@tannergooding
Copy link
Member Author

This was all implemented except for scatter which was superseded by #87097

@ghost ghost locked as resolved and limited conversation to collaborators Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.Intrinsics avx512 Related to the AVX-512 architecture
Projects
None yet
Development

No branches or pull requests

3 participants