-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expose the x86 HWIntrinsics via a set of class hierarchies matching the underlying ISA hierarchies #19186
Expose the x86 HWIntrinsics via a set of class hierarchies matching the underlying ISA hierarchies #19186
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,10 +11,12 @@ namespace System.Runtime.Intrinsics.X86 | |
/// This class provides access to Intel AES hardware instructions via intrinsics | ||
/// </summary> | ||
[CLSCompliant(false)] | ||
public static class Aes | ||
public abstract class Aes : Sse2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
{ | ||
public static bool IsSupported { get => IsSupported; } | ||
|
||
internal Aes() { } | ||
|
||
public new static bool IsSupported { get => IsSupported; } | ||
|
||
/// <summary> | ||
/// __m128i _mm_aesdec_si128 (__m128i a, __m128i RoundKey) | ||
/// AESDEC xmm, xmm/m128 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,10 +11,12 @@ namespace System.Runtime.Intrinsics.X86 | |
/// This class provides access to Intel AVX hardware instructions via intrinsics | ||
/// </summary> | ||
[CLSCompliant(false)] | ||
public static class Avx | ||
public abstract class Avx : Sse42 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 14.3 DETECTION OF AVX INSTRUCTIONS Intel AVX instructions operate on the 256-bit YMM register state. Application detection of new instruction extensions Prior to using AVX, the application must identify that the operating system supports the XGETBV instruction, the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed with Intel that AVX has an implicit dependency on Sse42 (and prior) due to extending the existing instructions. CC. @fiigii |
||
{ | ||
public static bool IsSupported { get { return false; } } | ||
|
||
internal Avx() { } | ||
|
||
public new static bool IsSupported { get { return false; } } | ||
|
||
/// <summary> | ||
/// __m256 _mm256_add_ps (__m256 a, __m256 b) | ||
/// VADDPS ymm, ymm, ymm/m256 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,9 +11,11 @@ namespace System.Runtime.Intrinsics.X86 | |
/// This class provides access to Intel AVX2 hardware instructions via intrinsics | ||
/// </summary> | ||
[CLSCompliant(false)] | ||
public static class Avx2 | ||
public abstract class Avx2 : Avx | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 14.7.1 Detection of AVX2 Hardware support for AVX2 is indicated by CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]=1. Application Software must identify that hardware supports AVX, after that it must also detect support for AVX2 by |
||
{ | ||
public static bool IsSupported { get { return false; } } | ||
internal Avx2() { } | ||
|
||
public new static bool IsSupported { get { return false; } } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_abs_epi8 (__m256i a) | ||
|
@@ -455,7 +457,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(sbyte* address, Vector256<sbyte> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(sbyte* address, Vector256<sbyte> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -466,7 +468,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(byte* address, Vector256<byte> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(byte* address, Vector256<byte> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -477,7 +479,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(short* address, Vector256<short> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(short* address, Vector256<short> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -488,7 +490,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(ushort* address, Vector256<ushort> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(ushort* address, Vector256<ushort> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -499,7 +501,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(int* address, Vector256<int> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(int* address, Vector256<int> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -510,7 +512,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(uint* address, Vector256<uint> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(uint* address, Vector256<uint> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -521,7 +523,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(long* address, Vector256<long> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(long* address, Vector256<long> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
|
@@ -532,7 +534,7 @@ public static class Avx2 | |
/// __m128i _mm256_extracti128_si256 (__m256i a, const int imm8) | ||
/// VEXTRACTI128 m128, ymm, imm8 | ||
/// </summary> | ||
public static unsafe void ExtractVector128(ulong* address, Vector256<ulong> value, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe void ExtractVector128(ulong* address, Vector256<ulong> value, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m128i _mm_i32gather_epi32 (int const* base_addr, __m128i vindex, const int scale) | ||
|
@@ -819,7 +821,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, xm128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<sbyte> InsertVector128(Vector256<sbyte> value, sbyte* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<sbyte> InsertVector128(Vector256<sbyte> value, sbyte* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -830,7 +832,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<byte> InsertVector128(Vector256<byte> value, byte* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<byte> InsertVector128(Vector256<byte> value, byte* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -841,7 +843,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<short> InsertVector128(Vector256<short> value, short* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<short> InsertVector128(Vector256<short> value, short* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -852,7 +854,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<ushort> InsertVector128(Vector256<ushort> value, ushort* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<ushort> InsertVector128(Vector256<ushort> value, ushort* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -863,7 +865,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<int> InsertVector128(Vector256<int> value, int* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<int> InsertVector128(Vector256<int> value, int* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -874,7 +876,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<uint> InsertVector128(Vector256<uint> value, uint* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<uint> InsertVector128(Vector256<uint> value, uint* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -885,7 +887,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<long> InsertVector128(Vector256<long> value, long* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<long> InsertVector128(Vector256<long> value, long* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
|
@@ -896,7 +898,7 @@ public static class Avx2 | |
/// __m256i _mm256_inserti128_si256 (__m256i a, __m128i b, const int imm8) | ||
/// VINSERTI128 ymm, ymm, m128, imm8 | ||
/// </summary> | ||
public static unsafe Vector256<ulong> InsertVector128(Vector256<ulong> value, ulong* address, byte index) { throw new PlatformNotSupportedException(); } | ||
public new static unsafe Vector256<ulong> InsertVector128(Vector256<ulong> value, ulong* address, byte index) { throw new PlatformNotSupportedException(); } | ||
|
||
/// <summary> | ||
/// __m256i _mm256_stream_load_si256 (__m256i const* mem_addr) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
12.13.4 Checking for AESNI Support
Before an application attempts to use AESNI instructions or PCLMULQDQ, the application should follow the steps
illustrated in Section 11.6.2, “Checking for SSE/SSE2 Support.” Next, use the additional step provided below:
Check that the processor supports AESNI (if CPUID.01H:ECX.AESNI[bit 25] = 1); check that the processor
supports PCLMULQDQ (if CPUID.01H:ECX.PCLMULQDQ[bit 1] = 1).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed with Intel that there is not a co-dependency between AESNI and PCLMULQDQ.
CC. @fiigii