Skip to content

Expose AVX512BW, AVX512CD, and AVX512DQ #76579

Description

@tannergooding

Summary

Continuing off #73604 where we exposed AVX512F, we should expose support for the additional ISAs that are part of the x86-64-v4 baseline.

API Proposal

We should expose the Avx512BW, AVX512CD, and AVX512DQ classes as the first part of the AVX512 feature set.

namespace System.Runtime.Intrinsics.X86;

public abstract partial class Avx512BW : Avx512F
{
    // SSE-SSE4.2

    public static Vector512<sbyte> Abs(Vector512<sbyte> value);
    public static Vector512<short> Abs(Vector512<short> value);

    public static Vector512<byte>   Add(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  Add(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  Add(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> Add(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<sbyte>  AddSaturate(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<short>  AddSaturate(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<byte>   AddSaturate(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<ushort> AddSaturate(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<byte>  AlignRight(Vector512<byte>  left, Vector512<sbyte>  right, byte mask);
    public static Vector512<sbyte> AlignRight(Vector512<sbyte> left, Vector512<ssbyte> right, byte mask);

    public static Vector512<byte>   Average(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<ushort> Average(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<short> ConvertToVector512Int16(Vector256<byte>  value);
    public static Vector512<short> ConvertToVector512Int16(Vector512<sbyte> value);

    public static Vector512<byte>   Max(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  Max(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  Max(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> Max(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<byte>   Min(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  Min(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  Min(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> Min(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<int>   MultiplyAddAdjacent(Vector512<short> left, Vector512<short> right);
    public static Vector512<short> MultiplyAddAdjacent(Vector512<byte>  left, Vector512<sbyte> right);

    public static Vector512<short>  MultiplyHigh(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<ushort> MultiplyHigh(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<short> MultiplyHighRoundScale(Vector512<short> left, Vector512<short> right);

    public static Vector512<short>  MultiplyLow(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<ushort> MultiplyLow(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<sbyte> PackSignedSaturate(Vector512<short> left, Vector512<short> right);
    public static Vector512<short> PackSignedSaturate(Vector512<int>   left, Vector512<int>   right);

    public static Vector512<byte>   PackUnignedSaturate(Vector512<short> left, Vector512<short> right);
    public static Vector512<ushort> PackUnignedSaturate(Vector512<int>   left, Vector512<int>   right);

    public static Vector512<short>  ShiftLeftLogical(Vector512<short>  value, byte count);
    public static Vector512<ushort> ShiftLeftLogical(Vector512<ushort> value, byte count);
    public static Vector512<short>  ShiftLeftLogical(Vector512<short>  value, Vector128<short>  count);
    public static Vector512<ushort> ShiftLeftLogical(Vector512<ushort> value, Vector128<ushort> count);

    public static Vector512<byte>   ShiftLeftLogical128BitLane(Vector512<byte>   value, byte numBytes);
    public static Vector512<short>  ShiftLeftLogical128BitLane(Vector512<short>  value, byte numBytes);
    public static Vector512<int>    ShiftLeftLogical128BitLane(Vector512<int>    value, byte numBytes);
    public static Vector512<long>   ShiftLeftLogical128BitLane(Vector512<long>   value, byte numBytes);
    public static Vector512<sbyte>  ShiftLeftLogical128BitLane(Vector512<sbyte>  value, byte numBytes);
    public static Vector512<ushort> ShiftLeftLogical128BitLane(Vector512<ushort> value, byte numBytes);
    public static Vector512<uint>   ShiftLeftLogical128BitLane(Vector512<uint>   value, byte numBytes);
    public static Vector512<ulong>  ShiftLeftLogical128BitLane(Vector512<ulong>  value, byte numBytes);

    public static Vector512<short>  ShiftRightArithmetic(Vector512<short>  value, byte count);
    public static Vector512<short>  ShiftRightArithmetic(Vector512<short>  value, Vector128<short>  count);

    public static Vector512<short>  ShiftRightLogical(Vector512<short>  value, byte count);
    public static Vector512<ushort> ShiftRightLogical(Vector512<ushort> value, byte count);
    public static Vector512<short>  ShiftRightLogical(Vector512<short>  value, Vector128<short>  count);
    public static Vector512<ushort> ShiftRightLogical(Vector512<ushort> value, Vector128<ushort> count);

    public static Vector512<byte>   ShiftRightLogical128BitLane(Vector512<byte>   value, byte numBytes);
    public static Vector512<short>  ShiftRightLogical128BitLane(Vector512<short>  value, byte numBytes);
    public static Vector512<int>    ShiftRightLogical128BitLane(Vector512<int>    value, byte numBytes);
    public static Vector512<long>   ShiftRightLogical128BitLane(Vector512<long>   value, byte numBytes);
    public static Vector512<sbyte>  ShiftRightLogical128BitLane(Vector512<sbyte>  value, byte numBytes);
    public static Vector512<ushort> ShiftRightLogical128BitLane(Vector512<ushort> value, byte numBytes);
    public static Vector512<uint>   ShiftRightLogical128BitLane(Vector512<uint>   value, byte numBytes);
    public static Vector512<ulong>  ShiftRightLogical128BitLane(Vector512<ulong>  value, byte numBytes);

    public static Vector512<byte>  Shuffle(Vector512<byte>  value, Vector512<byte>  mask);
    public static Vector512<sbyte> Shuffle(Vector512<sbyte> value, Vector512<sbyte> mask);

    public static Vector512<short>  ShuffleHigh(Vector512<short>  value, byte control);
    public static Vector512<ushort> ShuffleHigh(Vector512<ushort> value, byte control);

    public static Vector512<short>  ShuffleLow(Vector512<short>  value, byte control);
    public static Vector512<ushort> ShuffleLow(Vector512<ushort> value, byte control);

    public static Vector512<byte>   Subtract(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  Subtract(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  Subtract(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> Subtract(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<byte>   SubtractSaturate(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  SubtractSaturate(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  SubtractSaturate(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> SubtractSaturate(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<ushort> SumAbsoluteDifferences(Vector512<byte> byte, Vector512<byte> byte);

    public static Vector512<byte>   UnpackHigh(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<sbyte>  UnpackHigh(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<short>  UnpackHigh(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<ushort> UnpackHigh(Vector512<ushort> left, Vector512<ushort> right);

    public static Vector512<byte>   UnpackLow(Vector512<byte>   left, Vector512<byte>   right);
    public static Vector512<short>  UnpackLow(Vector512<short>  left, Vector512<short>  right);
    public static Vector512<sbyte>  UnpackLow(Vector512<sbyte>  left, Vector512<sbyte>  right);
    public static Vector512<ushort> UnpackLow(Vector512<ushort> left, Vector512<ushort> right);

    // AVX-AVX2

    public static Vector512<byte>   BroadcastScalarToVector512(Vector128<byte>   value);
    public static Vector512<short>  BroadcastScalarToVector512(Vector128<short>  value);
    public static Vector512<sbyte>  BroadcastScalarToVector512(Vector128<sbyte>  value);
    public static Vector512<ushort> BroadcastScalarToVector512(Vector128<ushort> value);

    public static Vector512<short>  PermuteVar32x16(Vector512<short>  value, Vector512<short>  control);
    public static Vector512<ushort> PermuteVar32x16(Vector512<ushort> value, Vector512<ushort> control);

    // AVX512

    public static Vector512<byte> SumAbsoluteDifferencesWidening(Vector512<byte> left, Vector512<byte> right, byte control);

    public static Vector512<short>  PermuteVar32x16(Vector512<short>  left, Vector512<short>  right, Vector512<short>  control);
    public static Vector512<ushort> PermuteVar32x16(Vector512<ushort> left, Vector512<ushort> right, Vector512<ushort> control);

    public static Vector256<byte>  ConvertToVector256ByteWithSaturation (Vector512<ushort> value);
    public static Vector256<sbyte> ConvertToVector256SByteWithSaturation(Vector512<short>  value);

    public static Vector512<short>  ShiftLeftLogicalVariable(Vector512<short>  value, Vector512<short>  count);
    public static Vector512<ushort> ShiftLeftLogicalVariable(Vector512<ushort> value, Vector512<ushort> count);

    public static Vector512<short>  ShiftRightArithmeticVariable(Vector512<short> value, Vector512<short> count);

    public static Vector512<short>  ShiftRightLogicalVariable(Vector512<short> value, Vector512<short>  count);
    public static Vector512<ushort> ShiftRightLogicalVariable(Vector512<short> value, Vector512<ushort> count);
}

public abstract partial class Avx512CD : Avx512F
{
    // AVX512

    public static Vector512<int>   DetectConflicts(Vector512<int>   value);
    public static Vector512<long>  DetectConflicts(Vector512<long>  value);
    public static Vector512<uint>  DetectConflicts(Vector512<uint>  value);
    public static Vector512<ulong> DetectConflicts(Vector512<ulong> value);

    public static Vector512<int>   LeadingZeroCount(Vector512<int>   value);
    public static Vector512<long>  LeadingZeroCount(Vector512<long>  value);
    public static Vector512<uint>  LeadingZeroCount(Vector512<uint>  value);
    public static Vector512<ulong> LeadingZeroCount(Vector512<ulong> value);
}


public abstract partial class Avx512DQ : Avx512F
{
    // SSE-SSE4.2

    public static Vector512<double> And(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  And(Vector512<float>  left, Vector512<float>  right);

    public static Vector512<double> AndNot(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  AndNot(Vector512<float>  left, Vector512<float>  right);

    public static Vector512<long>  MultiplyLow(Vector512<long>  left, Vector512<long>  right);
    public static Vector512<ulong> MultiplyLow(Vector512<ulong> left, Vector512<ulong> right);

    public static Vector512<double> Or(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  Or(Vector512<float>  left, Vector512<float>  right);

    public static Vector512<double> Xor(Vector512<double> left, Vector512<double> right);
    public static Vector512<float>  Xor(Vector512<float>  left, Vector512<float>  right);

    // AVX-AVX2

    public static Vector128<double> ExtractVector128(Vector512<double> value, byte index);
    public static Vector128<long>   ExtractVector128(Vector512<long>   value, byte index);
    public static Vector128<ulong>  ExtractVector128(Vector512<ulong>  value, byte index);

    public static Vector256<int>   ExtractVector256(Vector512<int>   value, byte index);
    public static Vector256<float> ExtractVector256(Vector512<float> value, byte index);
    public static Vector256<uint>  ExtractVector256(Vector512<uint>  value, byte index);

    public static Vector512<double> InsertVector128(Vector512<double> value, Vector128<double> data, byte index);
    public static Vector512<long>   InsertVector128(Vector512<long>   value, Vector128<long>   data, byte index);
    public static Vector512<ulong>  InsertVector128(Vector512<ulong>  value, Vector128<ulong>  data, byte index);

    public static Vector512<int>   InsertVector256(Vector512<int>   value, Vector256<int>   data, byte index);
    public static Vector512<float> InsertVector256(Vector512<float> value, Vector256<float> data, byte index);
    public static Vector512<uint>  InsertVector256(Vector512<uint>  value, Vector256<uint>  data, byte index);

    public static Vector512<int>   BroadcastPairScalarToVector512(Vector128<int>  value);
    public static Vector512<uint>  BroadcastPairScalarToVector512(Vector128<uint> value);

    public static Vector512<long>  BroadcastToVector512(Vector128<long>  value);
    public static Vector512<ulong> BroadcastToVector512(Vector128<ulong> value);
    public static Vector512<int>   BroadcastToVector512(Vector256<int>   value);
    public static Vector512<uint>  BroadcastToVector512(Vector256<uint>  value);

    // AVX512

    public static Vector512<float> BroadcastPairScalarToVector512(Vector128<float> value);

    public static Vector512<double> BroadcastToVector512(Vector128<double> value);
    public static Vector512<float>  BroadcastToVector512(Vector256<float>  value);

    public static Vector256<float> ConvertToVector256Single(Vector512<long>  value);
    public static Vector256<float> ConvertToVector256Single(Vector512<long>  value, FloatRoundingMode mode);
    public static Vector256<float> ConvertToVector256Single(Vector512<ulong> value);
    public static Vector256<float> ConvertToVector256Single(Vector512<ulong> value, FloatRoundingMode mode);

    public static Vector512<double> ConvertToVector512Double(Vector512<long> value);
    public static Vector512<double> ConvertToVector512Double(Vector512<long> value, FloatRoundingMode mode);
    public static Vector512<double> ConvertToVector512Double(Vector512<ulong> value);
    public static Vector512<double> ConvertToVector512Double(Vector512<ulong> value, FloatRoundingMode mode);

    public static Vector512<long> ConvertToVector512Int64(Vector512<double> value);
    public static Vector512<long> ConvertToVector512Int64(Vector512<double> value, FloatRoundingMode mode);
    public static Vector512<long> ConvertToVector512Int64(Vector512<float>  value);
    public static Vector512<long> ConvertToVector512Int64(Vector512<float>  value, FloatRoundingMode mode);

    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector256<float>  value);
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector256<float>  value, FloatRoundingMode mode);
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector512<double> value);
    public static Vector512<long> ConvertToVector512Int64WithTruncation(Vector512<double> value, FloatRoundingMode mode);

    public static Vector512<ulong> ConvertToVector512UInt64(Vector256<float>  value);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector256<float>  value, FloatRoundingMode mode);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector512<double> value);
    public static Vector512<ulong> ConvertToVector512UInt64(Vector512<double> value, FloatRoundingMode mode);

    public static Vector512<double> RangeRestrict(Vector512<double> left, Vector512<double> right, byte control);
    public static Vector512<float>  RangeRestrict(Vector512<float>  left, Vector512<float>  right, byte control);

    public static Vector128<double> RangeRestrictScalar(Vector128<double> left,  Vector128<double> right, byte control);
    public static Vector128<float>  RangeRestrictScalar(Vector128<float>  left,  Vector128<float>  right, byte control);

    public static Vector128<double> RangeRestrictScalar(Vector128<double> upper, Vector128<double> left, Vector128<double> right, byte control);
    public static Vector128<float>  RangeRestrictScalar(Vector128<float>  upper, Vector128<float>  left, Vector128<float>  right, byte control);

    public static Vector512<double> ReductionTransform(Vector512<double> value, byte control);
    public static Vector512<float>  ReductionTransform(Vector512<float>  value, byte control);

    public static Vector128<double> ReductionTransformScalar(Vector128<double> upper, Vector128<double> value, byte control);
    public static Vector128<float>  ReductionTransformScalar(Vector128<float>  upper, Vector128<float>  value, byte control);
}

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions