From 3652db318015a248c5a039b8cda0aa8d391728cb Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 3 May 2023 10:27:11 -0700 Subject: [PATCH 01/21] Expose AlignRight32 and AlignRight64 on Avx512F --- src/coreclr/jit/emitxarch.cpp | 4 ++ src/coreclr/jit/hwintrinsiclistxarch.h | 4 ++ src/coreclr/jit/instrsxarch.h | 2 + src/coreclr/jit/lowerxarch.cpp | 8 +++ .../X86/Avx512F.PlatformNotSupported.cs | 64 +++++++++++++++++++ .../System/Runtime/Intrinsics/X86/Avx512F.cs | 64 +++++++++++++++++++ .../ref/System.Runtime.Intrinsics.cs | 12 ++++ .../GenerateHWIntrinsicTests_X86.cs | 24 +++++++ 8 files changed, 182 insertions(+) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 5014781e3bce5..0ea1f1ca1fff5 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -18501,15 +18501,19 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_movshdup: case INS_insertps: case INS_palignr: + case INS_valignd: + case INS_valignq: case INS_vpermilps: case INS_vpermilpd: case INS_vpermilpsvar: case INS_vpermilpdvar: case INS_pslldq: case INS_psrldq: + { result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += PERFSCORE_LATENCY_1C; break; + } case INS_vblendvps: case INS_vblendvpd: diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index fd4fc497369f9..c8295f5cf292d 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -827,6 +827,8 @@ HARDWARE_INTRINSIC(AVX2, Xor, // AVX512F Intrinsics HARDWARE_INTRINSIC(AVX512F, Abs, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pabsd, INS_invalid, INS_vpabsq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F, Add, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_paddd, INS_paddd, INS_paddq, INS_paddq, INS_addps, INS_addpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) +HARDWARE_INTRINSIC(AVX512F, AlignRight32, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_valignd, INS_valignd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, AlignRight64, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_valignq, INS_valignq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, And, 64, 2, {INS_pand, INS_pand, INS_pand, INS_pand, INS_pand, INS_pand, INS_vpandq, INS_vpandq, INS_andps, INS_andpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F, AndNot, 64, 2, {INS_pandn, INS_pandn, INS_pandn, INS_pandn, INS_pandn, INS_pandn, INS_vpandnq, INS_vpandnq, INS_andnps, INS_andnpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, BroadcastScalarToVector512, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpbroadcastd, INS_vpbroadcastd, INS_vpbroadcastq, INS_vpbroadcastq, INS_vbroadcastss, INS_vbroadcastsd}, HW_Category_SIMDScalar, HW_Flag_NoFlag) @@ -927,6 +929,8 @@ HARDWARE_INTRINSIC(AVX512F, Xor, // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // AVX512F.VL Intrinsics HARDWARE_INTRINSIC(AVX512F_VL, Abs, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpabsq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(AVX512F_VL, AlignRight32, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_valignd, INS_valignd, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, AlignRight64, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_valignq, INS_valignq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, Max, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmaxsq, INS_vpmaxuq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F_VL, Min, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpminsq, INS_vpminuq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative) HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector128Byte, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpmovdb, INS_vpmovdb, INS_vpmovqb, INS_vpmovqb, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 189a0d66bd853..e2c85fce193ea 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -611,6 +611,8 @@ INST3(FIRST_AVX512_INSTRUCTION, "FIRST_AVX512_INSTRUCTION", IUM_WR, BAD_CODE, BA INST3(kmovw_gpr, "kmovw", IUM_WR, BAD_CODE, BAD_CODE, PCKFLT(0x92), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) INST3(kmovw_msk, "kmovw", IUM_WR, PCKFLT(0x91), BAD_CODE, PCKFLT(0x90), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) INST3(kortestw, "kortestw", IUM_RD, BAD_CODE, BAD_CODE, PCKFLT(0x98), INS_TT_NONE, REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) +INST3(valignd, "alignd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x03), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Align doubleword vectors +INST3(valignq, "alignq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x03), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Align quadword vectors INST3(vbroadcastf64x2, "broadcastf64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1A), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed float values read from memory to entire register INST3(vbroadcasti64x2, "broadcasti64x2", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x5A), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed integer values read from memory to entire register INST3(vbroadcastf64x4, "broadcastf64x4", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x1B), INS_TT_TUPLE2, Input_64Bit | REX_W1 | Encoding_EVEX) // Broadcast packed float values read from memory to entire register diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index a34d7c0592429..297f962958a34 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -6971,6 +6971,8 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX2_Shuffle: case NI_AVX2_ShuffleHigh: case NI_AVX2_ShuffleLow: + case NI_AVX512F_AlignRight32: + case NI_AVX512F_AlignRight64: case NI_AVX512F_Permute2x64: case NI_AVX512F_Permute4x32: case NI_AVX512F_Permute4x64: @@ -6978,6 +6980,8 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX512F_ShiftRightArithmetic: case NI_AVX512F_ShiftRightLogical: case NI_AVX512F_Shuffle: + case NI_AVX512F_VL_AlignRight32: + case NI_AVX512F_VL_AlignRight64: case NI_AVX512F_VL_ShiftRightArithmetic: case NI_AVX512BW_AlignRight: case NI_AVX512BW_ShiftLeftLogical: @@ -8156,11 +8160,15 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX2_InsertVector128: case NI_AVX2_MultipleSumAbsoluteDifferences: case NI_AVX2_Permute2x128: + case NI_AVX512F_AlignRight32: + case NI_AVX512F_AlignRight64: case NI_AVX512F_GetMantissaScalar: case NI_AVX512F_InsertVector128: case NI_AVX512F_InsertVector256: case NI_AVX512F_RoundScaleScalar: case NI_AVX512F_Shuffle: + case NI_AVX512F_VL_AlignRight32: + case NI_AVX512F_VL_AlignRight64: case NI_AVX512BW_AlignRight: case NI_AVX512DQ_InsertVector128: case NI_AVX512DQ_InsertVector256: diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs index 331e93cbca555..3588960396ce0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs @@ -33,6 +33,48 @@ internal VL() { } /// public static Vector256 Abs(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_alignr_epi32 (__m128i a, __m128i b, const int count) + /// VALIGND xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 AlignRight32(Vector128 left, Vector128 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_alignr_epi32 (__m128i a, __m128i b, const int count) + /// VALIGND xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 AlignRight32(Vector128 left, Vector128 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_alignr_epi32 (__m256i a, __m256i b, const int count) + /// VALIGND ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 AlignRight32(Vector256 left, Vector256 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_alignr_epi32 (__m256i a, __m256i b, const int count) + /// VALIGND ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 AlignRight32(Vector256 left, Vector256 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_alignr_epi64 (__m128i a, __m128i b, const int count) + /// VALIGNQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 AlignRight64(Vector128 left, Vector128 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_alignr_epi64 (__m128i a, __m128i b, const int count) + /// VALIGNQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 AlignRight64(Vector128 left, Vector128 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_alignr_epi64 (__m256i a, __m256i b, const int count) + /// VALIGNQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 AlignRight64(Vector256 left, Vector256 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_alignr_epi64 (__m256i a, __m256i b, const int count) + /// VALIGNQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 AlignRight64(Vector256 left, Vector256 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// /// __m128i _mm_cvtepi32_epi8 (__m128i a) /// VPMOVDB xmm1/m32 {k1}{z}, xmm2 @@ -729,6 +771,28 @@ internal X64() { } /// public static Vector512 Add(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_alignr_epi32 (__m512i a, __m512i b, const int count) + /// VALIGND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 AlignRight32(Vector512 left, Vector512 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_alignr_epi32 (__m512i a, __m512i b, const int count) + /// VALIGND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 AlignRight32(Vector512 left, Vector512 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_alignr_epi64 (__m512i a, __m512i b, const int count) + /// VALIGNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 AlignRight64(Vector512 left, Vector512 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_alignr_epi64 (__m512i a, __m512i b, const int count) + /// VALIGNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 AlignRight64(Vector512 left, Vector512 right, [ConstantExpected] byte mask) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_and_si512 (__m512i a, __m512i b) /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs index b687677a844dd..8049d09877ac3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs @@ -33,6 +33,48 @@ internal VL() { } /// public static Vector256 Abs(Vector256 value) => Abs(value); + /// + /// __m128i _mm_alignr_epi32 (__m128i a, __m128i b, const int count) + /// VALIGND xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 AlignRight32(Vector128 left, Vector128 right, [ConstantExpected] byte mask) => AlignRight32(left, right, mask); + /// + /// __m128i _mm_alignr_epi32 (__m128i a, __m128i b, const int count) + /// VALIGND xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 AlignRight32(Vector128 left, Vector128 right, [ConstantExpected] byte mask) => AlignRight32(left, right, mask); + /// + /// __m256i _mm256_alignr_epi32 (__m256i a, __m256i b, const int count) + /// VALIGND ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 AlignRight32(Vector256 left, Vector256 right, [ConstantExpected] byte mask) => AlignRight32(left, right, mask); + /// + /// __m256i _mm256_alignr_epi32 (__m256i a, __m256i b, const int count) + /// VALIGND ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 AlignRight32(Vector256 left, Vector256 right, [ConstantExpected] byte mask) => AlignRight32(left, right, mask); + + /// + /// __m128i _mm_alignr_epi64 (__m128i a, __m128i b, const int count) + /// VALIGNQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 AlignRight64(Vector128 left, Vector128 right, [ConstantExpected] byte mask) => AlignRight64(left, right, mask); + /// + /// __m128i _mm_alignr_epi64 (__m128i a, __m128i b, const int count) + /// VALIGNQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 AlignRight64(Vector128 left, Vector128 right, [ConstantExpected] byte mask) => AlignRight64(left, right, mask); + /// + /// __m256i _mm256_alignr_epi64 (__m256i a, __m256i b, const int count) + /// VALIGNQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 AlignRight64(Vector256 left, Vector256 right, [ConstantExpected] byte mask) => AlignRight64(left, right, mask); + /// + /// __m256i _mm256_alignr_epi64 (__m256i a, __m256i b, const int count) + /// VALIGNQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 AlignRight64(Vector256 left, Vector256 right, [ConstantExpected] byte mask) => AlignRight64(left, right, mask); + /// /// __m128i _mm_cvtepi32_epi8 (__m128i a) /// VPMOVDB xmm1/m32 {k1}{z}, xmm2 @@ -730,6 +772,28 @@ internal X64() { } /// public static Vector512 Add(Vector512 left, Vector512 right) => Add(left, right); + /// + /// __m512i _mm512_alignr_epi32 (__m512i a, __m512i b, const int count) + /// VALIGND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 AlignRight32(Vector512 left, Vector512 right, [ConstantExpected] byte mask) => AlignRight32(left, right, mask); + /// + /// __m512i _mm512_alignr_epi32 (__m512i a, __m512i b, const int count) + /// VALIGND zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 AlignRight32(Vector512 left, Vector512 right, [ConstantExpected] byte mask) => AlignRight32(left, right, mask); + + /// + /// __m512i _mm512_alignr_epi64 (__m512i a, __m512i b, const int count) + /// VALIGNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 AlignRight64(Vector512 left, Vector512 right, [ConstantExpected] byte mask) => AlignRight64(left, right, mask); + /// + /// __m512i _mm512_alignr_epi64 (__m512i a, __m512i b, const int count) + /// VALIGNQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 AlignRight64(Vector512 left, Vector512 right, [ConstantExpected] byte mask) => AlignRight64(left, right, mask); + /// /// __m512i _mm512_and_si512 (__m512i a, __m512i b) /// VPANDD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 478b78b9906b2..7060ad28ecd3e 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4679,6 +4679,10 @@ internal Avx512F() { } public static System.Runtime.Intrinsics.Vector512 Add(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Add(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Add(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 AlignRight32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector512 AlignRight32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector512 AlignRight64(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector512 AlignRight64(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } public static System.Runtime.Intrinsics.Vector512 And(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 And(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 And(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } @@ -5037,6 +5041,14 @@ internal VL() { } public static bool IsSupported { get { throw null; } } public static System.Runtime.Intrinsics.Vector128 Abs(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 Abs(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AlignRight32(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AlignRight32(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector256 AlignRight32(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector256 AlignRight32(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AlignRight64(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector128 AlignRight64(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector256 AlignRight64(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } + public static System.Runtime.Intrinsics.Vector256 AlignRight64(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte mask) { throw null; } public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 ConvertToVector128Byte(System.Runtime.Intrinsics.Vector128 value) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index b672ca49929bc..85d10086e2cd4 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1101,6 +1101,14 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Add", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Add", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(uint)(left[i] + right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Add", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(ulong)(left[i] + right[i]) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 11) ? right[i + 5] : left[i - 11])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Imm"] = "27", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != left[11]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 11] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 11) ? right[i + 5] : left[i - 11])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Imm"] = "27", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[11]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 11] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "And", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "(byte)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(byte)(left[i] & right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "And", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "(short)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] & right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "And", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "(int)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] & right[i]) != result[i]"}), @@ -1400,6 +1408,14 @@ (string templateFileName, Dictionary templateData)[] Avx512F_VL_Vector128Inputs = new [] { ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (ulong)((firstOp[0] < 0) ? -firstOp[0] : firstOp[0])", ["ValidateRemainingResults"] = "result[i] != (ulong)((firstOp[i] < 0) ? -firstOp[i] : firstOp[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? right[i + 1] : left[i - 1])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 1] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? right[i + 1] : left[i - 1])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 1] : 0)"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 2) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (byte)firstOp[i] : result[i])"}), @@ -1470,6 +1486,14 @@ (string templateFileName, Dictionary templateData)[] Avx512F_VL_Vector256Inputs = new [] { ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "Abs", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (ulong)((firstOp[0] < 0) ? -firstOp[0] : firstOp[0])", ["ValidateRemainingResults"] = "result[i] != (ulong)((firstOp[i] < 0) ? -firstOp[i] : firstOp[i])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 8) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 8) ? (byte)firstOp[i] : result[i])"}), From b9c96901ab5736c15bc6cf65bb39bf6384cfe3f8 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 3 May 2023 11:38:08 -0700 Subject: [PATCH 02/21] Expose RotateLeft and RotateRight for Avx512F --- src/coreclr/jit/emitxarch.cpp | 65 +++-- src/coreclr/jit/hwintrinsiclistxarch.h | 8 + src/coreclr/jit/hwintrinsicxarch.cpp | 33 ++- src/coreclr/jit/instrsxarch.h | 8 + src/coreclr/jit/lowerxarch.cpp | 8 + src/coreclr/jit/simd.h | 12 + src/coreclr/jit/valuenum.cpp | 14 + .../X86/Avx512F.PlatformNotSupported.cs | 248 ++++++++++++++++++ .../System/Runtime/Intrinsics/X86/Avx512F.cs | 248 ++++++++++++++++++ .../ref/System.Runtime.Intrinsics.cs | 48 ++++ .../GenerateHWIntrinsicTests_X86.cs | 104 ++++++-- 11 files changed, 745 insertions(+), 51 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 0ea1f1ca1fff5..94b61b07ce8ac 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -162,6 +162,18 @@ regNumber emitter::getSseShiftRegNumber(instruction ins) return (regNumber)4; } + case INS_vprold: + case INS_vprolq: + { + return (regNumber)1; + } + + case INS_vprord: + case INS_vprorq: + { + return (regNumber)0; + } + default: { assert(!"Invalid instruction for SSE2 instruction of the form: opcode reg, immed8"); @@ -6355,40 +6367,17 @@ void emitter::emitIns_R_R_I(instruction ins, emitAttr attr, regNumber reg1, regN code_t code = 0; - switch (ins) + if (hasCodeMR(ins)) { - case INS_pextrb: - case INS_pextrd: - case INS_pextrq: - case INS_pextrw_sse41: - case INS_extractps: - case INS_vextractf128: - case INS_vextractf32x8: - case INS_vextractf64x2: - case INS_vextractf64x4: - case INS_vextracti128: - case INS_vextracti32x8: - case INS_vextracti64x2: - case INS_vextracti64x4: - case INS_shld: - case INS_shrd: - { - code = insCodeMR(ins); - break; - } - - case INS_psrldq: - case INS_pslldq: - { - code = insCodeMI(ins); - break; - } - - default: - { - code = insCodeRM(ins); - break; - } + code = insCodeMR(ins); + } + else if (hasCodeMI(ins)) + { + code = insCodeMI(ins); + } + else + { + code = insCodeRM(ins); } UNATIVE_OFFSET sz = emitInsSizeRR(id, code, ival); @@ -18415,6 +18404,14 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_psignb: case INS_psignw: case INS_psignd: + case INS_vprold: + case INS_vprolq: + case INS_vprolvd: + case INS_vprolvq: + case INS_vprord: + case INS_vprorq: + case INS_vprorvd: + case INS_vprorvq: case INS_vpsravd: case INS_vpsravq: case INS_vpsravw: @@ -18435,9 +18432,11 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vpsrlvq: case INS_vpsrlvw: case INS_vpternlogd: + { result.insThroughput = PERFSCORE_THROUGHPUT_2X; result.insLatency += PERFSCORE_LATENCY_1C; break; + } case INS_pslld: case INS_psllw: diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index c8295f5cf292d..b94b24e628b43 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -903,6 +903,10 @@ HARDWARE_INTRINSIC(AVX512F, Reciprocal14, HARDWARE_INTRINSIC(AVX512F, Reciprocal14Scalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ss, INS_vrcp14sd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) HARDWARE_INTRINSIC(AVX512F, ReciprocalSqrt14, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ps, INS_vrsqrt14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, ReciprocalSqrt14Scalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ss, INS_vrsqrt14sd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, RotateLeft, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprold, INS_vprold, INS_vprolq, INS_vprolq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, RotateLeftVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprolvd, INS_vprolvd, INS_vprolvq, INS_vprolvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, RotateRight, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprord, INS_vprord, INS_vprorq, INS_vprorq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, RotateRightVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprorvd, INS_vprorvd, INS_vprorvq, INS_vprorvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, RoundScale, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaleps, INS_vrndscalepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, RoundScaleScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaless, INS_vrndscalesd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) HARDWARE_INTRINSIC(AVX512F, Scale, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -958,6 +962,10 @@ HARDWARE_INTRINSIC(AVX512F_VL, GetMantissa, HARDWARE_INTRINSIC(AVX512F_VL, PermuteVar4x64, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermq_reg, INS_vpermq_reg, INS_invalid, INS_vpermpd_reg}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX512F_VL, Reciprocal14, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ps, INS_vrcp14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, ReciprocalSqrt14, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ps, INS_vrsqrt14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, RotateLeft, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprold, INS_vprold, INS_vprolq, INS_vprolq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, RotateLeftVariable, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprolvd, INS_vprolvd, INS_vprolvq, INS_vprolvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, RotateRight, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprord, INS_vprord, INS_vprorq, INS_vprorq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, RotateRightVariable, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprorvd, INS_vprorvd, INS_vprorvq, INS_vprorvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, RoundScale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaleps, INS_vrndscalepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, Scale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, ShiftRightArithmetic, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsraq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 3f259b6b0100d..2ef279948d2d7 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -584,14 +584,43 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT case NI_AVX512BW_ShiftRightArithmetic: case NI_AVX512BW_ShiftRightLogical: { + // These intrinsics have overloads that take op2 in a simd register and just read the lowest 8-bits + + impSpillSideEffect(true, + verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); + + GenTree* op2 = impPopStack().val; + GenTree* op1 = impSIMDPopStack(); + + GenTree* tmpOp = gtNewSimdCreateScalarUnsafeNode(TYP_SIMD16, op2, CORINFO_TYPE_INT, 16); + return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, intrinsic, simdBaseJitType, genTypeSize(simdType)); + } + + case NI_AVX512F_RotateLeft: + case NI_AVX512F_RotateRight: + case NI_AVX512F_VL_RotateLeft: + case NI_AVX512F_VL_RotateRight: + { + // These intrinsics have variants that take op2 in a simd register and read a unique shift per element + intrinsic = static_cast(intrinsic + 1); + + static_assert_no_msg(NI_AVX512F_RotateLeftVariable == (NI_AVX512F_RotateLeft + 1)); + static_assert_no_msg(NI_AVX512F_RotateRightVariable == (NI_AVX512F_RotateRight + 1)); + static_assert_no_msg(NI_AVX512F_VL_RotateLeftVariable == (NI_AVX512F_VL_RotateLeft + 1)); + static_assert_no_msg(NI_AVX512F_VL_RotateRightVariable == (NI_AVX512F_VL_RotateRight + 1)); + impSpillSideEffect(true, verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); GenTree* op2 = impPopStack().val; GenTree* op1 = impSIMDPopStack(); - GenTree* tmpOp = - gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, NI_SSE2_ConvertScalarToVector128Int32, CORINFO_TYPE_INT, 16); + if (varTypeIsLong(simdType)) + { + op2 = gtNewCastNode(TYP_LONG, op2, /* fromUnsigned */ true, TYP_LONG); + } + + GenTree* tmpOp = gtNewSimdCreateBroadcastNode(simdType, op2, simdBaseJitType, genTypeSize(simdType)); return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, intrinsic, simdBaseJitType, genTypeSize(simdType)); } diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index e2c85fce193ea..6cfa7862d7841 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -684,6 +684,14 @@ INST3(vpmovusqb, "pmovusqb", IUM_WR, PSSE38(0xF3, 0x12), BAD_ INST3(vpmovusqd, "pmovusqd", IUM_WR, PSSE38(0xF3, 0x15), BAD_CODE, PSSE38(0xF3, 0x15), INS_TT_HALF_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) INST3(vpmovusqw, "pmovusqw", IUM_WR, PSSE38(0xF3, 0x14), BAD_CODE, PSSE38(0xF3, 0x14), INS_TT_QUARTER_MEM, Input_64Bit | REX_W0 | Encoding_EVEX) INST3(vporq, "porq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEB), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise OR of two xmm regs +INST3(vprold, "prold", IUM_WR, BAD_CODE, PCKDBL(0x72), BAD_CODE, INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate left +INST3(vprolq, "prolq", IUM_WR, BAD_CODE, PCKDBL(0x72), BAD_CODE, INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate left +INST3(vprolvd, "prolvd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x15), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate left +INST3(vprolvq, "prolvq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x15), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate left +INST3(vprord, "prord", IUM_WR, BAD_CODE, PCKDBL(0x72), BAD_CODE, INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate right +INST3(vprorq, "prorq", IUM_WR, BAD_CODE, PCKDBL(0x72), BAD_CODE, INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate right +INST3(vprorvd, "prorvd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x14), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate right +INST3(vprorvq, "prorvq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x14), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate right INST3(vpsraq, "psraq", IUM_WR, BAD_CODE, PCKDBL(0x72), PCKDBL(0xE2), INS_TT_FULL | INS_TT_MEM128, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed shift right arithmetic of 64-bit integers INST3(vpsravq, "psravq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x46), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Arithmetic INST3(vpternlogd, "pternlogd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x25), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 297f962958a34..be42755bd82a1 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -6976,12 +6976,16 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX512F_Permute2x64: case NI_AVX512F_Permute4x32: case NI_AVX512F_Permute4x64: + case NI_AVX512F_RotateLeft: + case NI_AVX512F_RotateRight: case NI_AVX512F_ShiftLeftLogical: case NI_AVX512F_ShiftRightArithmetic: case NI_AVX512F_ShiftRightLogical: case NI_AVX512F_Shuffle: case NI_AVX512F_VL_AlignRight32: case NI_AVX512F_VL_AlignRight64: + case NI_AVX512F_VL_RotateLeft: + case NI_AVX512F_VL_RotateRight: case NI_AVX512F_VL_ShiftRightArithmetic: case NI_AVX512BW_AlignRight: case NI_AVX512BW_ShiftLeftLogical: @@ -7736,9 +7740,13 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX2_ShiftLeftLogical: case NI_AVX2_ShiftRightArithmetic: case NI_AVX2_ShiftRightLogical: + case NI_AVX512F_RotateLeft: + case NI_AVX512F_RotateRight: case NI_AVX512F_ShiftLeftLogical: case NI_AVX512F_ShiftRightArithmetic: case NI_AVX512F_ShiftRightLogical: + case NI_AVX512F_VL_RotateLeft: + case NI_AVX512F_VL_RotateRight: case NI_AVX512F_VL_ShiftRightArithmetic: case NI_AVX512BW_ShiftLeftLogical: case NI_AVX512BW_ShiftRightArithmetic: diff --git a/src/coreclr/jit/simd.h b/src/coreclr/jit/simd.h index fcadaf0d9249a..d81016561c849 100644 --- a/src/coreclr/jit/simd.h +++ b/src/coreclr/jit/simd.h @@ -505,6 +505,18 @@ TBase EvaluateBinaryScalarSpecialized(genTreeOps oper, TBase arg0, TBase arg1) return arg0 | arg1; } + case GT_ROL: + { + return EvaluateBinaryScalarSpecialized(GT_LSH, arg0, arg1) | + EvaluateBinaryScalarRSZ(arg0, (sizeof(TBase) * 8) - arg1); + } + + case GT_ROR: + { + return EvaluateBinaryScalarRSZ(arg0, arg1) | + EvaluateBinaryScalarSpecialized(GT_LSH, arg0, (sizeof(TBase) * 8) - arg1); + } + case GT_RSH: { return arg0 >> (arg1 & ((sizeof(TBase) * 8) - 1)); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 692f2d660073b..45e3a85308019 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7303,6 +7303,20 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, return EvaluateBinarySimd(this, GT_OR, /* scalar */ false, type, baseType, arg0VN, arg1VN); } +#ifdef TARGET_XARCH + case NI_AVX512F_RotateLeft: + case NI_AVX512F_VL_RotateLeft: + { + return EvaluateBinarySimd(this, GT_ROL, /* scalar */ false, type, baseType, arg0VN, arg1VN); + } + + case NI_AVX512F_RotateRight: + case NI_AVX512F_VL_RotateRight: + { + return EvaluateBinarySimd(this, GT_ROR, /* scalar */ false, type, baseType, arg0VN, arg1VN); + } +#endif // TARGET_XARCH + #ifdef TARGET_ARM64 case NI_AdvSimd_ShiftLeftLogical: #else diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs index 3588960396ce0..d9d4db644610f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs @@ -607,6 +607,170 @@ internal VL() { } /// public static Vector256 ReciprocalSqrt14(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rol_epi32 (__m128i a, int imm8) + /// VPROLD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rol_epi32 (__m128i a, int imm8) + /// VPROLD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rol_epi64 (__m128i a, int imm8) + /// VPROLQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rol_epi64 (__m128i a, int imm8) + /// VPROLQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rol_epi32 (__m256i a, int imm8) + /// VPROLD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rol_epi32 (__m256i a, int imm8) + /// VPROLD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rol_epi64 (__m256i a, int imm8) + /// VPROLQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rol_epi64 (__m256i a, int imm8) + /// VPROLQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_rolv_epi32 (__m128i a, __m128i b) + /// VPROLDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rolv_epi32 (__m128i a, __m128i b) + /// VPROLDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rolv_epi64 (__m128i a, __m128i b) + /// VPROLQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rolv_epi64 (__m128i a, __m128i b) + /// VPROLQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rolv_epi32 (__m256i a, __m256i b) + /// VPROLDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rolv_epi32 (__m256i a, __m256i b) + /// VPROLDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rolv_epi64 (__m256i a, __m256i b) + /// VPROLQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rolv_epi64 (__m256i a, __m256i b) + /// VPROLQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_ror_epi32 (__m128i a, int imm8) + /// VPRORD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ror_epi32 (__m128i a, int imm8) + /// VPRORD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ror_epi64 (__m128i a, int imm8) + /// VPRORQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ror_epi64 (__m128i a, int imm8) + /// VPRORQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ror_epi32 (__m256i a, int imm8) + /// VPRORD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ror_epi32 (__m256i a, int imm8) + /// VPRORD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ror_epi64 (__m256i a, int imm8) + /// VPRORQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ror_epi64 (__m256i a, int imm8) + /// VPRORQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_rorv_epi32 (__m128i a, __m128i b) + /// VPRORDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rorv_epi32 (__m128i a, __m128i b) + /// VPRORDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rorv_epi64 (__m128i a, __m128i b) + /// VPRORQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_rorv_epi64 (__m128i a, __m128i b) + /// VPRORQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rorv_epi32 (__m256i a, __m256i b) + /// VPRORDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rorv_epi32 (__m256i a, __m256i b) + /// VPRORDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rorv_epi64 (__m256i a, __m256i b) + /// VPRORQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_rorv_epi64 (__m256i a, __m256i b) + /// VPRORQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + /// /// __m128 _mm_roundscale_ps (__m128 a, int imm) /// VRNDSCALEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 @@ -2106,6 +2270,90 @@ internal X64() { } /// public static Vector128 ReciprocalSqrt14Scalar(Vector128 upper, Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rol_epi32 (__m512i a, int imm8) + /// VPROLD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rol_epi32 (__m512i a, int imm8) + /// VPROLD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rol_epi64 (__m512i a, int imm8) + /// VPROLQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rol_epi64 (__m512i a, int imm8) + /// VPROLQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_rolv_epi32 (__m512i a, __m512i b) + /// VPROLDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rolv_epi32 (__m512i a, __m512i b) + /// VPROLDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rolv_epi64 (__m512i a, __m512i b) + /// VPROLQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rolv_epi64 (__m512i a, __m512i b) + /// VPROLQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_ror_epi32 (__m512i a, int imm8) + /// VPRORD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ror_epi32 (__m512i a, int imm8) + /// VPRORD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ror_epi64 (__m512i a, int imm8) + /// VPRORQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ror_epi64 (__m512i a, int imm8) + /// VPRORQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_rorv_epi32 (__m512i a, __m512i b) + /// VPRORDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rorv_epi32 (__m512i a, __m512i b) + /// VPRORDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rorv_epi64 (__m512i a, __m512i b) + /// VPRORQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_rorv_epi64 (__m512i a, __m512i b) + /// VPRORQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) { throw new PlatformNotSupportedException(); } + /// /// __m512 _mm512_roundscale_ps (__m512 a, int imm) /// VRNDSCALEPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae}, imm8 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs index 8049d09877ac3..b730cf9279071 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs @@ -607,6 +607,170 @@ internal VL() { } /// public static Vector256 ReciprocalSqrt14(Vector256 value) => ReciprocalSqrt14(value); + /// + /// __m128i _mm_rol_epi32 (__m128i a, int imm8) + /// VPROLD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m128i _mm_rol_epi32 (__m128i a, int imm8) + /// VPROLD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m128i _mm_rol_epi64 (__m128i a, int imm8) + /// VPROLQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m128i _mm_rol_epi64 (__m128i a, int imm8) + /// VPROLQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateLeft(Vector128 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m256i _mm256_rol_epi32 (__m256i a, int imm8) + /// VPROLD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m256i _mm256_rol_epi32 (__m256i a, int imm8) + /// VPROLD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m256i _mm256_rol_epi64 (__m256i a, int imm8) + /// VPROLQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m256i _mm256_rol_epi64 (__m256i a, int imm8) + /// VPROLQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateLeft(Vector256 value, [ConstantExpected] byte count) => RotateLeft(value, count); + + /// + /// __m128i _mm_rolv_epi32 (__m128i a, __m128i b) + /// VPROLDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) => RotateLeftVariable(value, count); + /// + /// __m128i _mm_rolv_epi32 (__m128i a, __m128i b) + /// VPROLDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) => RotateLeftVariable(value, count); + /// + /// __m128i _mm_rolv_epi64 (__m128i a, __m128i b) + /// VPROLQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) => RotateLeftVariable(value, count); + /// + /// __m128i _mm_rolv_epi64 (__m128i a, __m128i b) + /// VPROLQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateLeftVariable(Vector128 value, Vector128 count) => RotateLeftVariable(value, count); + /// + /// __m256i _mm256_rolv_epi32 (__m256i a, __m256i b) + /// VPROLDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) => RotateLeftVariable(value, count); + /// + /// __m256i _mm256_rolv_epi32 (__m256i a, __m256i b) + /// VPROLDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) => RotateLeftVariable(value, count); + /// + /// __m256i _mm256_rolv_epi64 (__m256i a, __m256i b) + /// VPROLQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) => RotateLeftVariable(value, count); + /// + /// __m256i _mm256_rolv_epi64 (__m256i a, __m256i b) + /// VPROLQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateLeftVariable(Vector256 value, Vector256 count) => RotateLeftVariable(value, count); + + /// + /// __m128i _mm_ror_epi32 (__m128i a, int imm8) + /// VPRORD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m128i _mm_ror_epi32 (__m128i a, int imm8) + /// VPRORD xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m128i _mm_ror_epi64 (__m128i a, int imm8) + /// VPRORQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m128i _mm_ror_epi64 (__m128i a, int imm8) + /// VPRORQ xmm1 {k1}{z}, xmm2/m128/m64bcst, imm8 + /// + public static Vector128 RotateRight(Vector128 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m256i _mm256_ror_epi32 (__m256i a, int imm8) + /// VPRORD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m256i _mm256_ror_epi32 (__m256i a, int imm8) + /// VPRORD ymm1 {k1}{z}, ymm2/m256/m32bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m256i _mm256_ror_epi64 (__m256i a, int imm8) + /// VPRORQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m256i _mm256_ror_epi64 (__m256i a, int imm8) + /// VPRORQ ymm1 {k1}{z}, ymm2/m256/m64bcst, imm8 + /// + public static Vector256 RotateRight(Vector256 value, [ConstantExpected] byte count) => RotateRight(value, count); + + /// + /// __m128i _mm_rorv_epi32 (__m128i a, __m128i b) + /// VPRORDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) => RotateRightVariable(value, count); + /// + /// __m128i _mm_rorv_epi32 (__m128i a, __m128i b) + /// VPRORDV xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) => RotateRightVariable(value, count); + /// + /// __m128i _mm_rorv_epi64 (__m128i a, __m128i b) + /// VPRORQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) => RotateRightVariable(value, count); + /// + /// __m128i _mm_rorv_epi64 (__m128i a, __m128i b) + /// VPRORQV xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst + /// + public static Vector128 RotateRightVariable(Vector128 value, Vector128 count) => RotateRightVariable(value, count); + /// + /// __m256i _mm256_rorv_epi32 (__m256i a, __m256i b) + /// VPRORDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) => RotateRightVariable(value, count); + /// + /// __m256i _mm256_rorv_epi32 (__m256i a, __m256i b) + /// VPRORDV ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) => RotateRightVariable(value, count); + /// + /// __m256i _mm256_rorv_epi64 (__m256i a, __m256i b) + /// VPRORQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) => RotateRightVariable(value, count); + /// + /// __m256i _mm256_rorv_epi64 (__m256i a, __m256i b) + /// VPRORQV ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst + /// + public static Vector256 RotateRightVariable(Vector256 value, Vector256 count) => RotateRightVariable(value, count); + /// /// __m128 _mm_roundscale_ps (__m128 a, int imm) /// VRNDSCALEPS xmm1 {k1}{z}, xmm2/m128/m32bcst, imm8 @@ -2107,6 +2271,90 @@ internal X64() { } /// public static Vector128 ReciprocalSqrt14Scalar(Vector128 upper, Vector128 value) => ReciprocalSqrt14Scalar(upper, value); + /// + /// __m512i _mm512_rol_epi32 (__m512i a, int imm8) + /// VPROLD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m512i _mm512_rol_epi32 (__m512i a, int imm8) + /// VPROLD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m512i _mm512_rol_epi64 (__m512i a, int imm8) + /// VPROLQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) => RotateLeft(value, count); + /// + /// __m512i _mm512_rol_epi64 (__m512i a, int imm8) + /// VPROLQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateLeft(Vector512 value, [ConstantExpected] byte count) => RotateLeft(value, count); + + /// + /// __m512i _mm512_rolv_epi32 (__m512i a, __m512i b) + /// VPROLDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) => RotateLeftVariable(value, count); + /// + /// __m512i _mm512_rolv_epi32 (__m512i a, __m512i b) + /// VPROLDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) => RotateLeftVariable(value, count); + /// + /// __m512i _mm512_rolv_epi64 (__m512i a, __m512i b) + /// VPROLQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) => RotateLeftVariable(value, count); + /// + /// __m512i _mm512_rolv_epi64 (__m512i a, __m512i b) + /// VPROLQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateLeftVariable(Vector512 value, Vector512 count) => RotateLeftVariable(value, count); + + /// + /// __m512i _mm512_ror_epi32 (__m512i a, int imm8) + /// VPRORD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m512i _mm512_ror_epi32 (__m512i a, int imm8) + /// VPRORD zmm1 {k1}{z}, zmm2/m512/m32bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m512i _mm512_ror_epi64 (__m512i a, int imm8) + /// VPRORQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) => RotateRight(value, count); + /// + /// __m512i _mm512_ror_epi64 (__m512i a, int imm8) + /// VPRORQ zmm1 {k1}{z}, zmm2/m512/m64bcst, imm8 + /// + public static Vector512 RotateRight(Vector512 value, [ConstantExpected] byte count) => RotateRight(value, count); + + /// + /// __m512i _mm512_rorv_epi32 (__m512i a, __m512i b) + /// VPRORDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) => RotateRightVariable(value, count); + /// + /// __m512i _mm512_rorv_epi32 (__m512i a, __m512i b) + /// VPRORDV zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) => RotateRightVariable(value, count); + /// + /// __m512i _mm512_rorv_epi64 (__m512i a, __m512i b) + /// VPRORQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) => RotateRightVariable(value, count); + /// + /// __m512i _mm512_rorv_epi64 (__m512i a, __m512i b) + /// VPRORQV zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst + /// + public static Vector512 RotateRightVariable(Vector512 value, Vector512 count) => RotateRightVariable(value, count); + /// /// __m512 _mm512_roundscale_ps (__m512 a, int imm) /// VRNDSCALEPS zmm1 {k1}{z}, zmm2/m512/m32bcst{sae}, imm8 diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 7060ad28ecd3e..658e831f49853 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4933,6 +4933,22 @@ internal Avx512F() { } public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14Scalar(System.Runtime.Intrinsics.Vector128 upper, System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeft(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeft(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeft(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeft(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeftVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeftVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeftVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateLeftVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRight(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRight(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRight(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRight(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRightVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRightVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRightVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } + public static System.Runtime.Intrinsics.Vector512 RotateRightVariable(System.Runtime.Intrinsics.Vector512 value, System.Runtime.Intrinsics.Vector512 count) { throw null; } public static System.Runtime.Intrinsics.Vector512 RoundScale(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector512 RoundScale(System.Runtime.Intrinsics.Vector512 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector128 RoundScaleScalar(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } @@ -5152,6 +5168,38 @@ internal VL() { } public static System.Runtime.Intrinsics.Vector128 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector128 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector256 value) { throw null; } public static System.Runtime.Intrinsics.Vector256 ReciprocalSqrt14(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeft(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeft(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeft(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeft(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeft(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeft(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeft(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeft(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeftVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeftVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeftVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateLeftVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeftVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeftVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeftVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateLeftVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRight(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRight(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRight(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRight(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRight(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRight(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRight(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRight(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRightVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRightVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRightVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 RotateRightVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRightVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRightVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRightVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector256 RotateRightVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } public static System.Runtime.Intrinsics.Vector128 RoundScale(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector128 RoundScale(System.Runtime.Intrinsics.Vector128 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector256 RoundScale(System.Runtime.Intrinsics.Vector256 value, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index 85d10086e2cd4..19f58e71d7a98 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1101,14 +1101,14 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Add", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Add", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(uint)(left[i] + right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Add", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(ulong)(left[i] + right[i]) != result[i]"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 11) ? right[i + 5] : left[i - 11])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Imm"] = "27", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != left[11]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 11] : 0)"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 11) ? right[i + 5] : left[i - 11])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Imm"] = "27", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[11]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 11] : 0)"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 11) ? right[i + 5] : left[i - 11])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Imm"] = "27", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[11]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? right[i + 11] : left[i - 5])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 11) ? right[i + 5] : left[i - 11])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Imm"] = "27", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[11]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? right[i + 11] : left[i - 5])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? right[i + 3] : left[i - 5])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Imm"] = "11", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? right[i + 3] : left[i - 5])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "And", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "(byte)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(byte)(left[i] & right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "And", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "(short)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] & right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "And", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "(int)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] & right[i]) != result[i]"}), @@ -1309,6 +1309,30 @@ ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "ReciprocalSqrt14Scalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "result[i] != firstOp[i]"}), ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "ReciprocalSqrt14Scalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "result[i] != firstOp[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "long.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "long.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(left[i], (int)(right[i])) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Imm"] = "4", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i]))"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Imm"] = "4", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Round(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(MathF.Round(firstOp[i]))"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0], MidpointRounding.AwayFromZero))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i], MidpointRounding.AwayFromZero))"}), @@ -1409,13 +1433,13 @@ { ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (ulong)((firstOp[0] < 0) ? -firstOp[0] : firstOp[0])", ["ValidateRemainingResults"] = "result[i] != (ulong)((firstOp[i] < 0) ? -firstOp[i] : firstOp[i])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? right[i + 1] : left[i - 1])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 1] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? right[i + 1] : left[i - 1])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? right[i + 1] : left[i - 1])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 1] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? right[i + 1] : left[i - 1])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 2) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (byte)firstOp[i] : result[i])"}), @@ -1466,6 +1490,30 @@ ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "Reciprocal14", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocal14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocal14(result[i], firstOp[i])"}), ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "long.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "long.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(left[i], (int)(right[i])) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Imm"] = "4", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i]))"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Imm"] = "4", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Round(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(MathF.Round(firstOp[i]))"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0], MidpointRounding.AwayFromZero))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i], MidpointRounding.AwayFromZero))"}), @@ -1487,13 +1535,13 @@ { ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "Abs", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (ulong)((firstOp[0] < 0) ? -firstOp[0] : firstOp[0])", ["ValidateRemainingResults"] = "result[i] != (ulong)((firstOp[i] < 0) ? -firstOp[i] : firstOp[i])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != right[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? right[i + 3] : left[i - 5])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[5]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 5] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != right[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 5) ? right[i + 3] : left[i - 5])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), - ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[3]", ["ValidateRemainingResults"] = "result[i] != ((i < 1) ? left[i + 3] : 0)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "AlignRight64", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != right[1]", ["ValidateRemainingResults"] = "result[i] != ((i < 3) ? right[i + 1] : left[i - 3])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 8) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (byte)firstOp[i] : result[i])"}), ("SimpleUnOpConvTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ConvertToVector128Byte", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (byte)firstOp[0]", ["ValidateRemainingResults"] = "result[i] != ((i < 8) ? (byte)firstOp[i] : result[i])"}), @@ -1547,6 +1595,30 @@ ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "Reciprocal14", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocal14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocal14(result[i], firstOp[i])"}), ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "long.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(left[i], (int)(right[i])) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "long.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(left[i], (int)(right[i])) != result[i]"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(left[i], (int)(right[i])) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Imm"] = "4", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i]))"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Imm"] = "4", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Round(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(MathF.Round(firstOp[i]))"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RoundScale", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Imm"] = "0", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0], MidpointRounding.AwayFromZero))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i], MidpointRounding.AwayFromZero))"}), From f9158a8c6cef32b915b4ab8576fc802ba9a470c9 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 4 May 2023 09:06:24 -0700 Subject: [PATCH 03/21] Expose SumAbsoluteDifferencesInBlock32 for Avx512BW + DetectConflicts and LeadingZeroCOunt for Avx512DQ --- src/coreclr/jit/emitxarch.cpp | 223 ++++++++++++------ src/coreclr/jit/emitxarch.h | 2 - src/coreclr/jit/gtlist.h | 2 + src/coreclr/jit/hwintrinsiclistxarch.h | 18 ++ src/coreclr/jit/instrsxarch.h | 7 + src/coreclr/jit/lowerxarch.cpp | 66 +++++- src/coreclr/jit/simd.h | 16 ++ src/coreclr/jit/valuenum.cpp | 6 + .../X86/Avx512BW.PlatformNotSupported.cs | 17 ++ .../System/Runtime/Intrinsics/X86/Avx512BW.cs | 17 ++ .../X86/Avx512CD.PlatformNotSupported.cs | 124 ++++++++++ .../System/Runtime/Intrinsics/X86/Avx512CD.cs | 124 ++++++++++ .../ref/System.Runtime.Intrinsics.cs | 27 +++ .../GenerateHWIntrinsicTests_X86.cs | 45 +++- .../X86/Shared/Avx512Verify.cs | 33 +++ .../X86/Shared/SseVerify.cs | 20 ++ 16 files changed, 666 insertions(+), 81 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 94b61b07ce8ac..d6573c687a2a7 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -1121,6 +1121,12 @@ bool emitter::TakesEvexPrefix(const instrDesc* id) const } #endif // DEBUG + if ((ins == INS_pslldq) || (ins == INS_psrldq)) + { + // The memory operand can only be encoded using the EVEX encoding + return id->idHasMem(); + } + return false; } @@ -6472,28 +6478,18 @@ void emitter::emitIns_R_A_I(instruction ins, emitAttr attr, regNumber reg1, GenT emitHandleMemOp(indir, id, emitInsModeFormat(ins, IF_RRD_ARD_CNS), ins); - UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival); - id->idCodeSize(sz); - - dispIns(id); - emitCurIGsize += sz; -} - -void emitter::emitIns_R_AR_I(instruction ins, emitAttr attr, regNumber reg1, regNumber base, int offs, int ival) -{ - noway_assert(emitVerifyEncodable(ins, EA_SIZE(attr), reg1)); - assert(IsAvx512OrPriorInstruction(ins)); - - instrDesc* id = emitNewInstrAmdCns(attr, offs, ival); - - id->idIns(ins); - id->idReg1(reg1); + code_t code = 0; - id->idInsFmt(emitInsModeFormat(ins, IF_RRD_ARD_CNS)); - id->idAddr()->iiaAddrMode.amBaseReg = base; - id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; + if (hasCodeMI(ins)) + { + code = insCodeMI(ins); + } + else + { + code = insCodeRM(ins); + } - UNATIVE_OFFSET sz = emitInsSizeAM(id, insCodeRM(ins), ival); + UNATIVE_OFFSET sz = emitInsSizeAM(id, code, ival); id->idCodeSize(sz); dispIns(id); @@ -6519,7 +6515,18 @@ void emitter::emitIns_R_C_I( id->idReg1(reg1); id->idAddr()->iiaFieldHnd = fldHnd; - UNATIVE_OFFSET sz = emitInsSizeCV(id, insCodeRM(ins), ival); + code_t code = 0; + + if (hasCodeMI(ins)) + { + code = insCodeMI(ins); + } + else + { + code = insCodeRM(ins); + } + + UNATIVE_OFFSET sz = emitInsSizeCV(id, code, ival); id->idCodeSize(sz); dispIns(id); @@ -6542,7 +6549,18 @@ void emitter::emitIns_R_S_I(instruction ins, emitAttr attr, regNumber reg1, int id->idDebugOnlyInfo()->idVarRefOffs = emitVarRefOffs; #endif - UNATIVE_OFFSET sz = emitInsSizeSV(id, insCodeRM(ins), varx, offs, ival); + code_t code = 0; + + if (hasCodeMI(ins)) + { + code = insCodeMI(ins); + } + else + { + code = insCodeRM(ins); + } + + UNATIVE_OFFSET sz = emitInsSizeSV(id, code, varx, offs, ival); id->idCodeSize(sz); dispIns(id); @@ -6832,43 +6850,7 @@ void emitter::emitIns_R_R_R_I( id->idReg2(reg1); id->idReg3(reg2); - code_t code = 0; - - switch (ins) - { - case INS_pextrb: - case INS_pextrd: - case INS_pextrq: - case INS_pextrw_sse41: - case INS_extractps: - case INS_vextractf128: - case INS_vextractf32x8: - case INS_vextractf64x2: - case INS_vextractf64x4: - case INS_vextracti128: - case INS_vextracti32x8: - case INS_vextracti64x2: - case INS_vextracti64x4: - { - code = insCodeMR(ins); - break; - } - - case INS_psrldq: - case INS_pslldq: - { - code = insCodeMI(ins); - break; - } - - default: - { - code = insCodeRM(ins); - break; - } - } - - UNATIVE_OFFSET sz = emitInsSizeRR(id, code, ival); + UNATIVE_OFFSET sz = emitInsSizeRR(id, insCodeRM(ins), ival); id->idCodeSize(sz); dispIns(id); @@ -12324,6 +12306,9 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc) case IF_RWR_ARD: case IF_RRW_ARD: case IF_AWR_RRD_RRD: + case IF_RRD_ARD_CNS: + case IF_RWR_ARD_CNS: + case IF_RRW_ARD_CNS: { src1 = id->idReg1(); break; @@ -16457,7 +16442,20 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsAmdCns(id, &cnsVal); - code = insCodeRM(ins); + + if (hasCodeMI(ins)) + { + assert(TakesEvexPrefix(id)); + assert(!EncodedBySSE38orSSE3A(ins)); + + code = insCodeMI(ins); + regcode = insEncodeReg345(id, getSseShiftRegNumber(ins), size, &code); + } + else + { + code = insCodeRM(ins); + regcode = insEncodeReg345(id, id->idReg1(), size, &code); + } if (EncodedBySSE38orSSE3A(ins)) { @@ -16467,9 +16465,21 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } else { - code = AddSimdPrefixIfNeeded(id, code, size); - regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputAM(dst, id, code | regcode, &cnsVal); + code = AddSimdPrefixIfNeeded(id, code, size); + + // In case of AVX instructions that take 3 operands, encode reg1 as first source. + // Note that reg1 is both a source and a destination. + // + // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For + // now we use the single source as source1 and source2. + // For this format, moves do not support a third operand, so we only need to handle the binary ops. + if (IsDstDstSrcAVXInstruction(ins)) + { + // encode source operand reg in 'vvvv' bits in 1's complement form + code = insEncodeReg3456(id, id->idReg1(), size, code); + } + + dst = emitOutputAM(dst, id, code | (regcode << 8), &cnsVal); } sz = emitSizeOfInsDsc_AMD(id); @@ -16667,7 +16677,20 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsCns(id, &cnsVal); - code = insCodeRM(ins); + + if (hasCodeMI(ins)) + { + assert(TakesEvexPrefix(id)); + assert(!EncodedBySSE38orSSE3A(ins)); + + code = insCodeMI(ins); + regcode = insEncodeReg345(id, getSseShiftRegNumber(ins), size, &code); + } + else + { + code = insCodeRM(ins); + regcode = insEncodeReg345(id, id->idReg1(), size, &code); + } if (EncodedBySSE38orSSE3A(ins)) { @@ -16691,8 +16714,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = insEncodeReg3456(id, id->idReg1(), size, code); } - regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputSV(dst, id, code | regcode, &cnsVal); + dst = emitOutputSV(dst, id, code | (regcode << 8), &cnsVal); } sz = emitSizeOfInsDsc_CNS(id); @@ -16865,7 +16887,20 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(IsAvx512OrPriorInstruction(ins)); emitGetInsDcmCns(id, &cnsVal); - code = insCodeRM(ins); + + if (hasCodeMI(ins)) + { + assert(TakesEvexPrefix(id)); + assert(!EncodedBySSE38orSSE3A(ins)); + + code = insCodeMI(ins); + regcode = insEncodeReg345(id, getSseShiftRegNumber(ins), size, &code); + } + else + { + code = insCodeRM(ins); + regcode = insEncodeReg345(id, id->idReg1(), size, &code); + } if (EncodedBySSE38orSSE3A(ins)) { @@ -16889,8 +16924,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = insEncodeReg3456(id, id->idReg1(), size, code); } - regcode = (insEncodeReg345(id, id->idReg1(), size, &code) << 8); - dst = emitOutputCV(dst, id, code | regcode | 0x0500, &cnsVal); + dst = emitOutputCV(dst, id, code | (regcode << 8) | 0x0500, &cnsVal); } sz = emitSizeOfInsDsc_DSP(id); @@ -18282,6 +18316,50 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins break; } + case INS_vpconflictd: + { + if (opSize == EA_16BYTE) + { + result.insThroughput = PERFSCORE_THROUGHPUT_6C; + result.insLatency += PERFSCORE_LATENCY_12C; + } + else if (opSize == EA_32BYTE) + { + result.insThroughput = PERFSCORE_THROUGHPUT_10C; + result.insLatency += PERFSCORE_LATENCY_16C; + } + else + { + assert(opSize == EA_64BYTE); + + result.insThroughput = PERFSCORE_THROUGHPUT_19C; + result.insLatency += PERFSCORE_LATENCY_26C; + } + break; + } + + case INS_vpconflictq: + { + if (opSize == EA_16BYTE) + { + result.insThroughput = PERFSCORE_THROUGHPUT_2C; + result.insLatency += PERFSCORE_LATENCY_4C; + } + else if (opSize == EA_32BYTE) + { + result.insThroughput = PERFSCORE_THROUGHPUT_6C; + result.insLatency += PERFSCORE_LATENCY_12C; + } + else + { + assert(opSize == EA_64BYTE); + + result.insThroughput = PERFSCORE_THROUGHPUT_10C; + result.insLatency += PERFSCORE_LATENCY_16C; + } + break; + } + case INS_roundpd: case INS_roundps: case INS_roundsd: @@ -18559,6 +18637,7 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_pext: case INS_pcmpgtq: case INS_psadbw: + case INS_vdbpsadbw: case INS_vpermps: case INS_vpermpd: case INS_vpermpd_reg: @@ -18583,9 +18662,11 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vinserti32x8: case INS_vinserti64x2: case INS_vinserti64x4: + { result.insThroughput = PERFSCORE_THROUGHPUT_1C; result.insLatency += PERFSCORE_LATENCY_3C; break; + } case INS_vpermw: result.insThroughput = PERFSCORE_THROUGHPUT_2C; @@ -18637,9 +18718,13 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vcmppd: case INS_vcmpss: case INS_vcmpsd: + case INS_vplzcntd: + case INS_vplzcntq: + { result.insThroughput = PERFSCORE_THROUGHPUT_2X; result.insLatency = PERFSCORE_LATENCY_4C; break; + } case INS_mulx: case INS_maxps: diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 1ac3ad219ab9b..8dcbb9ecf75a8 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -567,8 +567,6 @@ void emitIns_R_A(instruction ins, emitAttr attr, regNumber reg1, GenTreeIndir* i void emitIns_R_A_I(instruction ins, emitAttr attr, regNumber reg1, GenTreeIndir* indir, int ival); -void emitIns_R_AR_I(instruction ins, emitAttr attr, regNumber reg1, regNumber base, int offs, int ival); - void emitIns_R_C_I(instruction ins, emitAttr attr, regNumber reg1, CORINFO_FIELD_HANDLE fldHnd, int offs, int ival); void emitIns_R_S_I(instruction ins, emitAttr attr, regNumber reg1, int varx, int offs, int ival); diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index dc4451faefd3d..f3b2d6d714e71 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -101,6 +101,8 @@ GTNODE(ARR_ADDR , GenTreeArrAddr ,0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) GTNODE(BSWAP , GenTreeOp ,0,GTK_UNOP) // Byte swap (32-bit or 64-bit) GTNODE(BSWAP16 , GenTreeOp ,0,GTK_UNOP) // Byte swap lower 16-bits and zero upper 16 bits +GTNODE(LZCNT , GenTreeOp ,0,GTK_UNOP) // Leading Zero Count - Only used for SIMD VN evaluation today + //----------------------------------------------------------------------------- // Binary operators (2 operands): //----------------------------------------------------------------------------- diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index b94b24e628b43..93a3d9612a1be 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -1023,6 +1023,7 @@ HARDWARE_INTRINSIC(AVX512BW, Store, HARDWARE_INTRINSIC(AVX512BW, Subtract, 64, 2, {INS_psubb, INS_psubb, INS_psubw, INS_psubw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, SubtractSaturate, 64, 2, {INS_psubsb, INS_psubusb, INS_psubsw, INS_psubusw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, SumAbsoluteDifferences, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_psadbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512BW, SumAbsoluteDifferencesInBlock32, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_vdbpsadbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512BW, UnpackHigh, 64, 2, {INS_punpckhbw, INS_punpckhbw, INS_punpckhwd, INS_punpckhwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW, UnpackLow, 64, 2, {INS_punpcklbw, INS_punpcklbw, INS_punpcklwd, INS_punpcklwd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) @@ -1040,6 +1041,23 @@ HARDWARE_INTRINSIC(AVX512BW_VL, PermuteVar16x16, HARDWARE_INTRINSIC(AVX512BW_VL, ShiftLeftLogicalVariable, -1, 2, {INS_invalid, INS_invalid, INS_vpsllvw, INS_vpsllvw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW_VL, ShiftRightArithmeticVariable, -1, 2, {INS_invalid, INS_invalid, INS_vpsravw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512BW_VL, ShiftRightLogicalVariable, -1, 2, {INS_invalid, INS_invalid, INS_vpsrlvw, INS_vpsrlvw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512BW_VL, SumAbsoluteDifferencesInBlock32, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_vdbpsadbw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX512CD Intrinsics +HARDWARE_INTRINSIC(AVX512CD, DetectConflicts, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpconflictd, INS_vpconflictd, INS_vpconflictq, INS_vpconflictq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512CD, LeadingZeroCount, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vplzcntd, INS_vplzcntd, INS_vplzcntq, INS_vplzcntq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) + +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// ISA Function name SIMD size NumArg Instructions Category Flags +// {TYP_BYTE, TYP_UBYTE, TYP_SHORT, TYP_USHORT, TYP_INT, TYP_UINT, TYP_LONG, TYP_ULONG, TYP_FLOAT, TYP_DOUBLE} +// *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** +// AVX512CD.VL Intrinsics +HARDWARE_INTRINSIC(AVX512CD_VL, DetectConflicts, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpconflictd, INS_vpconflictd, INS_vpconflictq, INS_vpconflictq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512CD_VL, LeadingZeroCount, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vplzcntd, INS_vplzcntd, INS_vplzcntq, INS_vplzcntq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 6cfa7862d7841..bb8a75bc77cc7 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -728,6 +728,7 @@ INST3(kmovq_gpr, "kmovq", IUM_WR, BAD_CODE, BAD_ INST3(kmovq_msk, "kmovq", IUM_WR, PCKFLT(0x91), BAD_CODE, PCKFLT(0x90), INS_TT_NONE, REX_W1 | Encoding_VEX | KInstruction) INST3(kortestd, "kortestd", IUM_RD, BAD_CODE, BAD_CODE, PCKDBL(0x98), INS_TT_NONE, REX_W1 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) INST3(kortestq, "kortestq", IUM_RD, BAD_CODE, BAD_CODE, PCKFLT(0x98), INS_TT_NONE, REX_W1 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) +INST3(vdbpsadbw, "dbpsadbw", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x42), INS_TT_FULL_MEM, Input_8Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Double block packed Sum-Absolute-Differences (SAD) on unsigned bytes INST3(vmovdqu8, "movdqu8", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_8Bit | REX_W0 | Encoding_EVEX) INST3(vmovdqu16, "movdqu16", IUM_WR, SSEFLT(0x7F), BAD_CODE, SSEFLT(0x6F), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX) INST3(vpbroadcastb_gpr, "pbroadcastb", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x7A), INS_TT_TUPLE1_SCALAR, Input_8Bit | REX_W0 | Encoding_EVEX) // Broadcast int8 value from gpr to entire register @@ -752,6 +753,12 @@ INST3(vpsllvw, "psllvw", IUM_WR, BAD_CODE, BAD_ INST3(vpsravw, "psravw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x11), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Arithmetic INST3(vpsrlvw, "psrlvw", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x10), INS_TT_FULL_MEM, Input_16Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Logical +// AVX512CD +INST3(vpconflictd, "pconflictd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xC4), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Detect conflicts within a vector of packed dword values into dense memory/register +INST3(vpconflictq, "pconflictq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xC4), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Detect conflicts within a vector of packed qword values into dense memory/register +INST3(vplzcntd, "plzcntd", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x44), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX) // Count the number of leading zero bits for packed dword values +INST3(vplzcntq, "plzcntq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x44), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX) // Count the number of leading zero bits for packed qword values + // AVX512DQ INST3(kortestb, "kortestb", IUM_RD, BAD_CODE, BAD_CODE, PCKDBL(0x98), INS_TT_NONE, REX_W0 | Encoding_VEX | Resets_OF | Resets_SF | Writes_ZF | Resets_AF | Resets_PF | Writes_CF | KInstruction) INST3(kmovb_gpr, "kmovb", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0x92), INS_TT_NONE, REX_W0 | Encoding_VEX | KInstruction) diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index be42755bd82a1..1b1d125c3c35d 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -6973,19 +6973,25 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX2_ShuffleLow: case NI_AVX512F_AlignRight32: case NI_AVX512F_AlignRight64: + case NI_AVX512F_Fixup: + case NI_AVX512F_GetMantissa: case NI_AVX512F_Permute2x64: case NI_AVX512F_Permute4x32: case NI_AVX512F_Permute4x64: case NI_AVX512F_RotateLeft: case NI_AVX512F_RotateRight: + case NI_AVX512F_RoundScale: case NI_AVX512F_ShiftLeftLogical: case NI_AVX512F_ShiftRightArithmetic: case NI_AVX512F_ShiftRightLogical: case NI_AVX512F_Shuffle: case NI_AVX512F_VL_AlignRight32: case NI_AVX512F_VL_AlignRight64: + case NI_AVX512F_VL_Fixup: + case NI_AVX512F_VL_GetMantissa: case NI_AVX512F_VL_RotateLeft: case NI_AVX512F_VL_RotateRight: + case NI_AVX512F_VL_RoundScale: case NI_AVX512F_VL_ShiftRightArithmetic: case NI_AVX512BW_AlignRight: case NI_AVX512BW_ShiftLeftLogical: @@ -6993,6 +6999,12 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX512BW_ShiftRightLogical: case NI_AVX512BW_ShuffleHigh: case NI_AVX512BW_ShuffleLow: + case NI_AVX512BW_SumAbsoluteDifferencesInBlock32: + case NI_AVX512BW_VL_SumAbsoluteDifferencesInBlock32: + case NI_AVX512DQ_Range: + case NI_AVX512DQ_Reduce: + case NI_AVX512DQ_VL_Range: + case NI_AVX512DQ_VL_Reduce: { assert(!supportsSIMDScalarLoads); @@ -7005,6 +7017,34 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre break; } + case NI_SSE2_ShiftLeftLogical128BitLane: + case NI_SSE2_ShiftRightLogical128BitLane: + case NI_AVX2_ShiftLeftLogical128BitLane: + case NI_AVX2_ShiftRightLogical128BitLane: + case NI_AVX512BW_ShiftLeftLogical128BitLane: + case NI_AVX512BW_ShiftRightLogical128BitLane: + { + if (comp->compOpportunisticallyDependsOn(InstructionSet_Vector512)) + { + assert(!supportsSIMDScalarLoads); + + const unsigned expectedSize = genTypeSize(parentNode->GetSimdBaseType()); + const unsigned operandSize = genTypeSize(childNode->TypeGet()); + + supportsAlignedSIMDLoads = !comp->canUseVexEncoding() || !comp->opts.MinOpts(); + supportsUnalignedSIMDLoads = comp->canUseVexEncoding(); + supportsGeneralLoads = supportsUnalignedSIMDLoads && (operandSize >= expectedSize); + } + else + { + assert(supportsAlignedSIMDLoads == false); + assert(supportsGeneralLoads == false); + assert(supportsSIMDScalarLoads == false); + assert(supportsUnalignedSIMDLoads == false); + } + break; + } + case NI_AVX_InsertVector128: case NI_AVX2_InsertVector128: case NI_AVX512F_InsertVector128: @@ -7092,6 +7132,11 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre } case NI_AVX_CompareScalar: + case NI_AVX512F_FixupScalar: + case NI_AVX512F_GetMantissaScalar: + case NI_AVX512F_RoundScaleScalar: + case NI_AVX512DQ_RangeScalar: + case NI_AVX512DQ_ReduceScalar: { assert(supportsAlignedSIMDLoads == false); assert(supportsUnalignedSIMDLoads == false); @@ -7897,17 +7942,22 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX512BW_ShiftLeftLogical128BitLane: case NI_AVX512BW_ShiftRightLogical128BitLane: { -#if DEBUG - // These intrinsics should have been marked contained by the general-purpose handling - // earlier in the method. + // These intrinsics have op2 as an imm and op1 as a reg/mem when AVX512BW+VL is supported - GenTree* lastOp = node->Op(numArgs); + if (!isContainedImm) + { + // Don't contain if we're generating a jmp table fallback + break; + } - if (HWIntrinsicInfo::isImmOp(intrinsicId, lastOp) && lastOp->IsCnsIntOrI()) + if (IsContainableHWIntrinsicOp(node, op1, &supportsRegOptional)) { - assert(lastOp->isContained()); + MakeSrcContained(node, op1); + } + else if (supportsRegOptional) + { + MakeSrcRegOptional(node, op1); } -#endif break; } @@ -8178,6 +8228,8 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) case NI_AVX512F_VL_AlignRight32: case NI_AVX512F_VL_AlignRight64: case NI_AVX512BW_AlignRight: + case NI_AVX512BW_SumAbsoluteDifferencesInBlock32: + case NI_AVX512BW_VL_SumAbsoluteDifferencesInBlock32: case NI_AVX512DQ_InsertVector128: case NI_AVX512DQ_InsertVector256: case NI_AVX512DQ_Range: diff --git a/src/coreclr/jit/simd.h b/src/coreclr/jit/simd.h index d81016561c849..478b0a1af4f4a 100644 --- a/src/coreclr/jit/simd.h +++ b/src/coreclr/jit/simd.h @@ -292,6 +292,22 @@ TBase EvaluateUnaryScalarSpecialized(genTreeOps oper, TBase arg0) return ~arg0; } + case GT_LZCNT: + { + if (sizeof(TBase) == sizeof(uint32_t)) + { + uint32_t result = BitOperations::LeadingZeroCount(static_cast(arg0)); + return static_cast(result); + } + else if (sizeof(TBase) == sizeof(uint64_t)) + { + uint64_t result = BitOperations::LeadingZeroCount(static_cast(arg0)); + return static_cast(result); + } + + unreached(); + } + default: { unreached(); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 45e3a85308019..3fa36755d4e41 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7017,6 +7017,12 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunUnary(var_types type, #endif // TARGET_ARM64 #if defined(TARGET_XARCH) + case NI_AVX512CD_LeadingZeroCount: + case NI_AVX512CD_VL_LeadingZeroCount: + { + return EvaluateUnarySimd(this, GT_LZCNT, /* scalar */ false, type, baseType, arg0VN); + } + case NI_BMI1_TrailingZeroCount: { assert(!varTypeIsSmall(type) && !varTypeIsLong(type)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs index 4b6fcabee54e3..5f8c4fbf66d4b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.PlatformNotSupported.cs @@ -158,6 +158,17 @@ internal VL() { } /// VPSRLVW ymm1 {k1}{z}, ymm2, ymm3/m256 /// public static Vector256 ShiftRightLogicalVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_dbsad_epu8 (__m128i a, __m128i b, int imm8) + /// VDBPSADBW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 SumAbsoluteDifferencesInBlock32(Vector128 left, Vector128 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_dbsad_epu8 (__m256i a, __m256i b, int imm8) + /// VDBPSADBW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 SumAbsoluteDifferencesInBlock32(Vector256 left, Vector256 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } } public new abstract class X64 : Avx512F.X64 @@ -659,6 +670,12 @@ internal X64() { } /// public static Vector512 SumAbsoluteDifferences(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_dbsad_epu8 (__m512i a, __m512i b) + /// VDBPSADBW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 SumAbsoluteDifferencesInBlock32(Vector512 left, Vector512 right, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_unpackhi_epi8 (__m512i a, __m512i b) /// VPUNPCKHBW zmm1 {k1}{z}, zmm2, zmm3/m512 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs index 79a3219fe4c4a..19f1c1ab35aa9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512BW.cs @@ -158,6 +158,17 @@ internal VL() { } /// VPSRLVW ymm1 {k1}{z}, ymm2, ymm3/m256 /// public static Vector256 ShiftRightLogicalVariable(Vector256 value, Vector256 count) => ShiftRightLogicalVariable(value, count); + + /// + /// __m128i _mm_dbsad_epu8 (__m128i a, __m128i b, int imm8) + /// VDBPSADBW xmm1 {k1}{z}, xmm2, xmm3/m128 + /// + public static Vector128 SumAbsoluteDifferencesInBlock32(Vector128 left, Vector128 right, [ConstantExpected] byte control) => SumAbsoluteDifferencesInBlock32(left, right, control); + /// + /// __m256i _mm256_dbsad_epu8 (__m256i a, __m256i b, int imm8) + /// VDBPSADBW ymm1 {k1}{z}, ymm2, ymm3/m256 + /// + public static Vector256 SumAbsoluteDifferencesInBlock32(Vector256 left, Vector256 right, [ConstantExpected] byte control) => SumAbsoluteDifferencesInBlock32(left, right, control); } [Intrinsic] @@ -660,6 +671,12 @@ internal X64() { } /// public static Vector512 SumAbsoluteDifferences(Vector512 left, Vector512 right) => SumAbsoluteDifferences(left, right); + /// + /// __m512i _mm512_dbsad_epu8 (__m512i a, __m512i b, int imm8) + /// VDBPSADBW zmm1 {k1}{z}, zmm2, zmm3/m512 + /// + public static Vector512 SumAbsoluteDifferencesInBlock32(Vector512 left, Vector512 right, [ConstantExpected] byte control) => SumAbsoluteDifferencesInBlock32(left, right, control); + /// /// __m512i _mm512_unpackhi_epi8 (__m512i a, __m512i b) /// VPUNPCKHBW zmm1 {k1}{z}, zmm2, zmm3/m512 diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.PlatformNotSupported.cs index 6004737e1dd8b..f3b0af381a37e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.PlatformNotSupported.cs @@ -21,6 +21,88 @@ internal Avx512CD() { } internal VL() { } public static new bool IsSupported { [Intrinsic] get { return false; } } + + /// + /// __m128i _mm_conflict_epi32 (__m128i a) + /// VPCONFLICTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 DetectConflicts(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_conflict_epi32 (__m128i a) + /// VPCONFLICTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 DetectConflicts(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_conflict_epi64 (__m128i a) + /// VPCONFLICTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 DetectConflicts(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_conflict_epi64 (__m128i a) + /// VPCONFLICTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 DetectConflicts(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_conflict_epi32 (__m256i a) + /// VPCONFLICTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 DetectConflicts(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_conflict_epi32 (__m256i a) + /// VPCONFLICTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 DetectConflicts(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_conflict_epi64 (__m256i a) + /// VPCONFLICTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 DetectConflicts(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_conflict_epi64 (__m256i a) + /// VPCONFLICTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 DetectConflicts(Vector256 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_lzcnt_epi32 (__m128i a) + /// VPLZCNTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_lzcnt_epi32 (__m128i a) + /// VPLZCNTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_lzcnt_epi64 (__m128i a) + /// VPLZCNTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_lzcnt_epi64 (__m128i a) + /// VPLZCNTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_lzcnt_epi32 (__m256i a) + /// VPLZCNTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_lzcnt_epi32 (__m256i a) + /// VPLZCNTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_lzcnt_epi64 (__m256i a) + /// VPLZCNTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_lzcnt_epi64 (__m256i a) + /// VPLZCNTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) { throw new PlatformNotSupportedException(); } } public new abstract class X64 : Avx512F.X64 @@ -29,5 +111,47 @@ internal X64() { } public static new bool IsSupported { [Intrinsic] get { return false; } } } + + /// + /// __m512i _mm512_conflict_epi32 (__m512i a) + /// VPCONFLICTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 DetectConflicts(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_conflict_epi32 (__m512i a) + /// VPCONFLICTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 DetectConflicts(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_conflict_epi64 (__m512i a) + /// VPCONFLICTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 DetectConflicts(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_conflict_epi64 (__m512i a) + /// VPCONFLICTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 DetectConflicts(Vector512 value) { throw new PlatformNotSupportedException(); } + + /// + /// __m512i _mm512_lzcnt_epi32 (__m512i a) + /// VPLZCNTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_lzcnt_epi32 (__m512i a) + /// VPLZCNTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_lzcnt_epi64 (__m512i a) + /// VPLZCNTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_lzcnt_epi64 (__m512i a) + /// VPLZCNTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) { throw new PlatformNotSupportedException(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.cs index c2a80f48aefbe..aa1429b97ba42 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512CD.cs @@ -21,6 +21,88 @@ internal Avx512CD() { } internal VL() { } public static new bool IsSupported { get => IsSupported; } + + /// + /// __m128i _mm_conflict_epi32 (__m128i a) + /// VPCONFLICTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 DetectConflicts(Vector128 value) => DetectConflicts(value); + /// + /// __m128i _mm_conflict_epi32 (__m128i a) + /// VPCONFLICTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 DetectConflicts(Vector128 value) => DetectConflicts(value); + /// + /// __m128i _mm_conflict_epi64 (__m128i a) + /// VPCONFLICTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 DetectConflicts(Vector128 value) => DetectConflicts(value); + /// + /// __m128i _mm_conflict_epi64 (__m128i a) + /// VPCONFLICTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 DetectConflicts(Vector128 value) => DetectConflicts(value); + /// + /// __m256i _mm256_conflict_epi32 (__m256i a) + /// VPCONFLICTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 DetectConflicts(Vector256 value) => DetectConflicts(value); + /// + /// __m256i _mm256_conflict_epi32 (__m256i a) + /// VPCONFLICTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 DetectConflicts(Vector256 value) => DetectConflicts(value); + /// + /// __m256i _mm256_conflict_epi64 (__m256i a) + /// VPCONFLICTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 DetectConflicts(Vector256 value) => DetectConflicts(value); + /// + /// __m256i _mm256_conflict_epi64 (__m256i a) + /// VPCONFLICTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 DetectConflicts(Vector256 value) => DetectConflicts(value); + + /// + /// __m128i _mm_lzcnt_epi32 (__m128i a) + /// VPLZCNTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) => LeadingZeroCount(value); + /// + /// __m128i _mm_lzcnt_epi32 (__m128i a) + /// VPLZCNTD xmm1 {k1}{z}, xmm2/m128/m32bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) => LeadingZeroCount(value); + /// + /// __m128i _mm_lzcnt_epi64 (__m128i a) + /// VPLZCNTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) => LeadingZeroCount(value); + /// + /// __m128i _mm_lzcnt_epi64 (__m128i a) + /// VPLZCNTQ xmm1 {k1}{z}, xmm2/m128/m64bcst + /// + public static Vector128 LeadingZeroCount(Vector128 value) => LeadingZeroCount(value); + /// + /// __m256i _mm256_lzcnt_epi32 (__m256i a) + /// VPLZCNTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) => LeadingZeroCount(value); + /// + /// __m256i _mm256_lzcnt_epi32 (__m256i a) + /// VPLZCNTD ymm1 {k1}{z}, ymm2/m256/m32bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) => LeadingZeroCount(value); + /// + /// __m256i _mm256_lzcnt_epi64 (__m256i a) + /// VPLZCNTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) => LeadingZeroCount(value); + /// + /// __m256i _mm256_lzcnt_epi64 (__m256i a) + /// VPLZCNTQ ymm1 {k1}{z}, ymm2/m256/m64bcst + /// + public static Vector256 LeadingZeroCount(Vector256 value) => LeadingZeroCount(value); } [Intrinsic] @@ -30,5 +112,47 @@ internal X64() { } public static new bool IsSupported { get => IsSupported; } } + + /// + /// __m512i _mm512_conflict_epi32 (__m512i a) + /// VPCONFLICTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 DetectConflicts(Vector512 value) => DetectConflicts(value); + /// + /// __m512i _mm512_conflict_epi32 (__m512i a) + /// VPCONFLICTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 DetectConflicts(Vector512 value) => DetectConflicts(value); + /// + /// __m512i _mm512_conflict_epi64 (__m512i a) + /// VPCONFLICTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 DetectConflicts(Vector512 value) => DetectConflicts(value); + /// + /// __m512i _mm512_conflict_epi64 (__m512i a) + /// VPCONFLICTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 DetectConflicts(Vector512 value) => DetectConflicts(value); + + /// + /// __m512i _mm512_lzcnt_epi32 (__m512i a) + /// VPLZCNTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) => LeadingZeroCount(value); + /// + /// __m512i _mm512_lzcnt_epi32 (__m512i a) + /// VPLZCNTD zmm1 {k1}{z}, zmm2/m512/m32bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) => LeadingZeroCount(value); + /// + /// __m512i _mm512_lzcnt_epi64 (__m512i a) + /// VPLZCNTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) => LeadingZeroCount(value); + /// + /// __m512i _mm512_lzcnt_epi64 (__m512i a) + /// VPLZCNTQ zmm1 {k1}{z}, zmm2/m512/m64bcst + /// + public static Vector512 LeadingZeroCount(Vector512 value) => LeadingZeroCount(value); } } diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 658e831f49853..553d1a5713bde 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4495,6 +4495,7 @@ internal Avx512BW() { } public static System.Runtime.Intrinsics.Vector512 SubtractSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 SubtractSaturate(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 SumAbsoluteDifferences(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 SumAbsoluteDifferencesInBlock32(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector512 UnpackHigh(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 UnpackHigh(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 UnpackHigh(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } @@ -4533,6 +4534,8 @@ internal VL() { } public static System.Runtime.Intrinsics.Vector128 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } public static System.Runtime.Intrinsics.Vector256 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } public static System.Runtime.Intrinsics.Vector256 ShiftRightLogicalVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 SumAbsoluteDifferencesInBlock32(System.Runtime.Intrinsics.Vector128 left, System.Runtime.Intrinsics.Vector128 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 SumAbsoluteDifferencesInBlock32(System.Runtime.Intrinsics.Vector256 left, System.Runtime.Intrinsics.Vector256 right, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } } public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx512F.X64 { @@ -4545,10 +4548,34 @@ public abstract partial class Avx512CD : System.Runtime.Intrinsics.X86.Avx512F { internal Avx512CD() { } public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector512 DetectConflicts(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 DetectConflicts(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 DetectConflicts(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 DetectConflicts(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 LeadingZeroCount(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 LeadingZeroCount(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 LeadingZeroCount(System.Runtime.Intrinsics.Vector512 value) { throw null; } + public static System.Runtime.Intrinsics.Vector512 LeadingZeroCount(System.Runtime.Intrinsics.Vector512 value) { throw null; } public new abstract partial class VL : System.Runtime.Intrinsics.X86.Avx512F.VL { internal VL() { } public static new bool IsSupported { get { throw null; } } + public static System.Runtime.Intrinsics.Vector128 DetectConflicts(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DetectConflicts(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DetectConflicts(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 DetectConflicts(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 DetectConflicts(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 DetectConflicts(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 DetectConflicts(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 DetectConflicts(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 LeadingZeroCount(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 LeadingZeroCount(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 LeadingZeroCount(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector128 LeadingZeroCount(System.Runtime.Intrinsics.Vector128 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 LeadingZeroCount(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 LeadingZeroCount(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 LeadingZeroCount(System.Runtime.Intrinsics.Vector256 value) { throw null; } + public static System.Runtime.Intrinsics.Vector256 LeadingZeroCount(System.Runtime.Intrinsics.Vector256 value) { throw null; } } public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx512F.X64 { diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index 19f58e71d7a98..87e5fe5d3a40f 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -408,7 +408,7 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "SseVerify.SubtractSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "SseVerify.SubtractSaturate(left[i], right[i], result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "SseVerify.SubtractSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "SseVerify.SubtractSaturate(left[i], right[i], result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SumAbsoluteDifferences", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != Math.Abs(left[0] - right[0]) + Math.Abs(left[1] - right[1]) + Math.Abs(left[2] - right[2]) + Math.Abs(left[3] - right[3]) + Math.Abs(left[4] - right[4]) + Math.Abs(left[5] - right[5]) + Math.Abs(left[6] - right[6]) + Math.Abs(left[7] - right[7])", ["ValidateRemainingResults"] = "result[i] != (i != 4 ? 0 : Math.Abs(left[8] - right[8]) + Math.Abs(left[9] - right[9]) + Math.Abs(left[10] - right[10]) + Math.Abs(left[11] - right[11]) + Math.Abs(left[12] - right[12]) + Math.Abs(left[13] - right[13]) + Math.Abs(left[14] - right[14]) + Math.Abs(left[15] - right[15]))"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SumAbsoluteDifferences", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != SseVerify.SumAbsoluteDifferences(left, right, 0)", ["ValidateRemainingResults"] = "result[i] != SseVerify.SumAbsoluteDifferences(left, right, i)"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[1])", ["ValidateRemainingResults"] = "((i & 1) == 0) ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i/2+1]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[(i - 1)/2 + 1])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != left[1] || result[1] != right[1]", ["ValidateRemainingResults"] = "((i & 1) == 0) ? result[i] != left[i/2 + 1] : result[i] != right[(i - 1)/2 + 1]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[1] || result[1] != right[1]", ["ValidateRemainingResults"] = "((i & 1) == 0) ? result[i] != left[i/2 + 1] : result[i] != right[(i - 1)/2 + 1]"}), @@ -1031,7 +1031,7 @@ ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ShuffleHigh", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "228", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ShuffleLow", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "228", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ShuffleLow", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "228", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[i]"}), - ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "SumAbsoluteDifferences", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != Math.Abs(left[0] - right[0]) + Math.Abs(left[1] - right[1]) + Math.Abs(left[2] - right[2]) + Math.Abs(left[3] - right[3]) + Math.Abs(left[4] - right[4]) + Math.Abs(left[5] - right[5]) + Math.Abs(left[6] - right[6]) + Math.Abs(left[7] - right[7])", ["ValidateRemainingResults"] = "result[i] != (((i & 3) != 0) ? 0 : Math.Abs(left[(i/4)*8] - right[(i/4)*8]) + Math.Abs(left[(i/4)*8+1] - right[(i/4)*8+1]) + Math.Abs(left[(i/4)*8+2] - right[(i/4)*8+2]) + Math.Abs(left[(i/4)*8+3] - right[(i/4)*8+3]) + Math.Abs(left[(i/4)*8+4] - right[(i/4)*8+4]) + Math.Abs(left[(i/4)*8+5] - right[(i/4)*8+5]) + Math.Abs(left[(i/4)*8+6] - right[(i/4)*8+6]) + Math.Abs(left[(i/4)*8+7] - right[(i/4)*8+7]))"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "SumAbsoluteDifferences", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != SseVerify.SumAbsoluteDifferences(left, right, 0)", ["ValidateRemainingResults"] = "result[i] != SseVerify.SumAbsoluteDifferences(left, right, i)"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "(byte)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(byte)(left[i] - right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "(short)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] - right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "Subtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "(int)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] - right[i]) != result[i]"}), @@ -1736,7 +1736,8 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW", ["LoadIsa"] = "Avx512F", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "SseVerify.SubtractSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "SseVerify.SubtractSaturate(left[i], right[i], result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW", ["LoadIsa"] = "Avx512F", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "SseVerify.SubtractSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "SseVerify.SubtractSaturate(left[i], right[i], result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW", ["LoadIsa"] = "Avx512F", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "SseVerify.SubtractSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "SseVerify.SubtractSaturate(left[i], right[i], result[i])"}), - ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW", ["LoadIsa"] = "Avx512F", ["Method"] = "SumAbsoluteDifferences", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != Math.Abs(left[0] - right[0]) + Math.Abs(left[1] - right[1]) + Math.Abs(left[2] - right[2]) + Math.Abs(left[3] - right[3]) + Math.Abs(left[4] - right[4]) + Math.Abs(left[5] - right[5]) + Math.Abs(left[6] - right[6]) + Math.Abs(left[7] - right[7])", ["ValidateRemainingResults"] = "result[i] != (((i & 3) != 0) ? 0 : Math.Abs(left[(i/4)*8] - right[(i/4)*8]) + Math.Abs(left[(i/4)*8+1] - right[(i/4)*8+1]) + Math.Abs(left[(i/4)*8+2] - right[(i/4)*8+2]) + Math.Abs(left[(i/4)*8+3] - right[(i/4)*8+3]) + Math.Abs(left[(i/4)*8+4] - right[(i/4)*8+4]) + Math.Abs(left[(i/4)*8+5] - right[(i/4)*8+5]) + Math.Abs(left[(i/4)*8+6] - right[(i/4)*8+6]) + Math.Abs(left[(i/4)*8+7] - right[(i/4)*8+7]))"}), + ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW", ["LoadIsa"] = "Avx512F", ["Method"] = "SumAbsoluteDifferences", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != SseVerify.SumAbsoluteDifferences(left, right, 0)", ["ValidateRemainingResults"] = "result[i] != SseVerify.SumAbsoluteDifferences(left, right, i)"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW", ["LoadIsa"] = "Avx512F", ["Method"] = "SumAbsoluteDifferencesInBlock32", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["Imm"] = "228", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.SumAbsoluteDifferencesInBlock32(left, right, 228, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.SumAbsoluteDifferencesInBlock32(left, right, 228, i)"}), }; (string templateFileName, Dictionary templateData)[] Avx512BW_VL_Vector128Inputs = new [] @@ -1754,6 +1755,7 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmeticVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "(ushort)(TestLibrary.Generator.GetUInt16() & 15)", ["ValidateFirstResult"] = "(left[0] >> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >> (int)right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogicalVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "(ushort)(TestLibrary.Generator.GetUInt16() & 15)", ["ValidateFirstResult"] = "(left[0] >>> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >>> (int)right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogicalVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "(ushort)(TestLibrary.Generator.GetUInt16() & 15)", ["ValidateFirstResult"] = "(left[0] >>> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >>> (int)right[i]) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Sse2", ["Method"] = "SumAbsoluteDifferencesInBlock32", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Imm"] = "228", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.SumAbsoluteDifferencesInBlock32(left, right, 228, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.SumAbsoluteDifferencesInBlock32(left, right, 228, i)"}), }; (string templateFileName, Dictionary templateData)[] Avx512BW_VL_Vector256Inputs = new [] @@ -1771,6 +1773,43 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Avx", ["Method"] = "ShiftRightArithmeticVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "(ushort)(TestLibrary.Generator.GetUInt16() & 15)", ["ValidateFirstResult"] = "(left[0] >> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >> (int)right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Avx", ["Method"] = "ShiftRightLogicalVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "(ushort)(TestLibrary.Generator.GetUInt16() & 15)", ["ValidateFirstResult"] = "(left[0] >>> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >>> (int)right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Avx", ["Method"] = "ShiftRightLogicalVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "(ushort)(TestLibrary.Generator.GetUInt16() & 15)", ["ValidateFirstResult"] = "(left[0] >>> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >>> (int)right[i]) != result[i]"}), + ("ImmBinOpTest.template", new Dictionary { ["Isa"] = "Avx512BW.VL", ["LoadIsa"] = "Avx", ["Method"] = "SumAbsoluteDifferencesInBlock32", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["Imm"] = "228", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.SumAbsoluteDifferencesInBlock32(left, right, 228, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.SumAbsoluteDifferencesInBlock32(left, right, 228, i)"}), +}; + +(string templateFileName, Dictionary templateData)[] Avx512CDInputs = new [] +{ + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != int.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != int.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != long.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != long.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != uint.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != uint.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD", ["LoadIsa"] = "Avx512F", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != ulong.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != ulong.LeadingZeroCount(firstOp[i])"}), +}; + +(string templateFileName, Dictionary templateData)[] Avx512CD_VL_Vector128Inputs = new [] +{ + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != int.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != int.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != long.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != long.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != uint.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != uint.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Sse2", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != ulong.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != ulong.LeadingZeroCount(firstOp[i])"}), +}; + +(string templateFileName, Dictionary templateData)[] Avx512CD_VL_Vector256Inputs = new [] +{ + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "DetectConflicts", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != Avx512Verify.DetectConflicts(firstOp, 0)", ["ValidateRemainingResults"] = "result[i] != Avx512Verify.DetectConflicts(firstOp, i)"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != int.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != int.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != long.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != long.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != uint.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != uint.LeadingZeroCount(firstOp[i])"}), + ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512CD.VL", ["LoadIsa"] = "Avx", ["Method"] = "LeadingZeroCount", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != ulong.LeadingZeroCount(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != ulong.LeadingZeroCount(firstOp[i])"}), }; (string templateFileName, Dictionary templateData)[] Avx512DQInputs = new [] diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs b/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs index d6368207d0b52..27de2faa7fc75 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/Avx512Verify.cs @@ -42,6 +42,22 @@ public static bool ValidateFixup(float actual, float x, float y, int z) return !(float.IsNaN(actual) && float.IsNaN(expected)); } + public static TInteger DetectConflicts(TInteger[] firstOp, int i) + where TInteger : IBinaryInteger + { + TInteger result = TInteger.Zero; + + for (int n = 0; n < i - 1; n++) + { + if (firstOp[n] == firstOp[i]) + { + result |= (TInteger.One << n); + } + } + + return result; + } + public static float GetExponent(float x) { int biasedExponent = GetBiasedExponent(x); @@ -72,6 +88,23 @@ public static TFloat Reduce(TFloat x, int m) return x - TFloat.Round(TFloat.ScaleB(TFloat.One, m) * x) * TFloat.ScaleB(TFloat.One, -m); } + public static ushort SumAbsoluteDifferencesInBlock32(byte[] left, byte[] right, byte control, int i) + { + int a = i % 4; + int b = (a < 2) ? 0 : 4; + int c = (i / 4) * 8; + + ushort result = 0; + + for (int n = 0; n < 4; n++) + { + int tmp = int.Abs(left[c + n + b] - right[c + ((control >> (n * 2)) & 3) + a]); + result += (ushort)(tmp); + } + + return result; + } + public static bool ValidateReciprocal14(TFloat actual, TFloat value) where TFloat : IFloatingPointIeee754 { diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs index 09fcea6a89afd..e8bb0545d7c8d 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/SseVerify.cs @@ -45,6 +45,26 @@ public static bool AddSaturate(short x, short y, short z) return value != z; } + public static ushort SumAbsoluteDifferences(byte[] left, byte[] right, int i) + { + int b = (i / 4) * 8; + + if ((i & 3) != 0) + { + return 0; + } + + ushort result = 0; + + for (int n = 0; n < 8; n++) + { + int tmp = int.Abs(left[b + n] - right[b + n]); + result += (ushort)(tmp); + } + + return result; + } + public static bool SubtractSaturate(byte x, byte y, byte z) { int value = (int)x - y; From 2487a19ec2dcc6657a038892701ed8216288695c Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 4 May 2023 18:03:09 -0700 Subject: [PATCH 04/21] Exponse TernaryLogic for Avx512F --- src/coreclr/jit/compiler.h | 10 + src/coreclr/jit/emitxarch.cpp | 1 + src/coreclr/jit/gentree.cpp | 517 ++++++++++++++++-- src/coreclr/jit/hwintrinsic.cpp | 268 +++++++++ src/coreclr/jit/hwintrinsic.h | 100 ++++ src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 21 + src/coreclr/jit/hwintrinsiclistxarch.h | 8 +- src/coreclr/jit/hwintrinsicxarch.cpp | 37 ++ src/coreclr/jit/importervectorization.cpp | 43 +- src/coreclr/jit/instrsxarch.h | 3 +- src/coreclr/jit/lowerxarch.cpp | 50 ++ .../X86/Avx512F.PlatformNotSupported.cs | 170 ++++++ .../System/Runtime/Intrinsics/X86/Avx512F.cs | 170 ++++++ .../ref/System.Runtime.Intrinsics.cs | 30 + .../GenerateHWIntrinsicTests_X86.cs | 127 +++++ 15 files changed, 1516 insertions(+), 39 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 64ae8d35e6fdf..a09c5f234b600 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -2756,6 +2756,16 @@ class Compiler GenTree* gtNewSimdSumNode( var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize); +#if defined(TARGET_XARCH) + GenTree* gtNewSimdTernaryLogicNode(var_types type, + GenTree* op1, + GenTree* op2, + GenTree* op3, + GenTree* op4, + CorInfoType simdBaseJitType, + unsigned simdSize); +#endif // TARGET_XARCH + GenTree* gtNewSimdUnOpNode(genTreeOps op, var_types type, GenTree* op1, diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index d6573c687a2a7..da959d45b1ff0 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -18510,6 +18510,7 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins case INS_vpsrlvq: case INS_vpsrlvw: case INS_vpternlogd: + case INS_vpternlogq: { result.insThroughput = PERFSCORE_THROUGHPUT_2X; result.insLatency += PERFSCORE_LATENCY_1C; diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index c3f65a44bd74a..edb0cd5121e18 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -19388,6 +19388,13 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp) // in the case `op3` is a constant and none of the nibbles are // `0`, then we don't have to be RMW and can actually "drop" `op1` + GenTree* op4 = hwintrinsic->Op(4); + + if (!op4->IsIntegralConst()) + { + return true; + } + GenTree* op3 = hwintrinsic->Op(3); if (!op3->IsCnsVec()) @@ -19423,6 +19430,26 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp) return false; } + case NI_AVX512F_TernaryLogic: + case NI_AVX512F_VL_TernaryLogic: + { + // We may not be RMW depending on the control byte as there + // are many operations that do not use all three inputs. + + GenTree* op4 = hwintrinsic->Op(4); + + if (!op4->IsIntegralConst()) + { + return true; + } + + uint8_t control = static_cast(op4->AsIntCon()->gtIconVal); + const TernaryLogicInfo& info = TernaryLogicInfo::lookup(control); + TernaryLogicUseFlags useFlags = info.GetAllUseFlags(); + + return useFlags == TernaryLogicUseFlags::ABC; + } + default: { return false; @@ -19579,30 +19606,10 @@ GenTree* Compiler::gtNewSimdAbsNode(var_types type, GenTree* op1, CorInfoType si // Abs(v) = v & ~new vector(-0.0); assert((simdSize != 32) || compIsaSupportedDebugOnly(InstructionSet_AVX)); - GenTreeVecCon* bitMask = gtNewVconNode(type); + GenTree* bitMask; - if (simdBaseType == TYP_FLOAT) - { - for (unsigned i = 0; i < (simdSize / 4); i++) - { - // This is -0.0f. We use the bit pattern to avoid - // compiler issues on some platforms. - - bitMask->gtSimdVal.u32[i] = 0x80000000; - } - } - else - { - assert(simdBaseType == TYP_DOUBLE); - - for (unsigned i = 0; i < (simdSize / 8); i++) - { - // This is -0.0. We use the bit pattern to avoid - // compiler issues on some platforms. - - bitMask->gtSimdVal.u64[i] = 0x8000000000000000; - } - } + bitMask = gtNewDconNode(-0.0, simdBaseType); + bitMask = gtNewSimdCreateBroadcastNode(type, bitMask, simdBaseJitType, simdSize); return gtNewSimdBinOpNode(GT_AND_NOT, type, op1, bitMask, simdBaseJitType, simdSize); } @@ -19704,7 +19711,7 @@ GenTree* Compiler::gtNewSimdBinOpNode( if ((op == GT_LSH) || (op == GT_RSH) || (op == GT_RSZ)) { - assert(op2->TypeIs(TYP_INT)); + assert(genActualType(op2) == TYP_INT); } else { @@ -20975,6 +20982,9 @@ GenTree* Compiler::gtNewSimdCmpOpNode( v = gtNewSimdHWIntrinsicNode(type, v, gtNewIconNode(SHUFFLE_ZZXX, TYP_INT), NI_SSE2_Shuffle, CORINFO_TYPE_INT, simdSize); + // Validate we can't use AVX512F_VL_TernaryLogic here + assert(!compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + op2 = gtNewSimdBinOpNode(GT_AND, type, u, v, simdBaseJitType, simdSize); return gtNewSimdBinOpNode(GT_OR, type, op1, op2, simdBaseJitType, simdSize); } @@ -21211,6 +21221,9 @@ GenTree* Compiler::gtNewSimdCmpOpNode( v = gtNewSimdHWIntrinsicNode(type, v, gtNewIconNode(SHUFFLE_ZZXX, TYP_INT), NI_SSE2_Shuffle, CORINFO_TYPE_INT, simdSize); + // Validate we can't use AVX512F_VL_TernaryLogic here + assert(!compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + op2 = gtNewSimdBinOpNode(GT_AND, type, u, v, simdBaseJitType, simdSize); return gtNewSimdBinOpNode(GT_OR, type, op1, op2, simdBaseJitType, simdSize); } @@ -21732,6 +21745,13 @@ GenTree* Compiler::gtNewSimdCndSelNode( #if defined(TARGET_XARCH) assert((simdSize != 32) || compIsaSupportedDebugOnly(InstructionSet_AVX)); + + if (compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) + { + GenTree* control = gtNewIconNode(0xCA); // (B & A) | (C & ~A) + return gtNewSimdTernaryLogicNode(type, op1, op2, op3, control, simdBaseJitType, simdSize); + } + if (simdSize == 32) { intrinsic = NI_Vector256_ConditionalSelect; @@ -23147,6 +23167,9 @@ GenTree* Compiler::gtNewSimdNarrowNode( GenTree* vecCon2 = gtCloneExpr(vecCon1); + // Validate we can't use AVX512F_VL_TernaryLogic here + assert(!compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + tmp1 = gtNewSimdBinOpNode(GT_AND, type, op1, vecCon1, simdBaseJitType, simdSize); tmp2 = gtNewSimdBinOpNode(GT_AND, type, op2, vecCon2, simdBaseJitType, simdSize); tmp3 = gtNewSimdHWIntrinsicNode(type, tmp1, tmp2, NI_AVX2_PackUnsignedSaturate, CORINFO_TYPE_UBYTE, @@ -23185,6 +23208,9 @@ GenTree* Compiler::gtNewSimdNarrowNode( GenTree* vecCon2 = gtCloneExpr(vecCon1); + // Validate we can't use AVX512F_VL_TernaryLogic here + assert(!compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + tmp1 = gtNewSimdBinOpNode(GT_AND, type, op1, vecCon1, simdBaseJitType, simdSize); tmp2 = gtNewSimdBinOpNode(GT_AND, type, op2, vecCon2, simdBaseJitType, simdSize); tmp3 = gtNewSimdHWIntrinsicNode(type, tmp1, tmp2, NI_AVX2_PackUnsignedSaturate, CORINFO_TYPE_USHORT, @@ -23286,6 +23312,9 @@ GenTree* Compiler::gtNewSimdNarrowNode( GenTree* vecCon2 = gtCloneExpr(vecCon1); + // Validate we can't use AVX512F_VL_TernaryLogic here + assert(!compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + tmp1 = gtNewSimdBinOpNode(GT_AND, type, op1, vecCon1, simdBaseJitType, simdSize); tmp2 = gtNewSimdBinOpNode(GT_AND, type, op2, vecCon2, simdBaseJitType, simdSize); @@ -23322,6 +23351,9 @@ GenTree* Compiler::gtNewSimdNarrowNode( GenTree* vecCon2 = gtCloneExpr(vecCon1); + // Validate we can't use AVX512F_VL_TernaryLogic here + assert(!compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + tmp1 = gtNewSimdBinOpNode(GT_AND, type, op1, vecCon1, simdBaseJitType, simdSize); tmp2 = gtNewSimdBinOpNode(GT_AND, type, op2, vecCon2, simdBaseJitType, simdSize); @@ -24133,6 +24165,390 @@ GenTree* Compiler::gtNewSimdSumNode(var_types type, GenTree* op1, CorInfoType si #endif // !TARGET_XARCH && !TARGET_ARM64 } +#if defined(TARGET_XARCH) +GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, + GenTree* op1, + GenTree* op2, + GenTree* op3, + GenTree* op4, + CorInfoType simdBaseJitType, + unsigned simdSize) +{ + assert(IsBaselineVector512IsaSupportedDebugOnly()); + + assert(varTypeIsSIMD(type)); + assert(getSIMDTypeForSize(simdSize) == type); + + assert(op1 != nullptr); + assert(op1->TypeIs(type)); + + assert(op2 != nullptr); + assert(op2->TypeIs(type)); + + assert(op3 != nullptr); + assert(op3->TypeIs(type)); + + assert(op4 != nullptr); + assert(genActualType(op4) == TYP_INT); + + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + assert(varTypeIsArithmetic(simdBaseType)); + + NamedIntrinsic intrinsic = NI_Illegal; + + if (simdSize == 64) + { + intrinsic = NI_AVX512F_TernaryLogic; + } + else + { + assert((simdSize == 16) || (simdSize == 32)); + intrinsic = NI_AVX512F_VL_TernaryLogic; + } + + if (op4->IsIntegralConst()) + { + // We have a constant control byte, so we can potentially optimize + + uint8_t control = static_cast(op4->AsIntCon()->gtIconVal); + const TernaryLogicInfo& info = TernaryLogicInfo::lookup(control); + TernaryLogicUseFlags useFlags = info.GetAllUseFlags(); + + if (useFlags != TernaryLogicUseFlags::ABC) + { + // We are not using all 3 inputs, so we can potentially optimize + + assert(info.oper2 != TernaryLogicOperKind::Select); + assert(info.oper2 != TernaryLogicOperKind::True); + assert(info.oper2 != TernaryLogicOperKind::False); + assert(info.oper2 != TernaryLogicOperKind::Cond); + assert(info.oper2 != TernaryLogicOperKind::Major); + assert(info.oper2 != TernaryLogicOperKind::Minor); + assert(info.oper3 == TernaryLogicOperKind::None); + assert(info.oper3Use == TernaryLogicUseFlags::None); + + GenTree* value1; + GenTree* value2; + + switch (useFlags) + { + case TernaryLogicUseFlags::A: + { + // One operand. We swap it with C so it can be contained where possible + value1 = op1; + value2 = nullptr; + + std::swap(op1, op3); + break; + } + + case TernaryLogicUseFlags::B: + { + // One operand. We swap it with C so it can be contained where possible + value1 = op2; + value2 = nullptr; + + std::swap(op2, op3); + break; + } + + case TernaryLogicUseFlags::C: + { + // One operand. It is already in the ideal position + value1 = op3; + value2 = nullptr; + break; + } + + case TernaryLogicUseFlags::AB: + { + // Two operands. We swap A with C so it can be contained where possible + // and so we aren't RMW + + value1 = op1; + value2 = op2; + + std::swap(op1, op3); + break; + } + + case TernaryLogicUseFlags::AC: + { + // Two operands. We swap A with B so we aren't RMW + + value1 = op1; + value2 = op3; + + std::swap(op1, op2); + break; + } + + case TernaryLogicUseFlags::BC: + { + // Two operands. They are already in the ideal positions + + value1 = op2; + value2 = op3; + break; + } + + case TernaryLogicUseFlags::None: + { + // No operands. + + value1 = nullptr; + value2 = nullptr; + + break; + } + + default: + { + unreached(); + } + } + + switch (info.oper1) + { + case TernaryLogicOperKind::Select: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + assert(value2 == nullptr); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0)) || // A + (control == static_cast(0xCC)) || // B + (control == static_cast(0xAA))); // C + + return value1; + } + + case TernaryLogicOperKind::True: + { + assert(value1 == nullptr); + assert(value2 == nullptr); + + assert(info.oper1Use == TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert(control == static_cast(0xFF)); + + return gtNewAllBitsSetConNode(type); + } + + case TernaryLogicOperKind::False: + { + assert(value1 == nullptr); + assert(value2 == nullptr); + + assert(info.oper1Use == TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert(control == static_cast(0x00)); + + return gtNewZeroConNode(type); + } + + case TernaryLogicOperKind::Not: + { + assert(value1 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + if (info.oper2 == TernaryLogicOperKind::None) + { + assert(value2 == nullptr); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~0xF0)) || // ~A + (control == static_cast(~0xCC)) || // ~B + (control == static_cast(~0xAA))); // ~C + + if (!op1->IsVectorZero()) + { + assert(op1 != value1); + op1 = gtNewZeroConNode(type); + } + + if (!op2->IsVectorZero()) + { + assert(op2 != value1); + op2 = gtNewZeroConNode(type); + } + + assert(value1 == op3); + op4->AsIntCon()->gtIconVal = static_cast(~0xAA); + + break; + } + + assert(value2 != nullptr); + assert(info.oper2Use != TernaryLogicUseFlags::None); + + if (info.oper2 == TernaryLogicOperKind::And) + { + assert((control == static_cast(~0xF0 & 0xCC)) || // ~A & B + (control == static_cast(~0xF0 & 0xAA)) || // ~A & C + (control == static_cast(~0xCC & 0xF0)) || // ~B & A + (control == static_cast(~0xCC & 0xAA)) || // ~B & C + (control == static_cast(~0xAA & 0xF0)) || // ~C & A + (control == static_cast(~0xAA & 0xCC))); // ~C & B + + return gtNewSimdBinOpNode(GT_AND_NOT, type, value2, value1, simdBaseJitType, simdSize); + } + else + { + assert(info.oper2 == TernaryLogicOperKind::Or); + } + break; + } + + case TernaryLogicOperKind::And: + { + assert(value1 != nullptr); + assert(value2 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0 & 0xCC)) || // A & B + (control == static_cast(0xF0 & 0xAA)) || // A & C + (control == static_cast(0xCC & 0xAA))); // B & C + + return gtNewSimdBinOpNode(GT_AND, type, value1, value2, simdBaseJitType, simdSize); + } + + case TernaryLogicOperKind::Nand: + { + assert(value1 != nullptr); + assert(value2 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~(0xF0 & 0xCC))) || // ~(A & B) + (control == static_cast(~(0xF0 & 0xAA))) || // ~(A & C) + (control == static_cast(~(0xCC & 0xAA)))); // ~(B & C) + + if (!op1->IsVectorZero()) + { + assert(op1 != value1); + assert(op1 != value2); + op1 = gtNewZeroConNode(type); + } + + op4->AsIntCon()->gtIconVal = static_cast(~(0xCC & 0xAA)); + break; + } + + case TernaryLogicOperKind::Or: + { + assert(value1 != nullptr); + assert(value2 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0 | 0xCC)) || // A | B + (control == static_cast(0xF0 | 0xAA)) || // A | C + (control == static_cast(0xCC | 0xAA))); // B | C + + return gtNewSimdBinOpNode(GT_OR, type, value1, value2, simdBaseJitType, simdSize); + } + + case TernaryLogicOperKind::Nor: + { + assert(value1 != nullptr); + assert(value2 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~(0xF0 | 0xCC))) || // ~(A | B) + (control == static_cast(~(0xF0 | 0xAA))) || // ~(A | C) + (control == static_cast(~(0xCC | 0xAA)))); // ~(B | C) + + if (!op1->IsVectorZero()) + { + assert(op1 != value1); + assert(op1 != value2); + op1 = gtNewZeroConNode(type); + } + + op4->AsIntCon()->gtIconVal = static_cast(~(0xCC | 0xAA)); + break; + } + + case TernaryLogicOperKind::Xor: + { + assert(value1 != nullptr); + assert(value2 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0 ^ 0xCC)) || // A ^ B + (control == static_cast(0xF0 ^ 0xAA)) || // A ^ C + (control == static_cast(0xCC ^ 0xAA))); // B ^ C + + return gtNewSimdBinOpNode(GT_XOR, type, value1, value2, simdBaseJitType, simdSize); + } + + case TernaryLogicOperKind::Xnor: + { + assert(value1 != nullptr); + assert(value2 != nullptr); + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~(0xF0 ^ 0xCC))) || // ~(A ^ B) + (control == static_cast(~(0xF0 ^ 0xAA))) || // ~(A ^ C) + (control == static_cast(~(0xCC ^ 0xAA)))); // ~(B ^ C) + + if (!op1->IsVectorZero()) + { + assert(op1 != value1); + assert(op1 != value2); + op1 = gtNewZeroConNode(type); + } + + op4->AsIntCon()->gtIconVal = static_cast(~(0xCC ^ 0xAA)); + break; + } + + case TernaryLogicOperKind::None: + case TernaryLogicOperKind::Cond: + case TernaryLogicOperKind::Major: + case TernaryLogicOperKind::Minor: + { + // invalid table metadata + unreached(); + } + + default: + { + unreached(); + } + } + } + } + + return gtNewSimdHWIntrinsicNode(type, op1, op2, op3, op4, intrinsic, simdBaseJitType, simdSize); +} +#endif // TARGET_XARCH + GenTree* Compiler::gtNewSimdUnOpNode( genTreeOps op, var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { @@ -24149,6 +24565,7 @@ GenTree* Compiler::gtNewSimdUnOpNode( NamedIntrinsic intrinsic = NI_Illegal; GenTree* op2 = nullptr; + GenTree* op3 = nullptr; switch (op) { @@ -24164,10 +24581,22 @@ GenTree* Compiler::gtNewSimdUnOpNode( { assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); } - op2 = gtNewZeroConNode(type); - // Zero - op1 - return gtNewSimdBinOpNode(GT_SUB, type, op2, op1, simdBaseJitType, simdSize); + if (varTypeIsFloating(simdBaseType)) + { + // op1 ^ -0.0 + + op2 = gtNewDconNode(-0.0, simdBaseType); + op2 = gtNewSimdCreateBroadcastNode(type, op2, simdBaseJitType, simdSize); + + return gtNewSimdBinOpNode(GT_XOR, type, op1, op2, simdBaseJitType, simdSize); + } + else + { + // Zero - op1 + op2 = gtNewZeroConNode(type); + return gtNewSimdBinOpNode(GT_SUB, type, op2, op1, simdBaseJitType, simdSize); + } } case GT_NOT: @@ -24175,14 +24604,40 @@ GenTree* Compiler::gtNewSimdUnOpNode( if (simdSize == 64) { assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F)); + + if (genTypeSize(simdBaseType) >= 4) + { + intrinsic = NI_AVX512F_TernaryLogic; + } } - else if (simdSize == 32) + else { - assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); + if (simdSize == 32) + { + assert(compIsaSupportedDebugOnly(InstructionSet_AVX)); + } + + if ((genTypeSize(simdBaseType) >= 4) && compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) + { + intrinsic = NI_AVX512F_VL_TernaryLogic; + } } - op2 = gtNewAllBitsSetConNode(type); - return gtNewSimdBinOpNode(GT_XOR, type, op1, op2, simdBaseJitType, simdSize); + if (intrinsic != NI_Illegal) + { + // AVX512 allows performing `not` without requiring a memory access + assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + + op2 = gtNewZeroConNode(type); + op3 = gtNewZeroConNode(type); + + return gtNewSimdTernaryLogicNode(type, op3, op2, op1, gtNewIconNode(~0xAA), simdBaseJitType, simdSize); + } + else + { + op2 = gtNewAllBitsSetConNode(type); + return gtNewSimdBinOpNode(GT_XOR, type, op1, op2, simdBaseJitType, simdSize); + } } #elif defined(TARGET_ARM64) case GT_NEG: diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 920e6bb9846db..fde78c3fddf58 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -40,6 +40,274 @@ const HWIntrinsicInfo& HWIntrinsicInfo::lookup(NamedIntrinsic id) return hwIntrinsicInfoArray[id - NI_HW_INTRINSIC_START - 1]; } +#if defined(TARGET_XARCH) +const TernaryLogicInfo& TernaryLogicInfo::lookup(uint8_t control) +{ + // clang-format off + static const TernaryLogicInfo ternaryLogicFlags[256] = { + /* FALSE */ { TernaryLogicOperKind::False, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norABC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andCnorBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andBnorAC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norCA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norAxnorBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norAandBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norAnandBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norAxorBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andC!A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?!A:norBA */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* andB!A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?!A:norAC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* norAnorBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* !A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andAnorBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norCB */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norBxnorAC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norBandAC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norCxnorBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norCandBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?norBC:xorBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* minorABC */ { TernaryLogicOperKind::Minor, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?norBC:andBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?norBC:xnorBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?norBC:C */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?!A:!B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?norBC:B */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?!A:!C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* xorAorBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* nandAorBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norBnandAC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norBxorAC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andC!B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?!B:norBA */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?norAC:andAC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?norAC:xnorAC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?norAC:C */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?!B:!A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* andCxorBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?xorBA:norBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* andCnandBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?nandBA:norBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?!A:andAC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?!A:xnorAC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?!A:C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?nandBA:!A */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* andA!B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?!B:norBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* norBnorAC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* !B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?norAC:A */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?!B:!C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* xorBorAC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* nandBorAC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?!B:andBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?!B:xnorBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?!B:C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?nandBA:!B */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* xorBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?xorBA:nandBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?!B:orBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norCnandBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* norCxorBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?norBA:andBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* C?norBA:xnorBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* andB!C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?!C:norAC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?norBA:B */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?!C:!A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* andBxorAC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?xorAC:norAC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?!A:andBA */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?xorAC:!A */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* andBnandAC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?nandAC:norAC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?!A:B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?nandAC:!A */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* andA!C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?!C:norBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?norBA:A */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?!C:!B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* norCnorBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* !C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xorCorBA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* nandCorBA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?!C:andBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?!C:xnorBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* xorCA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?xorAC:nandAC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?!C:B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?nandAC:!C */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?!C:orBC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandCA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andAxorBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?xorBC:norBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?!B:andBA */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?xorBC:!B */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?!C:andAC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?xorBC:!C */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* xorCB */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?xorBC:nandBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?xorBC:andBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* xnorABC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xorCandBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?nandBA:xnorBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* xorBandAC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?nandAC:xnorAC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?nandAC:C */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* nandAxnorBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andAnandBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?nandBC:norBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?!B:A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?nandBC:!B */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?!C:A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?nandBC:!C */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?!C:orAC */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* nandCB */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xorAandBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?nandBC:xnorBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?nandBC:C */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandBxnorAC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?nandBC:B */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandCxnorBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?nandBC:orBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandABC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andABC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?andBC:norBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* andCxnorBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?andBC:!B */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* andBxnorAC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?andBC:!C */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?andBC:xorBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* xnorAandBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andCB */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?C:norAC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?andBC:C */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?C:!A */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?andBC:B */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?B:!A */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?andBC:orBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandAnandBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andAxnorBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?andAC:!C */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?andAC:xorAC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* xnorBandAC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?andBA:xorBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* xnorCandBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xorABC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?xnorBC:nandBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?xnorBC:andBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* xnorCB */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?xnorBC:C */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?C:nandAC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?xnorBC:B */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?B:nandBA */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?xnorBC:orBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* nandAxorBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andCA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?C:norBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?andAC:C */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?C:!B */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?xnorAC:andAC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* xnorCA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?C:xorBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?C:nandBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* andCorAB */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xnorCorBA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C */ { TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orCnorBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?C:B */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?orBA:!A */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?C:orBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* orC!A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?andAC:A */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?A:!B */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?andAC:orAC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* nandBnandAC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?xnorAC:A */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?A:nandBA */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?xnorAC:orAC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* nandBxorAC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?C:A */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?orBA:!B */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?C:orAC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* orC!B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?orBA:xorBA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* C?orBA:nandBA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* orCxorBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orCnandBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?B:norBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?xnorBA:andBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* xnorBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?andBA:B */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?B:!C */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?B:xorBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?B:nandBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* andBorAC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::And, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xnorBorAC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?B:C */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* B?orAC:!A */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B */ { TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orBnorAC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?B:orBC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* orB!A */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::A, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?andBA:A */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?A:!C */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?A:xorAC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?A:nandAC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?andBA:orBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* nandCnandBA */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?xnorBA:orBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* nandCxorBA */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?B:A */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* B?orAC:!C */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?orAC:xorAC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* B?orAC:nandAC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* C?B:orBA */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* orB!C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orBxorAC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orBnandAC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* andAorBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::And, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* xnorAorBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?A:C */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Select, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* A?orBC:!B */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* C?A:B */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Select, TernaryLogicUseFlags::B, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* A?orBC:!C */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?orBC:xorBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* A?orBC:nandBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* majorABC */ { TernaryLogicOperKind::Major, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A?orBC:xnorBC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A }, + /* orCandBA */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orCxnorBA */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Or, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orBandAC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orBxnorAC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orCB */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::BC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* nandAnorBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* A */ { TernaryLogicOperKind::Select, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orAnorBC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* B?A:orAC */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::B }, + /* orA!B */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::B, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* C?A:orBA */ { TernaryLogicOperKind::Cond, TernaryLogicUseFlags::A, TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Cond, TernaryLogicUseFlags::C }, + /* orA!C */ { TernaryLogicOperKind::Not, TernaryLogicUseFlags::C, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orAxorBC */ { TernaryLogicOperKind::Xor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orAnandBC */ { TernaryLogicOperKind::Nand, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orAandBC */ { TernaryLogicOperKind::And, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orAxnorBC */ { TernaryLogicOperKind::Xnor, TernaryLogicUseFlags::BC, TernaryLogicOperKind::Or, TernaryLogicUseFlags::A, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orCA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* nandBnorAC */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AC, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::B, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orBA */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::AB, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* nandCnorBA */ { TernaryLogicOperKind::Nor, TernaryLogicUseFlags::AB, TernaryLogicOperKind::Nand, TernaryLogicUseFlags::C, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* orABC */ { TernaryLogicOperKind::Or, TernaryLogicUseFlags::ABC, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + /* TRUE */ { TernaryLogicOperKind::True, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, + }; + // clang-format on + + return ternaryLogicFlags[control]; +} +#endif // TARGET_XARCH + //------------------------------------------------------------------------ // getBaseJitTypeFromArgIfNeeded: Get simdBaseJitType of intrinsic from 1st or 2nd argument depending on the flag // diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 341bc02b50825..34b06028c5d10 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -316,6 +316,106 @@ enum class FloatRoundingMode : unsigned char // _MM_FROUND_NO_EXC NoException = 0x08, }; + +enum class TernaryLogicUseFlags : uint8_t +{ + // Indicates no flags are present + None = 0, + + // Indicates the ternary logic uses A + A = 1 << 0, + + // Indicates the ternary logic uses B + B = 1 << 1, + + // Indicates the ternary logic uses C + C = 1 << 2, + + // Indicates the ternary logic uses A and B + AB = (A | B), + + // Indicates the ternary logic uses A and C + AC = (A | C), + + // Indicates the ternary logic uses B and C + BC = (B | C), + + // Indicates the ternary logic uses A, B, and C + ABC = (A | B | C), +}; + +enum class TernaryLogicOperKind : uint8_t +{ + // Indicates no operation is done + None = 0, + + // value + Select = 1, + + // constant true (1) + True = 2, + + // constant false (0) + False = 3, + + // ~value + Not = 4, + + // left & right + And = 5, + + // ~(left & right) + Nand = 6, + + // left | right + Or = 7, + + // ~(left | right) + Nor = 8, + + // left ^ right + Xor = 9, + + // ~(left ^ right) + Xnor = 10, + + // cond ? left : right + Cond = 11, + + // returns 0 if two+ of the three input bits are 0; else 1 + Major = 12, + + // returns 0 if two+ of the three input bits are 1; else 0 + Minor = 13, +}; + +struct TernaryLogicInfo +{ + // We have 256 entries, so we compress as much as possible + // This gives us 3-bytes per entry (21-bits) + + TernaryLogicOperKind oper1 : 4; + TernaryLogicUseFlags oper1Use : 3; + + TernaryLogicOperKind oper2 : 4; + TernaryLogicUseFlags oper2Use : 3; + + TernaryLogicOperKind oper3 : 4; + TernaryLogicUseFlags oper3Use : 3; + + static const TernaryLogicInfo& lookup(uint8_t control); + + TernaryLogicUseFlags GetAllUseFlags() const + { + uint8_t useFlagsBits = 0; + + useFlagsBits |= static_cast(oper1Use); + useFlagsBits |= static_cast(oper2Use); + useFlagsBits |= static_cast(oper3Use); + + return static_cast(useFlagsBits); + } +}; #endif // TARGET_XARCH struct HWIntrinsicInfo diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index 69a581c912dee..1b9302d41ba79 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -921,6 +921,27 @@ void CodeGen::genHWIntrinsic_R_R_R_RM_I(GenTreeHWIntrinsic* node, instruction in assert(!node->isRMWHWIntrinsic(compiler)); op1Reg = targetReg; + + if (op2->isContained()) + { + // op2 is never selected by the table so + // we can contain and ignore any register + // allocated to it resulting in better + // non-RMW based codegen. + +#if defined(DEBUG) + NamedIntrinsic intrinsicId = node->GetHWIntrinsicId(); + assert((intrinsicId == NI_AVX512F_TernaryLogic) || (intrinsicId == NI_AVX512F_VL_TernaryLogic)); + + uint8_t control = static_cast(ival); + const TernaryLogicInfo& info = TernaryLogicInfo::lookup(control); + TernaryLogicUseFlags useFlags = info.GetAllUseFlags(); + + assert(useFlags == TernaryLogicUseFlags::C); +#endif // DEBUG + + op2Reg = targetReg; + } } assert(targetReg != REG_NA); diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index 93a3d9612a1be..75a6cb80135b2 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -870,8 +870,8 @@ HARDWARE_INTRINSIC(AVX512F, DuplicateEvenIndexed, HARDWARE_INTRINSIC(AVX512F, DuplicateOddIndexed, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movshdup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX512F, ExtractVector128, 64, 2, {INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextracti128, INS_vextractf128, INS_vextractf128}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, ExtractVector256, 64, 2, {INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextracti64x4, INS_vextractf64x4, INS_vextractf64x4}, HW_Category_IMM, HW_Flag_FullRangeIMM) -HARDWARE_INTRINSIC(AVX512F, Fixup, 64, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmps, INS_vfixupimmpd}, HW_Category_IMM, HW_Flag_FullRangeIMM) -HARDWARE_INTRINSIC(AVX512F, FixupScalar, 16, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmss, INS_vfixupimmsd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) +HARDWARE_INTRINSIC(AVX512F, Fixup, 64, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmps, INS_vfixupimmpd}, HW_Category_IMM, HW_Flag_SpecialImport|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, FixupScalar, 16, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmss, INS_vfixupimmsd}, HW_Category_IMM, HW_Flag_SpecialImport|HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) HARDWARE_INTRINSIC(AVX512F, FusedMultiplyAdd, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfmadd213ps, INS_vfmadd213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512F, FusedMultiplyAddNegated, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfnmadd213ps, INS_vfnmadd213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX512F, FusedMultiplyAddSubtract, 64, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfmaddsub213ps, INS_vfmaddsub213pd}, HW_Category_SimpleSIMD, HW_Flag_SpecialCodeGen) @@ -924,6 +924,7 @@ HARDWARE_INTRINSIC(AVX512F, StoreAligned, HARDWARE_INTRINSIC(AVX512F, StoreAlignedNonTemporal, 64, 2, {INS_movntdq, INS_movntdq, INS_movntdq, INS_movntdq, INS_movntdq, INS_movntdq, INS_movntdq, INS_movntdq, INS_movntps, INS_movntpd}, HW_Category_MemoryStore, HW_Flag_NoRMWSemantics|HW_Flag_BaseTypeFromSecondArg) HARDWARE_INTRINSIC(AVX512F, Subtract, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_psubd, INS_psubd, INS_psubq, INS_psubq, INS_subps, INS_subpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, UnpackHigh, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_punpckhdq, INS_punpckhdq, INS_punpckhqdq, INS_punpckhqdq, INS_unpckhps, INS_unpckhpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F, TernaryLogic, 64, 4, {INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogq, INS_vpternlogq, INS_vpternlogd, INS_vpternlogq}, HW_Category_IMM, HW_Flag_SpecialImport|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, UnpackLow, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_punpckldq, INS_punpckldq, INS_punpcklqdq, INS_punpcklqdq, INS_unpcklps, INS_unpcklpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, Xor, 64, 2, {INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_vpxorq, INS_vpxorq, INS_xorps, INS_xorpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative) @@ -956,7 +957,7 @@ HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256Double, HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256Single, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtudq2ps, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256UInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvtps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(AVX512F_VL, ConvertToVector256UInt32WithTruncation, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vcvttps2udq, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(AVX512F_VL, Fixup, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmps, INS_vfixupimmpd}, HW_Category_IMM, HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, Fixup, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vfixupimmps, INS_vfixupimmpd}, HW_Category_IMM, HW_Flag_SpecialImport|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, GetExponent, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetexpps, INS_vgetexppd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, GetMantissa, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vgetmantps, INS_vgetmantpd}, HW_Category_IMM, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, PermuteVar4x64, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermq_reg, INS_vpermq_reg, INS_invalid, INS_vpermpd_reg}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) @@ -970,6 +971,7 @@ HARDWARE_INTRINSIC(AVX512F_VL, RoundScale, HARDWARE_INTRINSIC(AVX512F_VL, Scale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, ShiftRightArithmetic, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsraq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, ShiftRightArithmeticVariable, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpsravq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX512F_VL, TernaryLogic, -1, 4, {INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogd, INS_vpternlogq, INS_vpternlogq, INS_vpternlogd, INS_vpternlogq}, HW_Category_IMM, HW_Flag_SpecialImport|HW_Flag_FullRangeIMM) // *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** // ISA Function name SIMD size NumArg Instructions Category Flags diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 2ef279948d2d7..7d7a774da2bcb 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -2962,6 +2962,43 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_AVX512F_Fixup: + case NI_AVX512F_FixupScalar: + case NI_AVX512F_VL_Fixup: + { + assert(sig->numArgs == 4); + + op4 = impPopStack().val; + op3 = impSIMDPopStack(); + op2 = impSIMDPopStack(); + op1 = impSIMDPopStack(); + + retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, op4, intrinsic, simdBaseJitType, simdSize); + + if (!retNode->isRMWHWIntrinsic(this)) + { + if (!op1->IsVectorZero()) + { + retNode->AsHWIntrinsic()->Op(1) = gtNewZeroConNode(retType); + } + } + break; + } + + case NI_AVX512F_TernaryLogic: + case NI_AVX512F_VL_TernaryLogic: + { + assert(sig->numArgs == 4); + + op4 = impPopStack().val; + op3 = impSIMDPopStack(); + op2 = impSIMDPopStack(); + op1 = impSIMDPopStack(); + + retNode = gtNewSimdTernaryLogicNode(retType, op1, op2, op3, op4, simdBaseJitType, simdSize); + break; + } + case NI_AVX2_GatherMaskVector128: case NI_AVX2_GatherMaskVector256: { diff --git a/src/coreclr/jit/importervectorization.cpp b/src/coreclr/jit/importervectorization.cpp index c751c7b4d3ee5..b1d1a3700b75a 100644 --- a/src/coreclr/jit/importervectorization.cpp +++ b/src/coreclr/jit/importervectorization.cpp @@ -147,20 +147,55 @@ GenTree* Compiler::impExpandHalfConstEqualsSIMD( GenTree* vec1 = gtNewIndir(simdType, gtNewOperNode(GT_ADD, TYP_BYREF, data, offset1)); GenTree* vec2 = gtNewIndir(simdType, gtNewOperNode(GT_ADD, TYP_BYREF, gtClone(data), offset2)); + GenTree* xor1; + GenTree* orr; + if (cmpMode == OrdinalIgnoreCase) { // Apply ASCII-only ToLowerCase mask (bitwise OR 0x20 for all a-Z chars) GenTreeVecCon* toLowerVec1 = gtNewVconNode(simdType, toLowerMask); GenTreeVecCon* toLowerVec2 = gtNewVconNode(simdType, (BYTE*)toLowerMask + byteLen - simdSize); - vec1 = gtNewSimdBinOpNode(GT_OR, simdType, vec1, toLowerVec1, baseType, simdSize); +#if defined(TARGET_XARCH) + if (compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) + { + GenTree* control; + + control = gtNewIconNode(static_cast((0xF0 | 0xCC) ^ 0xAA)); // (A | B)) ^ C + xor1 = gtNewSimdTernaryLogicNode(simdType, vec1, toLowerVec1, cnsVec1, control, baseType, simdSize); + } + else +#endif // TARGET_XARCH + { + vec1 = gtNewSimdBinOpNode(GT_OR, simdType, vec1, toLowerVec1, baseType, simdSize); + xor1 = gtNewSimdBinOpNode(GT_XOR, simdType, vec1, cnsVec1, baseType, simdSize); + } + vec2 = gtNewSimdBinOpNode(GT_OR, simdType, vec2, toLowerVec2, baseType, simdSize); } + else + { + xor1 = gtNewSimdBinOpNode(GT_XOR, simdType, vec1, cnsVec1, baseType, simdSize); + } // ((v1 ^ cns1) | (v2 ^ cns2)) == zero - GenTree* xor1 = gtNewSimdBinOpNode(GT_XOR, simdType, vec1, cnsVec1, baseType, simdSize); - GenTree* xor2 = gtNewSimdBinOpNode(GT_XOR, simdType, vec2, cnsVec2, baseType, simdSize); - GenTree* orr = gtNewSimdBinOpNode(GT_OR, simdType, xor1, xor2, baseType, simdSize); + +#if defined(TARGET_XARCH) + if (compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) + { + GenTree* control; + + control = gtNewIconNode(static_cast(0xF0 | (0xCC ^ 0xAA))); // A | (B ^ C) + orr = gtNewSimdTernaryLogicNode(simdType, xor1, vec2, cnsVec2, control, baseType, simdSize); + } + else +#endif // TARGET_XARCH + { + GenTree* xor2; + + xor2 = gtNewSimdBinOpNode(GT_XOR, simdType, vec2, cnsVec2, baseType, simdSize); + orr = gtNewSimdBinOpNode(GT_OR, simdType, xor1, xor2, baseType, simdSize); + } // Optimization: use a single load when byteLen equals simdSize. // For code simplicity we always create nodes for two vectors case. diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index bb8a75bc77cc7..15006d779ea09 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -694,7 +694,8 @@ INST3(vprorvd, "prorvd", IUM_WR, BAD_CODE, BAD_ INST3(vprorvq, "prorvq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x14), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bit rotate right INST3(vpsraq, "psraq", IUM_WR, BAD_CODE, PCKDBL(0x72), PCKDBL(0xE2), INS_TT_FULL | INS_TT_MEM128, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed shift right arithmetic of 64-bit integers INST3(vpsravq, "psravq", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0x46), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Variable Bit Shift Right Arithmetic -INST3(vpternlogd, "pternlogd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x25), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) +INST3(vpternlogd, "pternlogd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x25), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bitwise Ternary Logic +INST3(vpternlogq, "pternlogq", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x25), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Bitwise Ternary Logic INST3(vpxorq, "pxorq", IUM_WR, BAD_CODE, BAD_CODE, PCKDBL(0xEF), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Packed bit-wise XOR of two xmm regs INST3(vrangepd, "rangepd", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x50), INS_TT_FULL, Input_64Bit | REX_W1 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Range restriction calculation from a pair of packed double-precision floating-point values INST3(vrangeps, "rangeps", IUM_WR, BAD_CODE, BAD_CODE, SSE3A(0x50), INS_TT_FULL, Input_32Bit | REX_W0 | Encoding_EVEX | INS_Flags_IsDstDstSrcAVXInstruction) // Range restriction calculation from a pair of packed single-precision floating-point values diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 1b1d125c3c35d..f4c365591eaf1 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -1954,6 +1954,8 @@ GenTree* Lowering::LowerHWIntrinsicCmpOpWithKReg(GenTreeHWIntrinsic* node) // GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* node) { + assert(!comp->compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL)); + var_types simdType = node->gtType; CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); var_types simdBaseType = node->GetSimdBaseType(); @@ -6985,6 +6987,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX512F_ShiftRightArithmetic: case NI_AVX512F_ShiftRightLogical: case NI_AVX512F_Shuffle: + case NI_AVX512F_TernaryLogic: case NI_AVX512F_VL_AlignRight32: case NI_AVX512F_VL_AlignRight64: case NI_AVX512F_VL_Fixup: @@ -6993,6 +6996,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre case NI_AVX512F_VL_RotateRight: case NI_AVX512F_VL_RoundScale: case NI_AVX512F_VL_ShiftRightArithmetic: + case NI_AVX512F_VL_TernaryLogic: case NI_AVX512BW_AlignRight: case NI_AVX512BW_ShiftLeftLogical: case NI_AVX512BW_ShiftRightArithmetic: @@ -8399,6 +8403,52 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) break; } + + case NI_AVX512F_TernaryLogic: + case NI_AVX512F_VL_TernaryLogic: + { + if (!isContainedImm) + { + // Don't contain if we're generating a jmp table fallback + break; + } + + if (IsContainableHWIntrinsicOp(node, op3, &supportsRegOptional)) + { + MakeSrcContained(node, op3); + } + else if (supportsRegOptional) + { + MakeSrcRegOptional(node, op3); + } + + uint8_t control = static_cast(op4->AsIntCon()->gtIconVal); + const TernaryLogicInfo& info = TernaryLogicInfo::lookup(control); + TernaryLogicUseFlags useFlags = info.GetAllUseFlags(); + + if (useFlags != TernaryLogicUseFlags::ABC) + { + assert(!node->isRMWHWIntrinsic(comp)); + + // op1, and possibly op2, are never selected + // by the table so we can contain and ignore + // any register allocated to it resulting in + // better non-RMW based codegen. + + MakeSrcContained(node, op1); + + if (useFlags == TernaryLogicUseFlags::C) + { + MakeSrcContained(node, op2); + } + else + { + assert(useFlags == TernaryLogicUseFlags::BC); + } + } + break; + } + default: { assert(!"Unhandled containment for quaternary hardware intrinsic with immediate operand"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs index d9d4db644610f..e60c9236826c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.PlatformNotSupported.cs @@ -845,6 +845,119 @@ internal VL() { } /// VPSRAVQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst /// public static Vector256 ShiftRightArithmeticVariable(Vector256 value, Vector256 count) { throw new PlatformNotSupportedException(); } + + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, byte imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, byte imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, short imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, short imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_epi32 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_epi32 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_epi64 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128i _mm_ternarylogic_epi64 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128 _mm_ternarylogic_ps (__m128 a, __m128 b, __m128 c, int imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m128d _mm_ternarylogic_pd (__m128d a, __m128d b, __m128d c, int imm) + /// VPTERNLOGQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, byte imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, byte imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, short imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, short imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_epi32 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_epi32 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_epi64 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256i _mm256_ternarylogic_epi64 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256 _mm256_ternarylogic_ps (__m256 a, __m256 b, __m256 c, int imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m256d _mm256_ternarylogic_pd (__m256d a, __m256d b, __m256d c, int imm) + /// VPTERNLOGQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } } public new abstract class X64 : Avx2.X64 @@ -2786,6 +2899,63 @@ internal X64() { } /// public static Vector512 Subtract(Vector512 left, Vector512 right) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, byte imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, short imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, short imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_epi32 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_epi32 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_epi64 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512i _mm512_ternarylogic_epi64 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512 _mm512_ternarylogic_ps (__m512 a, __m512 b, __m512 c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// + /// __m512d _mm512_ternarylogic_pd (__m512d a, __m512d b, __m512d c, int imm) + /// VPTERNLOGQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) { throw new PlatformNotSupportedException(); } + /// /// __m512i _mm512_unpackhi_epi32 (__m512i a, __m512i b) /// VPUNPCKHDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs index b730cf9279071..d01b191a3ca70 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/Avx512F.cs @@ -845,6 +845,119 @@ internal VL() { } /// VPSRAVQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst /// public static Vector256 ShiftRightArithmeticVariable(Vector256 value, Vector256 count) => ShiftRightArithmeticVariable(value, count); + + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, byte imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, byte imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, short imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_si128 (__m128i a, __m128i b, __m128i c, short imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_epi32 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_epi32 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_epi64 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128i _mm_ternarylogic_epi64 (__m128i a, __m128i b, __m128i c, int imm) + /// VPTERNLOGQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128 _mm_ternarylogic_ps (__m128 a, __m128 b, __m128 c, int imm) + /// VPTERNLOGD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m128d _mm_ternarylogic_pd (__m128d a, __m128d b, __m128d c, int imm) + /// VPTERNLOGQ xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector128 TernaryLogic(Vector128 a, Vector128 b, Vector128 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, byte imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, byte imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, short imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_si256 (__m256i a, __m256i b, __m256i c, short imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_epi32 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_epi32 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_epi64 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256i _mm256_ternarylogic_epi64 (__m256i a, __m256i b, __m256i c, int imm) + /// VPTERNLOGQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256 _mm256_ternarylogic_ps (__m256 a, __m256 b, __m256 c, int imm) + /// VPTERNLOGD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m256d _mm256_ternarylogic_pd (__m256d a, __m256d b, __m256d c, int imm) + /// VPTERNLOGQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector256 TernaryLogic(Vector256 a, Vector256 b, Vector256 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); } [Intrinsic] @@ -2786,6 +2899,63 @@ internal X64() { } /// public static Vector512 Subtract(Vector512 left, Vector512 right) => Subtract(left, right); + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, byte imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, short imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_si512 (__m512i a, __m512i b, __m512i c, short imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_epi32 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_epi32 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_epi64 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512i _mm512_ternarylogic_epi64 (__m512i a, __m512i b, __m512i c, int imm) + /// VPTERNLOGQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512 _mm512_ternarylogic_ps (__m512 a, __m512 b, __m512 c, int imm) + /// VPTERNLOGD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// + /// __m512d _mm512_ternarylogic_pd (__m512d a, __m512d b, __m512d c, int imm) + /// VPTERNLOGQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 + /// The above native signature does not exist. We provide this additional overload for consistency with the other bitwise APIs. + /// + public static Vector512 TernaryLogic(Vector512 a, Vector512 b, Vector512 c, [ConstantExpected] byte control) => TernaryLogic(a, b, c, control); + /// /// __m512i _mm512_unpackhi_epi32 (__m512i a, __m512i b) /// VPUNPCKHDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 553d1a5713bde..0c7fe6c1b6768 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -5058,6 +5058,16 @@ public unsafe static void StoreAlignedNonTemporal(ulong* address, System.Runtime public static System.Runtime.Intrinsics.Vector512 Subtract(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Subtract(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 Subtract(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector512 TernaryLogic(System.Runtime.Intrinsics.Vector512 a, System.Runtime.Intrinsics.Vector512 b, System.Runtime.Intrinsics.Vector512 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } public static System.Runtime.Intrinsics.Vector512 UnpackHigh(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 UnpackHigh(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } public static System.Runtime.Intrinsics.Vector512 UnpackHigh(System.Runtime.Intrinsics.Vector512 left, System.Runtime.Intrinsics.Vector512 right) { throw null; } @@ -5241,6 +5251,26 @@ internal VL() { } public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmetic(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } public static System.Runtime.Intrinsics.Vector128 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector128 value, System.Runtime.Intrinsics.Vector128 count) { throw null; } public static System.Runtime.Intrinsics.Vector256 ShiftRightArithmeticVariable(System.Runtime.Intrinsics.Vector256 value, System.Runtime.Intrinsics.Vector256 count) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector128 TernaryLogic(System.Runtime.Intrinsics.Vector128 a, System.Runtime.Intrinsics.Vector128 b, System.Runtime.Intrinsics.Vector128 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } + public static System.Runtime.Intrinsics.Vector256 TernaryLogic(System.Runtime.Intrinsics.Vector256 a, System.Runtime.Intrinsics.Vector256 b, System.Runtime.Intrinsics.Vector256 c, [System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute] byte control) { throw null; } } public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Avx2.X64 { diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index 87e5fe5d3a40f..1141a42cbbf0a 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1397,6 +1397,48 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Subtract", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(left[i] - right[i]) != BitConverter.SingleToInt32Bits(result[i])"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Subtract", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(uint)(left[i] - right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Subtract", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(ulong)(left[i] - right[i]) != result[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Byte", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Double", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (BitConverter.DoubleToInt64Bits(op1[0]) ^ (BitConverter.DoubleToInt64Bits(op2[0]) | BitConverter.DoubleToInt64Bits(op3[0])))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (BitConverter.DoubleToInt64Bits(op1[i]) ^ (BitConverter.DoubleToInt64Bits(op2[i]) | BitConverter.DoubleToInt64Bits(op3[i])))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int16", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A */ ["Imm"] = "240", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op1[0]", ["ValidateRemainingResults"] = "result[i] != op1[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* B */ ["Imm"] = "204", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op2[0]", ["ValidateRemainingResults"] = "result[i] != op2[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* C */ ["Imm"] = "170", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op3[0]", ["ValidateRemainingResults"] = "result[i] != op3[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* True */ ["Imm"] = "255", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != -1", ["ValidateRemainingResults"] = "result[i] != -1"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "255", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~A */ ["Imm"] = "15", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op1[0]", ["ValidateRemainingResults"] = "result[i] != ~op1[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B */ ["Imm"] = "51", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op2[0]", ["ValidateRemainingResults"] = "result[i] != ~op2[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C */ ["Imm"] = "85", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op3[0]", ["ValidateRemainingResults"] = "result[i] != ~op3[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~A & B */ ["Imm"] = "12", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~A & C */ ["Imm"] = "10", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B & A */ ["Imm"] = "48", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B & C */ ["Imm"] = "34", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C & A */ ["Imm"] = "80", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C & B */ ["Imm"] = "68", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A & B */ ["Imm"] = "192", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A & C */ ["Imm"] = "160", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* B & C */ ["Imm"] = "136", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(A & B) */ ["Imm"] = "63", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(A & C) */ ["Imm"] = "95", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(B & C) */ ["Imm"] = "119", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A | B */ ["Imm"] = "252", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A | C */ ["Imm"] = "250", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* B | C */ ["Imm"] = "238", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(A | B) */ ["Imm"] = "3", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(A | C) */ ["Imm"] = "5", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(B | C) */ ["Imm"] = "17", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A ^ B */ ["Imm"] = "60", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A ^ C */ ["Imm"] = "90", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* B ^ C */ ["Imm"] = "102", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(A ^ B) */ ["Imm"] = "195", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] ^ op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] ^ op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(A ^ C) */ ["Imm"] = "165", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~(B ^ C) */ ["Imm"] = "153", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int64", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "SByte", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Single", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != (BitConverter.SingleToInt32Bits(op1[0]) ^ (BitConverter.SingleToInt32Bits(op2[0]) | BitConverter.SingleToInt32Bits(op3[0])))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != (BitConverter.SingleToInt32Bits(op1[i]) ^ (BitConverter.SingleToInt32Bits(op2[i]) | BitConverter.SingleToInt32Bits(op3[i])))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "UInt16", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "UInt32", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "UInt64", ["Imm"] = "30", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Xor", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "(byte)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(byte)(left[i] ^ right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Xor", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "(short)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] ^ right[i]) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "Xor", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "(int)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] ^ right[i]) != result[i]"}), @@ -1529,6 +1571,49 @@ ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(firstOp[i] >> 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "(firstOp[0] >> 63) != result[0]", ["ValidateRemainingResults"] = "(firstOp[i] >> 63) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmeticVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "(left[0] >> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >> (int)right[i]) != result[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Double", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (BitConverter.DoubleToInt64Bits(op1[0]) ^ (BitConverter.DoubleToInt64Bits(op2[0]) | BitConverter.DoubleToInt64Bits(op3[0])))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (BitConverter.DoubleToInt64Bits(op1[i]) ^ (BitConverter.DoubleToInt64Bits(op2[i]) | BitConverter.DoubleToInt64Bits(op3[i])))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int16", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A */ ["Imm"] = "240", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op1[0]", ["ValidateRemainingResults"] = "result[i] != op1[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* B */ ["Imm"] = "204", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op2[0]", ["ValidateRemainingResults"] = "result[i] != op2[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* C */ ["Imm"] = "170", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op3[0]", ["ValidateRemainingResults"] = "result[i] != op3[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* True */ ["Imm"] = "255", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != -1", ["ValidateRemainingResults"] = "result[i] != -1"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "255", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~A */ ["Imm"] = "15", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op1[0]", ["ValidateRemainingResults"] = "result[i] != ~op1[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B */ ["Imm"] = "51", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op2[0]", ["ValidateRemainingResults"] = "result[i] != ~op2[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C */ ["Imm"] = "85", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op3[0]", ["ValidateRemainingResults"] = "result[i] != ~op3[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~A & B */ ["Imm"] = "12", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~A & C */ ["Imm"] = "10", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B & A */ ["Imm"] = "48", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B & C */ ["Imm"] = "34", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C & A */ ["Imm"] = "80", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C & B */ ["Imm"] = "68", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A & B */ ["Imm"] = "192", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A & C */ ["Imm"] = "160", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* B & C */ ["Imm"] = "136", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(A & B) */ ["Imm"] = "63", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(A & C) */ ["Imm"] = "95", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(B & C) */ ["Imm"] = "119", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A | B */ ["Imm"] = "252", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A | C */ ["Imm"] = "250", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* B | C */ ["Imm"] = "238", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(A | B) */ ["Imm"] = "3", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(A | C) */ ["Imm"] = "5", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(B | C) */ ["Imm"] = "17", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A ^ B */ ["Imm"] = "60", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A ^ C */ ["Imm"] = "90", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* B ^ C */ ["Imm"] = "102", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(A ^ B) */ ["Imm"] = "195", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] ^ op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] ^ op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(A ^ C) */ ["Imm"] = "165", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~(B ^ C) */ ["Imm"] = "153", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int64", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Single", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != (BitConverter.SingleToInt32Bits(op1[0]) ^ (BitConverter.SingleToInt32Bits(op2[0]) | BitConverter.SingleToInt32Bits(op3[0])))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != (BitConverter.SingleToInt32Bits(op1[i]) ^ (BitConverter.SingleToInt32Bits(op2[i]) | BitConverter.SingleToInt32Bits(op3[i])))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + }; (string templateFileName, Dictionary templateData)[] Avx512F_VL_Vector256Inputs = new [] @@ -1634,6 +1719,48 @@ ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(firstOp[i] >> 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "(firstOp[0] >> 63) != result[0]", ["ValidateRemainingResults"] = "(firstOp[i] >> 63) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ShiftRightArithmeticVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "(left[0] >> (int)right[0]) != result[0]", ["ValidateRemainingResults"] = "(left[i] >> (int)right[i]) != result[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Byte", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Double", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp3"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (BitConverter.DoubleToInt64Bits(op1[0]) ^ (BitConverter.DoubleToInt64Bits(op2[0]) | BitConverter.DoubleToInt64Bits(op3[0])))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (BitConverter.DoubleToInt64Bits(op1[i]) ^ (BitConverter.DoubleToInt64Bits(op2[i]) | BitConverter.DoubleToInt64Bits(op3[i])))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int16", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A */ ["Imm"] = "240", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op1[0]", ["ValidateRemainingResults"] = "result[i] != op1[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* B */ ["Imm"] = "204", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op2[0]", ["ValidateRemainingResults"] = "result[i] != op2[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* C */ ["Imm"] = "170", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op3[0]", ["ValidateRemainingResults"] = "result[i] != op3[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* True */ ["Imm"] = "255", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != -1", ["ValidateRemainingResults"] = "result[i] != -1"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "255", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~A */ ["Imm"] = "15", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op1[0]", ["ValidateRemainingResults"] = "result[i] != ~op1[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B */ ["Imm"] = "51", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op2[0]", ["ValidateRemainingResults"] = "result[i] != ~op2[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C */ ["Imm"] = "85", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op3[0]", ["ValidateRemainingResults"] = "result[i] != ~op3[i]"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~A & B */ ["Imm"] = "12", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~A & C */ ["Imm"] = "10", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B & A */ ["Imm"] = "48", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B & C */ ["Imm"] = "34", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C & A */ ["Imm"] = "80", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C & B */ ["Imm"] = "68", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A & B */ ["Imm"] = "192", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A & C */ ["Imm"] = "160", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* B & C */ ["Imm"] = "136", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(A & B) */ ["Imm"] = "63", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(A & C) */ ["Imm"] = "95", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(B & C) */ ["Imm"] = "119", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] & op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A | B */ ["Imm"] = "252", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A | C */ ["Imm"] = "250", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* B | C */ ["Imm"] = "238", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(A | B) */ ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(A | C) */ ["Imm"] = "5", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(B | C) */ ["Imm"] = "17", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A ^ B */ ["Imm"] = "60", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A ^ C */ ["Imm"] = "90", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* B ^ C */ ["Imm"] = "102", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(A ^ B) */ ["Imm"] = "195", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] ^ op2[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] ^ op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(A ^ C) */ ["Imm"] = "165", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op1[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op1[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~(B ^ C) */ ["Imm"] = "153", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~(op2[0] ^ op3[0])", ["ValidateRemainingResults"] = "result[i] != ~(op2[i] ^ op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int64", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "SByte", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Single", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp3"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != (BitConverter.SingleToInt32Bits(op1[0]) ^ (BitConverter.SingleToInt32Bits(op2[0]) | BitConverter.SingleToInt32Bits(op3[0])))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != (BitConverter.SingleToInt32Bits(op1[i]) ^ (BitConverter.SingleToInt32Bits(op2[i]) | BitConverter.SingleToInt32Bits(op3[i])))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "UInt16", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "UInt32", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "UInt64", ["Imm"] = "30", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), }; (string templateFileName, Dictionary templateData)[] Avx512F_X64Inputs = new [] From 6e72be6069b678ef06af9dc4561976ab4297eb0c Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 5 May 2023 11:47:56 -0700 Subject: [PATCH 05/21] Apply formatting patch --- src/coreclr/jit/hwintrinsiccodegenxarch.cpp | 8 ++++---- src/coreclr/jit/importervectorization.cpp | 2 +- src/coreclr/jit/lowerxarch.cpp | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index 1b9302d41ba79..6d4a1346f7d65 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -924,10 +924,10 @@ void CodeGen::genHWIntrinsic_R_R_R_RM_I(GenTreeHWIntrinsic* node, instruction in if (op2->isContained()) { - // op2 is never selected by the table so - // we can contain and ignore any register - // allocated to it resulting in better - // non-RMW based codegen. +// op2 is never selected by the table so +// we can contain and ignore any register +// allocated to it resulting in better +// non-RMW based codegen. #if defined(DEBUG) NamedIntrinsic intrinsicId = node->GetHWIntrinsicId(); diff --git a/src/coreclr/jit/importervectorization.cpp b/src/coreclr/jit/importervectorization.cpp index b1d1a3700b75a..a382e025d4bc8 100644 --- a/src/coreclr/jit/importervectorization.cpp +++ b/src/coreclr/jit/importervectorization.cpp @@ -178,7 +178,7 @@ GenTree* Compiler::impExpandHalfConstEqualsSIMD( xor1 = gtNewSimdBinOpNode(GT_XOR, simdType, vec1, cnsVec1, baseType, simdSize); } - // ((v1 ^ cns1) | (v2 ^ cns2)) == zero +// ((v1 ^ cns1) | (v2 ^ cns2)) == zero #if defined(TARGET_XARCH) if (compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL)) diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index f4c365591eaf1..1c97544ffca47 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -8403,7 +8403,6 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node) break; } - case NI_AVX512F_TernaryLogic: case NI_AVX512F_VL_TernaryLogic: { From ea83d7be024f8b6b0343088cc61ba050aefa6742 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 5 May 2023 13:56:21 -0700 Subject: [PATCH 06/21] Ensure side effects are preserved when optimizing certain intrinsic imports --- src/coreclr/jit/gentree.cpp | 178 ++++++++++++++++-- src/coreclr/jit/hwintrinsicxarch.cpp | 13 +- .../GenerateHWIntrinsicTests_X86.cs | 19 +- 3 files changed, 193 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 52c073bc8ea02..5658f717c2018 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -24322,6 +24322,20 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(0xCC)) || // B (control == static_cast(0xAA))); // C + assert(op1 != value1); + assert(op2 != value1); + assert(op3 == value1); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + + if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op2, value1); + } + return value1; } @@ -24337,6 +24351,21 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, assert(control == static_cast(0xFF)); + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + + if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op2, value1); + } + + if ((op3->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op3, value1); + } + return gtNewAllBitsSetConNode(type); } @@ -24352,6 +24381,21 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, assert(control == static_cast(0x00)); + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + + if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op2, value1); + } + + if ((op3->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op3, value1); + } + return gtNewZeroConNode(type); } @@ -24369,21 +24413,39 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(~0xCC)) || // ~B (control == static_cast(~0xAA))); // ~C + assert(op1 != value1); + assert(op2 != value1); + assert(op3 == value1); + if (!op1->IsVectorZero()) { - assert(op1 != value1); - op1 = gtNewZeroConNode(type); + GenTree* zero = gtNewZeroConNode(type); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op1 = gtNewOperNode(GT_COMMA, type, op1, zero); + } + else + { + op1 = zero; + } } if (!op2->IsVectorZero()) { - assert(op2 != value1); - op2 = gtNewZeroConNode(type); + GenTree* zero = gtNewZeroConNode(type); + + if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op2 = gtNewOperNode(GT_COMMA, type, op2, zero); + } + else + { + op2 = zero; + } } - assert(value1 == op3); op4->AsIntCon()->gtIconVal = static_cast(~0xAA); - break; } @@ -24399,11 +24461,43 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(~0xAA & 0xF0)) || // ~C & A (control == static_cast(~0xAA & 0xCC))); // ~C & B + assert(op1 != value1); + assert(op1 != value2); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + return gtNewSimdBinOpNode(GT_AND_NOT, type, value2, value1, simdBaseJitType, simdSize); } else { assert(info.oper2 == TernaryLogicOperKind::Or); + + assert((control == static_cast(~0xF0 | 0xCC)) || // ~A | B + (control == static_cast(~0xF0 | 0xAA)) || // ~A | C + (control == static_cast(~0xCC | 0xF0)) || // ~B | A + (control == static_cast(~0xCC | 0xAA)) || // ~B | C + (control == static_cast(~0xAA | 0xF0)) || // ~C | A + (control == static_cast(~0xAA | 0xCC))); // ~C | B + + assert(op1 != value1); + assert(op1 != value2); + + if (!op1->IsVectorZero()) + { + GenTree* zero = gtNewZeroConNode(type); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op1 = gtNewOperNode(GT_COMMA, type, op1, zero); + } + else + { + op1 = zero; + } + } } break; } @@ -24421,6 +24515,14 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(0xF0 & 0xAA)) || // A & C (control == static_cast(0xCC & 0xAA))); // B & C + assert(op1 != value1); + assert(op1 != value2); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + return gtNewSimdBinOpNode(GT_AND, type, value1, value2, simdBaseJitType, simdSize); } @@ -24437,11 +24539,21 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(~(0xF0 & 0xAA))) || // ~(A & C) (control == static_cast(~(0xCC & 0xAA)))); // ~(B & C) + assert(op1 != value1); + assert(op1 != value2); + if (!op1->IsVectorZero()) { - assert(op1 != value1); - assert(op1 != value2); - op1 = gtNewZeroConNode(type); + GenTree* zero = gtNewZeroConNode(type); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op1 = gtNewOperNode(GT_COMMA, type, op1, zero); + } + else + { + op1 = zero; + } } op4->AsIntCon()->gtIconVal = static_cast(~(0xCC & 0xAA)); @@ -24461,6 +24573,14 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(0xF0 | 0xAA)) || // A | C (control == static_cast(0xCC | 0xAA))); // B | C + assert(op1 != value1); + assert(op1 != value2); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + return gtNewSimdBinOpNode(GT_OR, type, value1, value2, simdBaseJitType, simdSize); } @@ -24477,11 +24597,21 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(~(0xF0 | 0xAA))) || // ~(A | C) (control == static_cast(~(0xCC | 0xAA)))); // ~(B | C) + assert(op1 != value1); + assert(op1 != value2); + if (!op1->IsVectorZero()) { - assert(op1 != value1); - assert(op1 != value2); - op1 = gtNewZeroConNode(type); + GenTree* zero = gtNewZeroConNode(type); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op1 = gtNewOperNode(GT_COMMA, type, op1, zero); + } + else + { + op1 = zero; + } } op4->AsIntCon()->gtIconVal = static_cast(~(0xCC | 0xAA)); @@ -24501,6 +24631,14 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(0xF0 ^ 0xAA)) || // A ^ C (control == static_cast(0xCC ^ 0xAA))); // B ^ C + assert(op1 != value1); + assert(op1 != value2); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + value1 = gtNewOperNode(GT_COMMA, type, op1, value1); + } + return gtNewSimdBinOpNode(GT_XOR, type, value1, value2, simdBaseJitType, simdSize); } @@ -24517,11 +24655,21 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, (control == static_cast(~(0xF0 ^ 0xAA))) || // ~(A ^ C) (control == static_cast(~(0xCC ^ 0xAA)))); // ~(B ^ C) + assert(op1 != value1); + assert(op1 != value2); + if (!op1->IsVectorZero()) { - assert(op1 != value1); - assert(op1 != value2); - op1 = gtNewZeroConNode(type); + GenTree* zero = gtNewZeroConNode(type); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op1 = gtNewOperNode(GT_COMMA, type, op1, zero); + } + else + { + op1 = zero; + } } op4->AsIntCon()->gtIconVal = static_cast(~(0xCC ^ 0xAA)); diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index ec234ebbfc8f6..60979a23950b2 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -2979,7 +2979,18 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { if (!op1->IsVectorZero()) { - retNode->AsHWIntrinsic()->Op(1) = gtNewZeroConNode(retType); + GenTree* zero = gtNewZeroConNode(retType); + + if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + { + op1 = gtNewOperNode(GT_COMMA, retType, op1, zero); + } + else + { + op1 = zero; + } + + retNode->AsHWIntrinsic()->Op(1) = op1; } } break; diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index 1141a42cbbf0a..e99271f038858 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1415,6 +1415,12 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B & C */ ["Imm"] = "34", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op3[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C & A */ ["Imm"] = "80", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op1[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C & B */ ["Imm"] = "68", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~A | B */ ["Imm"] = "207", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~A | C */ ["Imm"] = "175", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B | A */ ["Imm"] = "243", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] | op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] | op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B | C */ ["Imm"] = "187", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C | A */ ["Imm"] = "245", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] | op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] | op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C | B */ ["Imm"] = "221", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] | op2[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A & B */ ["Imm"] = "192", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op2[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* A & C */ ["Imm"] = "160", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op3[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* B & C */ ["Imm"] = "136", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] & op3[i])"}), @@ -1589,6 +1595,12 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B & C */ ["Imm"] = "34", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op3[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C & A */ ["Imm"] = "80", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op1[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C & B */ ["Imm"] = "68", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~A | B */ ["Imm"] = "207", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~A | C */ ["Imm"] = "175", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B | A */ ["Imm"] = "243", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] | op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] | op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B | C */ ["Imm"] = "187", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C | A */ ["Imm"] = "245", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] | op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] | op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C | B */ ["Imm"] = "221", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] | op2[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A & B */ ["Imm"] = "192", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op2[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* A & C */ ["Imm"] = "160", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op3[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* B & C */ ["Imm"] = "136", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] & op3[i])"}), @@ -1613,7 +1625,6 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt16", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt32", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "UInt64", ["Imm"] = "30", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != (op1[0] ^ (op2[0] | op3[0]))", ["ValidateRemainingResults"] = "result[i] != (op1[i] ^ (op2[i] | op3[i]))"}), - }; (string templateFileName, Dictionary templateData)[] Avx512F_VL_Vector256Inputs = new [] @@ -1737,6 +1748,12 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B & C */ ["Imm"] = "34", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] & op3[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C & A */ ["Imm"] = "80", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op1[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C & B */ ["Imm"] = "68", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] & op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~A | B */ ["Imm"] = "207", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] | op2[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~A | C */ ["Imm"] = "175", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op1[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op1[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B | A */ ["Imm"] = "243", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] | op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] | op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B | C */ ["Imm"] = "187", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op2[0] | op3[0])", ["ValidateRemainingResults"] = "result[i] != (~op2[i] | op3[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C | A */ ["Imm"] = "245", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] | op1[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] | op1[i])"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C | B */ ["Imm"] = "221", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (~op3[0] | op2[0])", ["ValidateRemainingResults"] = "result[i] != (~op3[i] | op2[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A & B */ ["Imm"] = "192", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op2[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op2[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* A & C */ ["Imm"] = "160", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op1[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op1[i] & op3[i])"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* B & C */ ["Imm"] = "136", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != (op2[0] & op3[0])", ["ValidateRemainingResults"] = "result[i] != (op2[i] & op3[i])"}), From e58abbb74a7d20b4f988a6d1c13cd2a725601c5d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 5 May 2023 14:14:09 -0700 Subject: [PATCH 07/21] Ensure the instruction code has the SIMD prefix before trying to encode the register --- src/coreclr/jit/emitxarch.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index da959d45b1ff0..c30c7d7908416 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -16449,11 +16449,13 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(!EncodedBySSE38orSSE3A(ins)); code = insCodeMI(ins); + code = AddSimdPrefixIfNeeded(id, code, size); regcode = insEncodeReg345(id, getSseShiftRegNumber(ins), size, &code); } else { code = insCodeRM(ins); + code = AddSimdPrefixIfNeeded(id, code, size); regcode = insEncodeReg345(id, id->idReg1(), size, &code); } @@ -16465,8 +16467,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } else { - code = AddSimdPrefixIfNeeded(id, code, size); - // In case of AVX instructions that take 3 operands, encode reg1 as first source. // Note that reg1 is both a source and a destination. // @@ -16684,11 +16684,13 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(!EncodedBySSE38orSSE3A(ins)); code = insCodeMI(ins); + code = AddSimdPrefixIfNeeded(id, code, size); regcode = insEncodeReg345(id, getSseShiftRegNumber(ins), size, &code); } else { code = insCodeRM(ins); + code = AddSimdPrefixIfNeeded(id, code, size); regcode = insEncodeReg345(id, id->idReg1(), size, &code); } @@ -16700,8 +16702,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } else { - code = AddSimdPrefixIfNeeded(id, code, size); - // In case of AVX instructions that take 3 operands, encode reg1 as first source. // Note that reg1 is both a source and a destination. // @@ -16894,11 +16894,13 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(!EncodedBySSE38orSSE3A(ins)); code = insCodeMI(ins); + code = AddSimdPrefixIfNeeded(id, code, size); regcode = insEncodeReg345(id, getSseShiftRegNumber(ins), size, &code); } else { code = insCodeRM(ins); + code = AddSimdPrefixIfNeeded(id, code, size); regcode = insEncodeReg345(id, id->idReg1(), size, &code); } @@ -16910,8 +16912,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } else { - code = AddSimdPrefixIfNeeded(id, code, size); - // In case of AVX instructions that take 3 operands, encode reg1 as first source. // Note that reg1 is both a source and a destination. // From a5323e2290d77f49398e8f5cf61c0ba152f10cc0 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 5 May 2023 15:00:41 -0700 Subject: [PATCH 08/21] Ensure side effects have been accounted for before swapping operands --- src/coreclr/jit/gentree.cpp | 63 +++++++++++++------ src/coreclr/jit/hwintrinsicxarch.cpp | 90 ++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 19 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 5658f717c2018..b450707684542 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -19875,7 +19875,11 @@ GenTree* Compiler::gtNewSimdBinOpNode( } // GT_AND_NOT expects `op1 & ~op2`, but xarch does `~op1 & op2` + // We expect op1 to have already been spilled + + assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); std::swap(op1, op2); + break; } @@ -24234,27 +24238,38 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, { case TernaryLogicUseFlags::A: { - // One operand. We swap it with C so it can be contained where possible - value1 = op1; - value2 = nullptr; + // We'll swap from 'A, B, C' to 'B, C, A' + // We expect A to have been spilled - std::swap(op1, op3); + assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); + + std::swap(op1, op2); // B, A, C + std::swap(op2, op3); // B, C, A + + value1 = op3; + value2 = nullptr; break; } case TernaryLogicUseFlags::B: { - // One operand. We swap it with C so it can be contained where possible - value1 = op2; - value2 = nullptr; + // We'll swap from 'A, B, C' to 'A, C, B' + // We expect A and B to have been spilled + + assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); + assert((op2->gtFlags & GTF_SIDE_EFFECT) == 0); + + std::swap(op2, op3); // A, C, B - std::swap(op2, op3); + value1 = op3; + value2 = nullptr; break; } case TernaryLogicUseFlags::C: { - // One operand. It is already in the ideal position + // We don't require any operands to have been spilled + value1 = op3; value2 = nullptr; break; @@ -24262,30 +24277,37 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, case TernaryLogicUseFlags::AB: { - // Two operands. We swap A with C so it can be contained where possible - // and so we aren't RMW + // We'll swap from 'A, B, C' to 'C, A, B' + // We expect A and B to have been spilled - value1 = op1; - value2 = op2; + assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); + assert((op2->gtFlags & GTF_SIDE_EFFECT) == 0); - std::swap(op1, op3); + std::swap(op1, op3); // C, B, A + std::swap(op2, op3); // C, A, B + + value1 = op2; + value2 = op3; break; } case TernaryLogicUseFlags::AC: { - // Two operands. We swap A with B so we aren't RMW + // We'll swap from 'A, B, C' to 'B, C, A' + // We expect A to have been spilled - value1 = op1; - value2 = op3; + assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); + + std::swap(op1, op2); // B, A, C - std::swap(op1, op2); + value1 = op2; + value2 = op3; break; } case TernaryLogicUseFlags::BC: { - // Two operands. They are already in the ideal positions + // We don't require any operands to have been spilled value1 = op2; value2 = op3; @@ -24469,6 +24491,9 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, value1 = gtNewOperNode(GT_COMMA, type, op1, value1); } + // GT_AND_NOT takes them as `op1 & ~op2` and x86 reorders them back to `~op1 & op2` + // since the underlying andnps/andnpd/pandn instructions take them as such + return gtNewSimdBinOpNode(GT_AND_NOT, type, value2, value1, simdBaseJitType, simdSize); } else diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 60979a23950b2..e710d8eac1093 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3002,6 +3002,96 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(sig->numArgs == 4); op4 = impPopStack().val; + + bool spillOp1 = false; + bool spillOp2 = false; + + if (op4->IsIntegralConst()) + { + uint8_t control = static_cast(op4->AsIntCon()->gtIconVal); + const TernaryLogicInfo& info = TernaryLogicInfo::lookup(control); + TernaryLogicUseFlags useFlags = info.GetAllUseFlags(); + + if (useFlags != TernaryLogicUseFlags::ABC) + { + switch (useFlags) + { + case TernaryLogicUseFlags::A: + { + // We'll swap from 'A, B, C' to 'B, C, A' + // so just spill A + + spillOp1 = true; + break; + } + + case TernaryLogicUseFlags::B: + { + // We'll swap from 'A, B, C' to 'A, C, B' + // so spill A and B + + spillOp1 = true; + spillOp2 = true; + break; + } + + case TernaryLogicUseFlags::C: + { + // No operands will be swapped + break; + } + + case TernaryLogicUseFlags::AB: + { + // We'll swap from 'A, B, C' to 'C, A, B' + // so spill A and B + + spillOp1 = true; + spillOp2 = true; + break; + } + + case TernaryLogicUseFlags::AC: + { + // We'll swap from 'A, B, C' to 'B, C, A' + // so just spill A + + spillOp1 = true; + break; + } + + case TernaryLogicUseFlags::BC: + { + // No operands will be swapped + break; + } + + case TernaryLogicUseFlags::None: + { + // No operands. + break; + } + + default: + { + unreached(); + } + } + } + } + + if (spillOp1) + { + impSpillSideEffect(true, verCurrentState.esStackDepth - + 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); + } + + if (spillOp2) + { + impSpillSideEffect(true, verCurrentState.esStackDepth - + 2 DEBUGARG("Spilling op2 side effects for HWIntrinsic")); + } + op3 = impSIMDPopStack(); op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); From 2584e7df4c4dd1a4d18749ffc2eb451c6e22d9ea Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 8 May 2023 09:06:19 -0700 Subject: [PATCH 09/21] Move the complex ternary logic simplification logic to import, since the JIT will never produce such nodes itself --- src/coreclr/jit/gentree.cpp | 508 --------------------------- src/coreclr/jit/hwintrinsicxarch.cpp | 460 ++++++++++++++++++++++-- 2 files changed, 435 insertions(+), 533 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b450707684542..616e23d457cbb 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -24210,514 +24210,6 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, intrinsic = NI_AVX512F_VL_TernaryLogic; } - if (op4->IsIntegralConst()) - { - // We have a constant control byte, so we can potentially optimize - - uint8_t control = static_cast(op4->AsIntCon()->gtIconVal); - const TernaryLogicInfo& info = TernaryLogicInfo::lookup(control); - TernaryLogicUseFlags useFlags = info.GetAllUseFlags(); - - if (useFlags != TernaryLogicUseFlags::ABC) - { - // We are not using all 3 inputs, so we can potentially optimize - - assert(info.oper2 != TernaryLogicOperKind::Select); - assert(info.oper2 != TernaryLogicOperKind::True); - assert(info.oper2 != TernaryLogicOperKind::False); - assert(info.oper2 != TernaryLogicOperKind::Cond); - assert(info.oper2 != TernaryLogicOperKind::Major); - assert(info.oper2 != TernaryLogicOperKind::Minor); - assert(info.oper3 == TernaryLogicOperKind::None); - assert(info.oper3Use == TernaryLogicUseFlags::None); - - GenTree* value1; - GenTree* value2; - - switch (useFlags) - { - case TernaryLogicUseFlags::A: - { - // We'll swap from 'A, B, C' to 'B, C, A' - // We expect A to have been spilled - - assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); - - std::swap(op1, op2); // B, A, C - std::swap(op2, op3); // B, C, A - - value1 = op3; - value2 = nullptr; - break; - } - - case TernaryLogicUseFlags::B: - { - // We'll swap from 'A, B, C' to 'A, C, B' - // We expect A and B to have been spilled - - assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); - assert((op2->gtFlags & GTF_SIDE_EFFECT) == 0); - - std::swap(op2, op3); // A, C, B - - value1 = op3; - value2 = nullptr; - break; - } - - case TernaryLogicUseFlags::C: - { - // We don't require any operands to have been spilled - - value1 = op3; - value2 = nullptr; - break; - } - - case TernaryLogicUseFlags::AB: - { - // We'll swap from 'A, B, C' to 'C, A, B' - // We expect A and B to have been spilled - - assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); - assert((op2->gtFlags & GTF_SIDE_EFFECT) == 0); - - std::swap(op1, op3); // C, B, A - std::swap(op2, op3); // C, A, B - - value1 = op2; - value2 = op3; - break; - } - - case TernaryLogicUseFlags::AC: - { - // We'll swap from 'A, B, C' to 'B, C, A' - // We expect A to have been spilled - - assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); - - std::swap(op1, op2); // B, A, C - - value1 = op2; - value2 = op3; - break; - } - - case TernaryLogicUseFlags::BC: - { - // We don't require any operands to have been spilled - - value1 = op2; - value2 = op3; - break; - } - - case TernaryLogicUseFlags::None: - { - // No operands. - - value1 = nullptr; - value2 = nullptr; - - break; - } - - default: - { - unreached(); - } - } - - switch (info.oper1) - { - case TernaryLogicOperKind::Select: - { - assert(info.oper1Use != TernaryLogicUseFlags::None); - assert(value2 == nullptr); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(0xF0)) || // A - (control == static_cast(0xCC)) || // B - (control == static_cast(0xAA))); // C - - assert(op1 != value1); - assert(op2 != value1); - assert(op3 == value1); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op2, value1); - } - - return value1; - } - - case TernaryLogicOperKind::True: - { - assert(value1 == nullptr); - assert(value2 == nullptr); - - assert(info.oper1Use == TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert(control == static_cast(0xFF)); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op2, value1); - } - - if ((op3->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op3, value1); - } - - return gtNewAllBitsSetConNode(type); - } - - case TernaryLogicOperKind::False: - { - assert(value1 == nullptr); - assert(value2 == nullptr); - - assert(info.oper1Use == TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert(control == static_cast(0x00)); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op2, value1); - } - - if ((op3->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op3, value1); - } - - return gtNewZeroConNode(type); - } - - case TernaryLogicOperKind::Not: - { - assert(value1 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - if (info.oper2 == TernaryLogicOperKind::None) - { - assert(value2 == nullptr); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(~0xF0)) || // ~A - (control == static_cast(~0xCC)) || // ~B - (control == static_cast(~0xAA))); // ~C - - assert(op1 != value1); - assert(op2 != value1); - assert(op3 == value1); - - if (!op1->IsVectorZero()) - { - GenTree* zero = gtNewZeroConNode(type); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op1 = gtNewOperNode(GT_COMMA, type, op1, zero); - } - else - { - op1 = zero; - } - } - - if (!op2->IsVectorZero()) - { - GenTree* zero = gtNewZeroConNode(type); - - if ((op2->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op2 = gtNewOperNode(GT_COMMA, type, op2, zero); - } - else - { - op2 = zero; - } - } - - op4->AsIntCon()->gtIconVal = static_cast(~0xAA); - break; - } - - assert(value2 != nullptr); - assert(info.oper2Use != TernaryLogicUseFlags::None); - - if (info.oper2 == TernaryLogicOperKind::And) - { - assert((control == static_cast(~0xF0 & 0xCC)) || // ~A & B - (control == static_cast(~0xF0 & 0xAA)) || // ~A & C - (control == static_cast(~0xCC & 0xF0)) || // ~B & A - (control == static_cast(~0xCC & 0xAA)) || // ~B & C - (control == static_cast(~0xAA & 0xF0)) || // ~C & A - (control == static_cast(~0xAA & 0xCC))); // ~C & B - - assert(op1 != value1); - assert(op1 != value2); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - // GT_AND_NOT takes them as `op1 & ~op2` and x86 reorders them back to `~op1 & op2` - // since the underlying andnps/andnpd/pandn instructions take them as such - - return gtNewSimdBinOpNode(GT_AND_NOT, type, value2, value1, simdBaseJitType, simdSize); - } - else - { - assert(info.oper2 == TernaryLogicOperKind::Or); - - assert((control == static_cast(~0xF0 | 0xCC)) || // ~A | B - (control == static_cast(~0xF0 | 0xAA)) || // ~A | C - (control == static_cast(~0xCC | 0xF0)) || // ~B | A - (control == static_cast(~0xCC | 0xAA)) || // ~B | C - (control == static_cast(~0xAA | 0xF0)) || // ~C | A - (control == static_cast(~0xAA | 0xCC))); // ~C | B - - assert(op1 != value1); - assert(op1 != value2); - - if (!op1->IsVectorZero()) - { - GenTree* zero = gtNewZeroConNode(type); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op1 = gtNewOperNode(GT_COMMA, type, op1, zero); - } - else - { - op1 = zero; - } - } - } - break; - } - - case TernaryLogicOperKind::And: - { - assert(value1 != nullptr); - assert(value2 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(0xF0 & 0xCC)) || // A & B - (control == static_cast(0xF0 & 0xAA)) || // A & C - (control == static_cast(0xCC & 0xAA))); // B & C - - assert(op1 != value1); - assert(op1 != value2); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - return gtNewSimdBinOpNode(GT_AND, type, value1, value2, simdBaseJitType, simdSize); - } - - case TernaryLogicOperKind::Nand: - { - assert(value1 != nullptr); - assert(value2 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(~(0xF0 & 0xCC))) || // ~(A & B) - (control == static_cast(~(0xF0 & 0xAA))) || // ~(A & C) - (control == static_cast(~(0xCC & 0xAA)))); // ~(B & C) - - assert(op1 != value1); - assert(op1 != value2); - - if (!op1->IsVectorZero()) - { - GenTree* zero = gtNewZeroConNode(type); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op1 = gtNewOperNode(GT_COMMA, type, op1, zero); - } - else - { - op1 = zero; - } - } - - op4->AsIntCon()->gtIconVal = static_cast(~(0xCC & 0xAA)); - break; - } - - case TernaryLogicOperKind::Or: - { - assert(value1 != nullptr); - assert(value2 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(0xF0 | 0xCC)) || // A | B - (control == static_cast(0xF0 | 0xAA)) || // A | C - (control == static_cast(0xCC | 0xAA))); // B | C - - assert(op1 != value1); - assert(op1 != value2); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - return gtNewSimdBinOpNode(GT_OR, type, value1, value2, simdBaseJitType, simdSize); - } - - case TernaryLogicOperKind::Nor: - { - assert(value1 != nullptr); - assert(value2 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(~(0xF0 | 0xCC))) || // ~(A | B) - (control == static_cast(~(0xF0 | 0xAA))) || // ~(A | C) - (control == static_cast(~(0xCC | 0xAA)))); // ~(B | C) - - assert(op1 != value1); - assert(op1 != value2); - - if (!op1->IsVectorZero()) - { - GenTree* zero = gtNewZeroConNode(type); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op1 = gtNewOperNode(GT_COMMA, type, op1, zero); - } - else - { - op1 = zero; - } - } - - op4->AsIntCon()->gtIconVal = static_cast(~(0xCC | 0xAA)); - break; - } - - case TernaryLogicOperKind::Xor: - { - assert(value1 != nullptr); - assert(value2 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(0xF0 ^ 0xCC)) || // A ^ B - (control == static_cast(0xF0 ^ 0xAA)) || // A ^ C - (control == static_cast(0xCC ^ 0xAA))); // B ^ C - - assert(op1 != value1); - assert(op1 != value2); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - value1 = gtNewOperNode(GT_COMMA, type, op1, value1); - } - - return gtNewSimdBinOpNode(GT_XOR, type, value1, value2, simdBaseJitType, simdSize); - } - - case TernaryLogicOperKind::Xnor: - { - assert(value1 != nullptr); - assert(value2 != nullptr); - assert(info.oper1Use != TernaryLogicUseFlags::None); - - assert(info.oper2 == TernaryLogicOperKind::None); - assert(info.oper2Use == TernaryLogicUseFlags::None); - - assert((control == static_cast(~(0xF0 ^ 0xCC))) || // ~(A ^ B) - (control == static_cast(~(0xF0 ^ 0xAA))) || // ~(A ^ C) - (control == static_cast(~(0xCC ^ 0xAA)))); // ~(B ^ C) - - assert(op1 != value1); - assert(op1 != value2); - - if (!op1->IsVectorZero()) - { - GenTree* zero = gtNewZeroConNode(type); - - if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - op1 = gtNewOperNode(GT_COMMA, type, op1, zero); - } - else - { - op1 = zero; - } - } - - op4->AsIntCon()->gtIconVal = static_cast(~(0xCC ^ 0xAA)); - break; - } - - case TernaryLogicOperKind::None: - case TernaryLogicOperKind::Cond: - case TernaryLogicOperKind::Major: - case TernaryLogicOperKind::Minor: - { - // invalid table metadata - unreached(); - } - - default: - { - unreached(); - } - } - } - } - return gtNewSimdHWIntrinsicNode(type, op1, op2, op3, op4, intrinsic, simdBaseJitType, simdSize); } #endif // TARGET_XARCH diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index e710d8eac1093..820581278c715 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3003,9 +3003,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, op4 = impPopStack().val; - bool spillOp1 = false; - bool spillOp2 = false; - if (op4->IsIntegralConst()) { uint8_t control = static_cast(op4->AsIntCon()->gtIconVal); @@ -3014,61 +3011,187 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (useFlags != TernaryLogicUseFlags::ABC) { + // We are not using all 3 inputs, so we can potentially optimize + // + // In particular, for unary and binary operations we want to prefer + // the standard operator over vpternlog with unused operands where + // possible and we want to normalize to a consistent ternlog otherwise. + // + // Doing this massively simplifies downstream checks because later + // phases, such as morph which can combine bitwise operations to + // produce new vpternlog nodes, no longer have to consider all the + // special edges themselves. + // + // For example, they don't have to consider that `bitwise and` could + // present itself as all of the following: + // * HWINTRINSIC_TernaryLogic(op1, op2, unused, cns) + // * HWINTRINSIC_TernaryLogic(op1, unused, op2, cns) + // * HWINTRINSIC_TernaryLogic(unused, op1, op2, cns) + // + // Instead, it will only see HWINTRINSIC_And(op1, op2). + // + // For cases which must be kept as vpternlog, such as `not` or `xnor` + // (because there is no regular unary/binary operator for them), it + // ensures we only have one form to consider and that any side effects + // will have already been spilled where relevant. + // + // For example, they don't have to consider that `not` could present + // itself as all of the following: + // * HWINTRINSIC_TernaryLogic(op1, unused, unused, cns) + // * HWINTRINSIC_TernaryLogic(unused, op1, unused, cns) + // * HWINTRINSIC_TernaryLogic(unused, unused, op1, cns) + // + // Instead, it will only see HWINTRINSIC_TernaryLogic(unused, unused, op1, cns) + + assert(info.oper2 != TernaryLogicOperKind::Select); + assert(info.oper2 != TernaryLogicOperKind::True); + assert(info.oper2 != TernaryLogicOperKind::False); + assert(info.oper2 != TernaryLogicOperKind::Cond); + assert(info.oper2 != TernaryLogicOperKind::Major); + assert(info.oper2 != TernaryLogicOperKind::Minor); + assert(info.oper3 == TernaryLogicOperKind::None); + assert(info.oper3Use == TernaryLogicUseFlags::None); + + bool spillOp1 = false; + bool spillOp2 = false; + + GenTree*& val1 = op1; + GenTree*& val2 = op2; + GenTree*& val3 = op3; + + bool unusedVal1 = false; + bool unusedVal2 = false; + bool unusedVal3 = false; + switch (useFlags) { case TernaryLogicUseFlags::A: { - // We'll swap from 'A, B, C' to 'B, C, A' - // so just spill A + // We're only using op1, so we'll swap + // from '1, 2, 3' to '2, 3, 1', this + // means we need to spill op1 and + // append op2/op3 as gtUnusedVal + // + // This gives us: + // * tmp1 = op1 + // * unused(op2) + // * unused(op3) + // * res = tmp1 spillOp1 = true; + + std::swap(val1, val2); // 2, 1, 3 + std::swap(val2, val3); // 2, 3, 1 + + unusedVal1 = true; + unusedVal2 = true; break; } case TernaryLogicUseFlags::B: { - // We'll swap from 'A, B, C' to 'A, C, B' - // so spill A and B + // We're only using op2, so we'll swap + // from '1, 2, 3' to '1, 3, 2', this + // means we need to spill op1/op2 and + // append op3 as gtUnusedVal + // + // This gives us: + // * tmp1 = op1 + // * tmp2 = op2 + // * unused(op3) + // * res = tmp2 spillOp1 = true; spillOp2 = true; + + std::swap(val2, val3); // 1, 3, 2 + + unusedVal2 = true; break; } case TernaryLogicUseFlags::C: { - // No operands will be swapped + // We're only using op3, so we don't + // need to swap, but we do need to + // append op1/op2 as gtUnusedVal + // + // This gives us: + // * unused(op1) + // * unused(op2) + // * res = op3 + + unusedVal1 = true; + unusedVal2 = true; break; } case TernaryLogicUseFlags::AB: { - // We'll swap from 'A, B, C' to 'C, A, B' - // so spill A and B + // We're using op1 and op2, so we need + // to swap from '1, 2, 3' to '3, 1, 2', + // this means we need to spill op1/op2 + // and append op3 as gtUnusedVal + // + // This gives us: + // tmp1 = op1 + // tmp2 = op2 + // unused(op3) + // res = BinOp(tmp1, tmp2) spillOp1 = true; spillOp2 = true; + + std::swap(val1, val3); // 3, 2, 1 + std::swap(val2, val3); // 3, 1, 2 + + unusedVal1 = true; break; } case TernaryLogicUseFlags::AC: { - // We'll swap from 'A, B, C' to 'B, C, A' - // so just spill A + // We're using op1 and op3, so we need + // to swap from '1, 2, 3' to '2, 1, 3', + // this means we need to spill op1 and + // append op2 as gtUnusedVal + // + // This gives us: + // tmp1 = op1 + // unused(op2) + // res = BinOp(tmp1, op3) spillOp1 = true; + + std::swap(val1, val2); // 2, 1, 3 + + unusedVal1 = true; break; } case TernaryLogicUseFlags::BC: { - // No operands will be swapped + // We're using op2 and op3, so we don't + // need to swap, but we do need to + // append op1 as gtUnusedVal + // + // This gives us: + // * unused(op1) + // * res = BinOp(op2, op3) + + unusedVal1 = true; break; } case TernaryLogicUseFlags::None: { - // No operands. + // We're not using any operands, so we don't + // need to swap, but we do need push all three + // operands up as gtUnusedVal + + unusedVal1 = true; + unusedVal2 = true; + unusedVal3 = true; break; } @@ -3077,19 +3200,306 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, unreached(); } } - } - } - if (spillOp1) - { - impSpillSideEffect(true, verCurrentState.esStackDepth - - 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); - } + if (spillOp1) + { + impSpillSideEffect(true, verCurrentState.esStackDepth - + 3 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); + } - if (spillOp2) - { - impSpillSideEffect(true, verCurrentState.esStackDepth - - 2 DEBUGARG("Spilling op2 side effects for HWIntrinsic")); + if (spillOp2) + { + impSpillSideEffect(true, verCurrentState.esStackDepth - + 2 DEBUGARG("Spilling op2 side effects for HWIntrinsic")); + } + + op3 = impSIMDPopStack(); + op2 = impSIMDPopStack(); + op1 = impSIMDPopStack(); + + if (unusedVal1) + { + impAppendTree(gtUnusedValNode(val1), CHECK_SPILL_NONE, impCurStmtDI); + } + + if (unusedVal2) + { + impAppendTree(gtUnusedValNode(val2), CHECK_SPILL_NONE, impCurStmtDI); + } + + if (unusedVal3) + { + impAppendTree(gtUnusedValNode(val3), CHECK_SPILL_NONE, impCurStmtDI); + } + + switch (info.oper1) + { + case TernaryLogicOperKind::Select: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0)) || // A + (control == static_cast(0xCC)) || // B + (control == static_cast(0xAA))); // C + + assert(unusedVal1); + assert(unusedVal2); + assert(!unusedVal3); + + return val3; + } + + case TernaryLogicOperKind::True: + { + assert(info.oper1Use == TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert(control == static_cast(0xFF)); + + assert(unusedVal1); + assert(unusedVal2); + assert(unusedVal3); + + return gtNewAllBitsSetConNode(retType); + } + + case TernaryLogicOperKind::False: + { + assert(info.oper1Use == TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert(control == static_cast(0x00)); + + assert(unusedVal1); + assert(unusedVal2); + assert(unusedVal3); + + return gtNewZeroConNode(retType); + } + + case TernaryLogicOperKind::Not: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + if (info.oper2 == TernaryLogicOperKind::None) + { + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~0xF0)) || // ~A + (control == static_cast(~0xCC)) || // ~B + (control == static_cast(~0xAA))); // ~C + + assert(unusedVal1); + assert(unusedVal2); + assert(!unusedVal3); + + if (!val1->IsVectorZero()) + { + val1 = gtNewZeroConNode(retType); + } + + if (!val2->IsVectorZero()) + { + val2 = gtNewZeroConNode(retType); + } + + op4->AsIntCon()->gtIconVal = static_cast(~0xAA); + break; + } + + assert(info.oper2Use != TernaryLogicUseFlags::None); + + if (info.oper2 == TernaryLogicOperKind::And) + { + assert((control == static_cast(~0xF0 & 0xCC)) || // ~A & B + (control == static_cast(~0xF0 & 0xAA)) || // ~A & C + (control == static_cast(~0xCC & 0xF0)) || // ~B & A + (control == static_cast(~0xCC & 0xAA)) || // ~B & C + (control == static_cast(~0xAA & 0xF0)) || // ~C & A + (control == static_cast(~0xAA & 0xCC))); // ~C & B + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + // GT_AND_NOT takes them as `op1 & ~op2` and x86 reorders them back to `~op1 & op2` + // since the underlying andnps/andnpd/pandn instructions take them as such + + return gtNewSimdBinOpNode(GT_AND_NOT, retType, val3, val2, simdBaseJitType, simdSize); + } + else + { + assert(info.oper2 == TernaryLogicOperKind::Or); + + assert((control == static_cast(~0xF0 | 0xCC)) || // ~A | B + (control == static_cast(~0xF0 | 0xAA)) || // ~A | C + (control == static_cast(~0xCC | 0xF0)) || // ~B | A + (control == static_cast(~0xCC | 0xAA)) || // ~B | C + (control == static_cast(~0xAA | 0xF0)) || // ~C | A + (control == static_cast(~0xAA | 0xCC))); // ~C | B + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + if (!val1->IsVectorZero()) + { + val1 = gtNewZeroConNode(retType); + } + } + break; + } + + case TernaryLogicOperKind::And: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0 & 0xCC)) || // A & B + (control == static_cast(0xF0 & 0xAA)) || // A & C + (control == static_cast(0xCC & 0xAA))); // B & C + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + return gtNewSimdBinOpNode(GT_AND, retType, val2, val3, simdBaseJitType, simdSize); + } + + case TernaryLogicOperKind::Nand: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~(0xF0 & 0xCC))) || // ~(A & B) + (control == static_cast(~(0xF0 & 0xAA))) || // ~(A & C) + (control == static_cast(~(0xCC & 0xAA)))); // ~(B & C) + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + if (!val1->IsVectorZero()) + { + val1 = gtNewZeroConNode(retType); + } + + op4->AsIntCon()->gtIconVal = static_cast(~(0xCC & 0xAA)); + break; + } + + case TernaryLogicOperKind::Or: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0 | 0xCC)) || // A | B + (control == static_cast(0xF0 | 0xAA)) || // A | C + (control == static_cast(0xCC | 0xAA))); // B | C + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + return gtNewSimdBinOpNode(GT_OR, retType, val2, val3, simdBaseJitType, simdSize); + } + + case TernaryLogicOperKind::Nor: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~(0xF0 | 0xCC))) || // ~(A | B) + (control == static_cast(~(0xF0 | 0xAA))) || // ~(A | C) + (control == static_cast(~(0xCC | 0xAA)))); // ~(B | C) + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + if (!val1->IsVectorZero()) + { + val1 = gtNewZeroConNode(retType); + } + + op4->AsIntCon()->gtIconVal = static_cast(~(0xCC | 0xAA)); + break; + } + + case TernaryLogicOperKind::Xor: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(0xF0 ^ 0xCC)) || // A ^ B + (control == static_cast(0xF0 ^ 0xAA)) || // A ^ C + (control == static_cast(0xCC ^ 0xAA))); // B ^ C + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + return gtNewSimdBinOpNode(GT_XOR, retType, val2, val3, simdBaseJitType, simdSize); + } + + case TernaryLogicOperKind::Xnor: + { + assert(info.oper1Use != TernaryLogicUseFlags::None); + + assert(info.oper2 == TernaryLogicOperKind::None); + assert(info.oper2Use == TernaryLogicUseFlags::None); + + assert((control == static_cast(~(0xF0 ^ 0xCC))) || // ~(A ^ B) + (control == static_cast(~(0xF0 ^ 0xAA))) || // ~(A ^ C) + (control == static_cast(~(0xCC ^ 0xAA)))); // ~(B ^ C) + + assert(unusedVal1); + assert(!unusedVal2); + assert(!unusedVal3); + + if (!val1->IsVectorZero()) + { + val1 = gtNewZeroConNode(retType); + } + + op4->AsIntCon()->gtIconVal = static_cast(~(0xCC ^ 0xAA)); + break; + } + + case TernaryLogicOperKind::None: + case TernaryLogicOperKind::Cond: + case TernaryLogicOperKind::Major: + case TernaryLogicOperKind::Minor: + { + // invalid table metadata + unreached(); + } + + default: + { + unreached(); + } + } + + retNode = gtNewSimdTernaryLogicNode(retType, val1, val2, val3, op4, simdBaseJitType, simdSize); + } } op3 = impSIMDPopStack(); From 6636fba8f00d9e0b2305b261162a6da840fba519 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 8 May 2023 10:30:47 -0700 Subject: [PATCH 10/21] Ensure gtNewSimdUnOpNode(GT_NOT) uses an in range constant for TernaryLogic --- src/coreclr/jit/gentree.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 616e23d457cbb..7f45cec10496b 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -24296,7 +24296,8 @@ GenTree* Compiler::gtNewSimdUnOpNode( op2 = gtNewZeroConNode(type); op3 = gtNewZeroConNode(type); - return gtNewSimdTernaryLogicNode(type, op3, op2, op1, gtNewIconNode(~0xAA), simdBaseJitType, simdSize); + GenTree* cns = gtNewIconNode(static_cast(~0xAA)); // ~C + return gtNewSimdTernaryLogicNode(type, op3, op2, op1, cns, simdBaseJitType, simdSize); } else { From acdfb9b0b085b4fda7c15264696a8be327eae2f0 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 8 May 2023 13:09:33 -0700 Subject: [PATCH 11/21] Remove a new assert added to AND_NOT, logging an issue instead --- src/coreclr/jit/gentree.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 7f45cec10496b..b9cb38495c008 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -19877,9 +19877,7 @@ GenTree* Compiler::gtNewSimdBinOpNode( // GT_AND_NOT expects `op1 & ~op2`, but xarch does `~op1 & op2` // We expect op1 to have already been spilled - assert((op1->gtFlags & GTF_SIDE_EFFECT) == 0); std::swap(op1, op2); - break; } From 49646ce1f261467b2962b1ca8b7fbc183b264f26 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 8 May 2023 19:09:21 -0700 Subject: [PATCH 12/21] Add a missing `break;` statement --- src/coreclr/jit/hwintrinsicxarch.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 820581278c715..23c3f02f9a711 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3499,6 +3499,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } retNode = gtNewSimdTernaryLogicNode(retType, val1, val2, val3, op4, simdBaseJitType, simdSize); + break; } } From 142064279708d24183fa4efb84ec4298e855dbc2 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 07:43:19 -0700 Subject: [PATCH 13/21] Ensure val1/2/3 are GenTree** so swapping works and add a comment explaining the TernaryLogic table --- src/coreclr/jit/hwintrinsic.cpp | 28 ++++++++++++++++ src/coreclr/jit/hwintrinsicxarch.cpp | 48 ++++++++++++++-------------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 07dab3a133e95..68c1241dde975 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -43,6 +43,34 @@ const HWIntrinsicInfo& HWIntrinsicInfo::lookup(NamedIntrinsic id) #if defined(TARGET_XARCH) const TernaryLogicInfo& TernaryLogicInfo::lookup(uint8_t control) { + // This table is 768 bytes and is about as small as we can make it. + // + // The way the constants work is we have three keys: + // * A: 0xF0 + // * B: 0xCC + // * C: 0xAA + // + // To compute the correct control byte, you simply perform the corresponding operation on these keys. So, if you + // wanted to do (A & B) ^ C, you would compute (0xF0 & 0xCC) ^ 0xAA or 0x6A. + // + // This table allows us to compute the inverse information, that is given a control, what are the operations it performs. + // This allows us to determine things like what operands are actually used (so we can correctly compute isRMW) and + // what operations are performed and in what order (such that we can do constant folding in the future). + // + // The total set of operations supported are: + // * true: AllBitsSet + // * false: Zero + // * not: ~value + // * and: left & right + // * nand: ~(left & right) + // * or: left | right + // * nor: ~(left | right) + // * xor: left ^ right + // * xnor: ~(left ^ right) + // * cndsel: a ? b : c; aka (B & A) | (C & ~A) + // * major: 0 if two+ input bits are 0 + // * minor: 1 if two+ input bits are 0 + // clang-format off static const TernaryLogicInfo ternaryLogicFlags[256] = { /* FALSE */ { TernaryLogicOperKind::False, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None, TernaryLogicOperKind::None, TernaryLogicUseFlags::None }, diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 23c3f02f9a711..17592f8556fc0 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3055,9 +3055,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, bool spillOp1 = false; bool spillOp2 = false; - GenTree*& val1 = op1; - GenTree*& val2 = op2; - GenTree*& val3 = op3; + GenTree** val1 = &op1; + GenTree** val2 = &op2; + GenTree** val3 = &op3; bool unusedVal1 = false; bool unusedVal2 = false; @@ -3219,17 +3219,17 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (unusedVal1) { - impAppendTree(gtUnusedValNode(val1), CHECK_SPILL_NONE, impCurStmtDI); + impAppendTree(gtUnusedValNode(*val1), CHECK_SPILL_NONE, impCurStmtDI); } if (unusedVal2) { - impAppendTree(gtUnusedValNode(val2), CHECK_SPILL_NONE, impCurStmtDI); + impAppendTree(gtUnusedValNode(*val2), CHECK_SPILL_NONE, impCurStmtDI); } if (unusedVal3) { - impAppendTree(gtUnusedValNode(val3), CHECK_SPILL_NONE, impCurStmtDI); + impAppendTree(gtUnusedValNode(*val3), CHECK_SPILL_NONE, impCurStmtDI); } switch (info.oper1) @@ -3249,7 +3249,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(unusedVal2); assert(!unusedVal3); - return val3; + return *val3; } case TernaryLogicOperKind::True: @@ -3300,14 +3300,14 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(unusedVal2); assert(!unusedVal3); - if (!val1->IsVectorZero()) + if (!(*val1)->IsVectorZero()) { - val1 = gtNewZeroConNode(retType); + *val1 = gtNewZeroConNode(retType); } - if (!val2->IsVectorZero()) + if (!(*val2)->IsVectorZero()) { - val2 = gtNewZeroConNode(retType); + *val2 = gtNewZeroConNode(retType); } op4->AsIntCon()->gtIconVal = static_cast(~0xAA); @@ -3332,7 +3332,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, // GT_AND_NOT takes them as `op1 & ~op2` and x86 reorders them back to `~op1 & op2` // since the underlying andnps/andnpd/pandn instructions take them as such - return gtNewSimdBinOpNode(GT_AND_NOT, retType, val3, val2, simdBaseJitType, simdSize); + return gtNewSimdBinOpNode(GT_AND_NOT, retType, *val3, *val2, simdBaseJitType, simdSize); } else { @@ -3349,9 +3349,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - if (!val1->IsVectorZero()) + if (!(*val1)->IsVectorZero()) { - val1 = gtNewZeroConNode(retType); + *val1 = gtNewZeroConNode(retType); } } break; @@ -3372,7 +3372,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - return gtNewSimdBinOpNode(GT_AND, retType, val2, val3, simdBaseJitType, simdSize); + return gtNewSimdBinOpNode(GT_AND, retType, *val2, *val3, simdBaseJitType, simdSize); } case TernaryLogicOperKind::Nand: @@ -3390,9 +3390,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - if (!val1->IsVectorZero()) + if (!(*val1)->IsVectorZero()) { - val1 = gtNewZeroConNode(retType); + *val1 = gtNewZeroConNode(retType); } op4->AsIntCon()->gtIconVal = static_cast(~(0xCC & 0xAA)); @@ -3414,7 +3414,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - return gtNewSimdBinOpNode(GT_OR, retType, val2, val3, simdBaseJitType, simdSize); + return gtNewSimdBinOpNode(GT_OR, retType, *val2, *val3, simdBaseJitType, simdSize); } case TernaryLogicOperKind::Nor: @@ -3432,9 +3432,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - if (!val1->IsVectorZero()) + if (!(*val1)->IsVectorZero()) { - val1 = gtNewZeroConNode(retType); + *val1 = gtNewZeroConNode(retType); } op4->AsIntCon()->gtIconVal = static_cast(~(0xCC | 0xAA)); @@ -3456,7 +3456,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - return gtNewSimdBinOpNode(GT_XOR, retType, val2, val3, simdBaseJitType, simdSize); + return gtNewSimdBinOpNode(GT_XOR, retType, *val2, *val3, simdBaseJitType, simdSize); } case TernaryLogicOperKind::Xnor: @@ -3474,9 +3474,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(!unusedVal2); assert(!unusedVal3); - if (!val1->IsVectorZero()) + if (!(*val1)->IsVectorZero()) { - val1 = gtNewZeroConNode(retType); + *val1 = gtNewZeroConNode(retType); } op4->AsIntCon()->gtIconVal = static_cast(~(0xCC ^ 0xAA)); @@ -3498,7 +3498,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } } - retNode = gtNewSimdTernaryLogicNode(retType, val1, val2, val3, op4, simdBaseJitType, simdSize); + retNode = gtNewSimdTernaryLogicNode(retType, *val1, *val2, *val3, op4, simdBaseJitType, simdSize); break; } } From 1af17d80923a148dbfc95699bac4796976be2007 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 08:03:48 -0700 Subject: [PATCH 14/21] Fix formatting of a comment --- src/coreclr/jit/hwintrinsic.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 68c1241dde975..94d0d028dfd1f 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -53,9 +53,9 @@ const TernaryLogicInfo& TernaryLogicInfo::lookup(uint8_t control) // To compute the correct control byte, you simply perform the corresponding operation on these keys. So, if you // wanted to do (A & B) ^ C, you would compute (0xF0 & 0xCC) ^ 0xAA or 0x6A. // - // This table allows us to compute the inverse information, that is given a control, what are the operations it performs. - // This allows us to determine things like what operands are actually used (so we can correctly compute isRMW) and - // what operations are performed and in what order (such that we can do constant folding in the future). + // This table allows us to compute the inverse information, that is given a control, what are the operations it + // performs. This allows us to determine things like what operands are actually used (so we can correctly compute + // isRMW) and what operations are performed and in what order (such that we can do constant folding in the future). // // The total set of operations supported are: // * true: AllBitsSet From f2d83785a8c45507db4d96012c8b517b5f23d158 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 10:12:29 -0700 Subject: [PATCH 15/21] Don't double encode the 'vvvv' bits for `emitOutputAM` --- src/coreclr/jit/emitxarch.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index c30c7d7908416..459cc71718e8e 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -16467,18 +16467,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } else { - // In case of AVX instructions that take 3 operands, encode reg1 as first source. - // Note that reg1 is both a source and a destination. - // - // TODO-XArch-CQ: Eventually we need to support 3 operand instruction formats. For - // now we use the single source as source1 and source2. - // For this format, moves do not support a third operand, so we only need to handle the binary ops. - if (IsDstDstSrcAVXInstruction(ins)) - { - // encode source operand reg in 'vvvv' bits in 1's complement form - code = insEncodeReg3456(id, id->idReg1(), size, code); - } - dst = emitOutputAM(dst, id, code | (regcode << 8), &cnsVal); } From 94b5e53f15907733cc49148a2cfd7a364a3c1f5b Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 12:29:30 -0700 Subject: [PATCH 16/21] Avoid an assert in gtNewSimdCreateBroadcastNode for TYP_LONG on 32-bit --- src/coreclr/jit/hwintrinsicxarch.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 17592f8556fc0..d1448575254fd 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -609,13 +609,23 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT static_assert_no_msg(NI_AVX512F_VL_RotateLeftVariable == (NI_AVX512F_VL_RotateLeft + 1)); static_assert_no_msg(NI_AVX512F_VL_RotateRightVariable == (NI_AVX512F_VL_RotateRight + 1)); + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + +#if defined(TARGET_X86) + if (varTypeIsLong(simdBaseType)) + { + // TODO-XARCH-CQ: We need to add TYP_LONG support to gtNewSimdCreateBroadcastNode + return nullptr; + } +#endif // TARGET_X86 + impSpillSideEffect(true, verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); GenTree* op2 = impPopStack().val; GenTree* op1 = impSIMDPopStack(); - if (varTypeIsLong(simdType)) + if (varTypeIsLong(simdBaseType)) { op2 = gtNewCastNode(TYP_LONG, op2, /* fromUnsigned */ true, TYP_LONG); } From 5d0a740f9cf8690287f886449a042461ad3b51d0 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 13:41:47 -0700 Subject: [PATCH 17/21] Ensure we use CHECK_SPILL_ALL --- src/coreclr/jit/hwintrinsicxarch.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index d1448575254fd..ed6b6219161a4 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3229,17 +3229,17 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (unusedVal1) { - impAppendTree(gtUnusedValNode(*val1), CHECK_SPILL_NONE, impCurStmtDI); + impAppendTree(gtUnusedValNode(*val1), CHECK_SPILL_ALL, impCurStmtDI); } if (unusedVal2) { - impAppendTree(gtUnusedValNode(*val2), CHECK_SPILL_NONE, impCurStmtDI); + impAppendTree(gtUnusedValNode(*val2), CHECK_SPILL_ALL, impCurStmtDI); } if (unusedVal3) { - impAppendTree(gtUnusedValNode(*val3), CHECK_SPILL_NONE, impCurStmtDI); + impAppendTree(gtUnusedValNode(*val3), CHECK_SPILL_ALL, impCurStmtDI); } switch (info.oper1) From d07bc37070a72d1ccfa8222c1980c26cbd8fb038 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 17:25:36 -0700 Subject: [PATCH 18/21] Ensure mustExpand is handled for `RotateLeft(Vector###)` on 32-bit --- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/gentree.cpp | 15 ++++++++++ src/coreclr/jit/hwintrinsic.cpp | 4 +-- src/coreclr/jit/hwintrinsicarm64.cpp | 6 +++- src/coreclr/jit/hwintrinsicxarch.cpp | 42 ++++++++++++++++++++-------- 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ef7a92321e7fc..1f2ef2c3a3d11 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3999,7 +3999,7 @@ class Compiler CORINFO_CLASS_HANDLE argClass, bool expectAddr = false, GenTree* newobjThis = nullptr); - GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType); + GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType, bool mustExpand); GenTree* addRangeCheckIfNeeded( NamedIntrinsic intrinsic, GenTree* immOp, bool mustExpand, int immLowerBound, int immUpperBound); GenTree* addRangeCheckForHWIntrinsic(GenTree* immOp, int immLowerBound, int immUpperBound); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 269ec70ae079a..3f9b8c22c2301 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -24159,6 +24159,21 @@ GenTree* Compiler::gtNewSimdSumNode(var_types type, GenTree* op1, CorInfoType si } #if defined(TARGET_XARCH) +//---------------------------------------------------------------------------------------------- +// Compiler::gtNewSimdTernaryLogicNode: Creates a new simd TernaryLogic node +// +// Arguments: +// type - The return type of SIMD node being created +// op1 - The value of the first operand: 'A' +// op2 - The value of the second operand: 'B' +// op3 - The value of the third operand: 'C' +// op4 - The constant control byte used to determine how 'A', 'B', and 'C' are manipulated +// simdBaseJitType - The base JIT type of SIMD type of the intrinsic +// simdSize - The size of the SIMD type of the intrinsic +// +// Returns: +// The created TernaryLogic node that performs the specified operation on 'A', 'B', and 'C'. +// GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type, GenTree* op1, GenTree* op2, diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 4fcbda8f30d57..f4f5d7b20c2ff 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1160,7 +1160,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, if (!immOp2->IsCnsIntOrI()) { assert(HWIntrinsicInfo::NoJmpTableImm(intrinsic)); - return impNonConstFallback(intrinsic, retType, simdBaseJitType); + return impNonConstFallback(intrinsic, retType, simdBaseJitType, mustExpand); } unsigned int otherSimdSize = 0; @@ -1269,7 +1269,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, { if (HWIntrinsicInfo::NoJmpTableImm(intrinsic)) { - return impNonConstFallback(intrinsic, retType, simdBaseJitType); + return impNonConstFallback(intrinsic, retType, simdBaseJitType, mustExpand); } else if (!mustExpand) { diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index b79c2de163c1b..b67fb5cbe6f15 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -277,11 +277,15 @@ void HWIntrinsicInfo::lookupImmBounds( // intrinsic -- intrinsic ID // simdType -- Vector type // simdBaseJitType -- base JIT type of the Vector64/128 +// mustExpand -- true if the intrinsict must be expanded; otherwise false // // Return Value: // return the IR of semantic alternative on non-const imm-arg // -GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType) +GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, + var_types simdType, + CorInfoType simdBaseJitType, + bool mustExpand) { return nullptr; } diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index ed6b6219161a4..5510d9314134b 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -561,11 +561,15 @@ bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa) // intrinsic -- intrinsic ID // simdType -- Vector type // simdBaseJitType -- SIMD base JIT type of the Vector128/256 +// mustExpand -- true if the intrinsict must be expanded; otherwise false // // Return Value: // return the IR of semantic alternative on non-const imm-arg // -GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType) +GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, + var_types simdType, + CorInfoType simdBaseJitType, + bool mustExpand) { assert(HWIntrinsicInfo::NoJmpTableImm(intrinsic)); switch (intrinsic) @@ -601,29 +605,43 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT case NI_AVX512F_VL_RotateLeft: case NI_AVX512F_VL_RotateRight: { - // These intrinsics have variants that take op2 in a simd register and read a unique shift per element - intrinsic = static_cast(intrinsic + 1); - - static_assert_no_msg(NI_AVX512F_RotateLeftVariable == (NI_AVX512F_RotateLeft + 1)); - static_assert_no_msg(NI_AVX512F_RotateRightVariable == (NI_AVX512F_RotateRight + 1)); - static_assert_no_msg(NI_AVX512F_VL_RotateLeftVariable == (NI_AVX512F_VL_RotateLeft + 1)); - static_assert_no_msg(NI_AVX512F_VL_RotateRightVariable == (NI_AVX512F_VL_RotateRight + 1)); + GenTree* op1; + GenTree* op2; var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); #if defined(TARGET_X86) if (varTypeIsLong(simdBaseType)) { - // TODO-XARCH-CQ: We need to add TYP_LONG support to gtNewSimdCreateBroadcastNode - return nullptr; + if (mustExpand) + { + op2 = impPopStack().val; + op1 = impSIMDPopStack(); + + return gtNewSimdHWIntrinsicNode(simdType, op1, op2, intrinsic, simdBaseJitType, + genTypeSize(simdType)); + } + else + { + // TODO-XARCH-CQ: We need to add TYP_LONG support to gtNewSimdCreateBroadcastNode + return nullptr; + } } #endif // TARGET_X86 + // These intrinsics have variants that take op2 in a simd register and read a unique shift per element + intrinsic = static_cast(intrinsic + 1); + + static_assert_no_msg(NI_AVX512F_RotateLeftVariable == (NI_AVX512F_RotateLeft + 1)); + static_assert_no_msg(NI_AVX512F_RotateRightVariable == (NI_AVX512F_RotateRight + 1)); + static_assert_no_msg(NI_AVX512F_VL_RotateLeftVariable == (NI_AVX512F_VL_RotateLeft + 1)); + static_assert_no_msg(NI_AVX512F_VL_RotateRightVariable == (NI_AVX512F_VL_RotateRight + 1)); + impSpillSideEffect(true, verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); - GenTree* op2 = impPopStack().val; - GenTree* op1 = impSIMDPopStack(); + op2 = impPopStack().val; + op1 = impSIMDPopStack(); if (varTypeIsLong(simdBaseType)) { From afccab8f2eb7132e8db711a20860b3d043ac57f2 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 20:50:53 -0700 Subject: [PATCH 19/21] Make sure all tests are actually running and handle the "maybe no jmp table fallback" --- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/hwintrinsic.cpp | 24 +++++++++++-- src/coreclr/jit/hwintrinsic.h | 10 ++++++ src/coreclr/jit/hwintrinsicarm64.cpp | 6 +--- src/coreclr/jit/hwintrinsiclistxarch.h | 8 ++--- src/coreclr/jit/hwintrinsicxarch.cpp | 34 +++---------------- .../GenerateHWIntrinsicTests_X86.cs | 3 +- 7 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 1f2ef2c3a3d11..ef7a92321e7fc 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3999,7 +3999,7 @@ class Compiler CORINFO_CLASS_HANDLE argClass, bool expectAddr = false, GenTree* newobjThis = nullptr); - GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType, bool mustExpand); + GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType); GenTree* addRangeCheckIfNeeded( NamedIntrinsic intrinsic, GenTree* immOp, bool mustExpand, int immLowerBound, int immUpperBound); GenTree* addRangeCheckForHWIntrinsic(GenTree* immOp, int immLowerBound, int immUpperBound); diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index f4f5d7b20c2ff..24ac9f7975c4c 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1160,7 +1160,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, if (!immOp2->IsCnsIntOrI()) { assert(HWIntrinsicInfo::NoJmpTableImm(intrinsic)); - return impNonConstFallback(intrinsic, retType, simdBaseJitType, mustExpand); + return impNonConstFallback(intrinsic, retType, simdBaseJitType); } unsigned int otherSimdSize = 0; @@ -1269,8 +1269,28 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, { if (HWIntrinsicInfo::NoJmpTableImm(intrinsic)) { - return impNonConstFallback(intrinsic, retType, simdBaseJitType, mustExpand); + return impNonConstFallback(intrinsic, retType, simdBaseJitType); } +#if defined(TARGET_XARCH) + else if (HWIntrinsicInfo::MaybeNoJmpTableImm(intrinsic)) + { +#if defined(TARGET_X86) + var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); + + if (varTypeIsLong(simdBaseType)) + { + if (!mustExpand) + { + return nullptr; + } + } + else +#endif // TARGET_XARCH + { + return impNonConstFallback(intrinsic, retType, simdBaseJitType); + } + } +#endif // TARGET_XARCH else if (!mustExpand) { // When the imm-argument is not a constant and we are not being forced to expand, we need to diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 402379fa3f748..b42cdd7305251 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -186,6 +186,10 @@ enum HWIntrinsicFlag : unsigned int HW_Flag_SpecialSideEffect_Other = 0x400000, HW_Flag_SpecialSideEffectMask = (HW_Flag_SpecialSideEffect_Barrier | HW_Flag_SpecialSideEffect_Other), + + // MaybeNoJmpTable IMM + // the imm intrinsic may not need jumptable fallback when it gets non-const argument + HW_Flag_MaybeNoJmpTableIMM = 0x800000, }; #if defined(TARGET_XARCH) @@ -973,6 +977,12 @@ struct HWIntrinsicInfo HWIntrinsicFlag flags = lookupFlags(id); return (flags & HW_Flag_SpecialSideEffect_Barrier) != 0; } + + static bool MaybeNoJmpTableImm(NamedIntrinsic id) + { + HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_MaybeNoJmpTableIMM) != 0; + } }; #ifdef TARGET_ARM64 diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index b67fb5cbe6f15..b79c2de163c1b 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -277,15 +277,11 @@ void HWIntrinsicInfo::lookupImmBounds( // intrinsic -- intrinsic ID // simdType -- Vector type // simdBaseJitType -- base JIT type of the Vector64/128 -// mustExpand -- true if the intrinsict must be expanded; otherwise false // // Return Value: // return the IR of semantic alternative on non-const imm-arg // -GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, - var_types simdType, - CorInfoType simdBaseJitType, - bool mustExpand) +GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType) { return nullptr; } diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index 75a6cb80135b2..403a341d5f53a 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -903,9 +903,9 @@ HARDWARE_INTRINSIC(AVX512F, Reciprocal14, HARDWARE_INTRINSIC(AVX512F, Reciprocal14Scalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ss, INS_vrcp14sd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) HARDWARE_INTRINSIC(AVX512F, ReciprocalSqrt14, 64, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ps, INS_vrsqrt14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, ReciprocalSqrt14Scalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ss, INS_vrsqrt14sd}, HW_Category_SimpleSIMD, HW_Flag_CopyUpperBits) -HARDWARE_INTRINSIC(AVX512F, RotateLeft, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprold, INS_vprold, INS_vprolq, INS_vprolq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, RotateLeft, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprold, INS_vprold, INS_vprolq, INS_vprolq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_MaybeNoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, RotateLeftVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprolvd, INS_vprolvd, INS_vprolvq, INS_vprolvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AVX512F, RotateRight, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprord, INS_vprord, INS_vprorq, INS_vprorq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F, RotateRight, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprord, INS_vprord, INS_vprorq, INS_vprorq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_MaybeNoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, RotateRightVariable, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprorvd, INS_vprorvd, INS_vprorvq, INS_vprorvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F, RoundScale, 64, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaleps, INS_vrndscalepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F, RoundScaleScalar, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaless, INS_vrndscalesd}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_CopyUpperBits) @@ -963,9 +963,9 @@ HARDWARE_INTRINSIC(AVX512F_VL, GetMantissa, HARDWARE_INTRINSIC(AVX512F_VL, PermuteVar4x64, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vpermq_reg, INS_vpermq_reg, INS_invalid, INS_vpermpd_reg}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport) HARDWARE_INTRINSIC(AVX512F_VL, Reciprocal14, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrcp14ps, INS_vrcp14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, ReciprocalSqrt14, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrsqrt14ps, INS_vrsqrt14pd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AVX512F_VL, RotateLeft, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprold, INS_vprold, INS_vprolq, INS_vprolq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, RotateLeft, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprold, INS_vprold, INS_vprolq, INS_vprolq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_MaybeNoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, RotateLeftVariable, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprolvd, INS_vprolvd, INS_vprolvq, INS_vprolvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) -HARDWARE_INTRINSIC(AVX512F_VL, RotateRight, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprord, INS_vprord, INS_vprorq, INS_vprorq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_NoJmpTableIMM|HW_Flag_FullRangeIMM) +HARDWARE_INTRINSIC(AVX512F_VL, RotateRight, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprord, INS_vprord, INS_vprorq, INS_vprorq, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_MaybeIMM|HW_Flag_MaybeNoJmpTableIMM|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, RotateRightVariable, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vprorvd, INS_vprorvd, INS_vprorvq, INS_vprorvq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX512F_VL, RoundScale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vrndscaleps, INS_vrndscalepd}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX512F_VL, Scale, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_vscalefps, INS_vscalefpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 5510d9314134b..6da6cd49b50c3 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -561,17 +561,13 @@ bool HWIntrinsicInfo::isScalarIsa(CORINFO_InstructionSet isa) // intrinsic -- intrinsic ID // simdType -- Vector type // simdBaseJitType -- SIMD base JIT type of the Vector128/256 -// mustExpand -- true if the intrinsict must be expanded; otherwise false // // Return Value: // return the IR of semantic alternative on non-const imm-arg // -GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, - var_types simdType, - CorInfoType simdBaseJitType, - bool mustExpand) +GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType) { - assert(HWIntrinsicInfo::NoJmpTableImm(intrinsic)); + assert(HWIntrinsicInfo::NoJmpTableImm(intrinsic) || HWIntrinsicInfo::MaybeNoJmpTableImm(intrinsic)); switch (intrinsic) { case NI_SSE2_ShiftLeftLogical: @@ -605,30 +601,8 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, case NI_AVX512F_VL_RotateLeft: case NI_AVX512F_VL_RotateRight: { - GenTree* op1; - GenTree* op2; - var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); -#if defined(TARGET_X86) - if (varTypeIsLong(simdBaseType)) - { - if (mustExpand) - { - op2 = impPopStack().val; - op1 = impSIMDPopStack(); - - return gtNewSimdHWIntrinsicNode(simdType, op1, op2, intrinsic, simdBaseJitType, - genTypeSize(simdType)); - } - else - { - // TODO-XARCH-CQ: We need to add TYP_LONG support to gtNewSimdCreateBroadcastNode - return nullptr; - } - } -#endif // TARGET_X86 - // These intrinsics have variants that take op2 in a simd register and read a unique shift per element intrinsic = static_cast(intrinsic + 1); @@ -640,8 +614,8 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, impSpillSideEffect(true, verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic")); - op2 = impPopStack().val; - op1 = impSIMDPopStack(); + GenTree* op2 = impPopStack().val; + GenTree* op1 = impSIMDPopStack(); if (varTypeIsLong(simdBaseType)) { diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index e99271f038858..bab558e617f97 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -2321,7 +2321,8 @@ bool isImmTemplate(string name) name == "ExtractScalarTest.template" || name == "InsertVector128Test.template" || name == "ExtractVector128Test.template" || name == "InsertLoadTest.template" || name == "ExtractStoreTest.template" || name == "ImmBinOpTest.template" || - name == "AesImmOpTest.template" || name == "PclmulqdqOpTest.template"; + name == "AesImmOpTest.template" || name == "PclmulqdqOpTest.template" || + name == "ImmTernOpTest.template"; } string projectName = args[0]; From 10c74fc56517e4583a922db6e44403dfc858b5ab Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Tue, 9 May 2023 22:11:05 -0700 Subject: [PATCH 20/21] Handle a couple test issues and ensure we set the constant when normalizing ~B | C --- src/coreclr/jit/hwintrinsicxarch.cpp | 41 +++++++++++++------ .../GenerateHWIntrinsicTests_X86.cs | 30 +++++++------- .../X86/Shared/ImmUnOpTest.template | 2 +- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index 6da6cd49b50c3..6655b027da525 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -3108,6 +3108,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, std::swap(val2, val3); // 1, 3, 2 + unusedVal1 = true; unusedVal2 = true; break; } @@ -3320,12 +3321,19 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (info.oper2 == TernaryLogicOperKind::And) { - assert((control == static_cast(~0xF0 & 0xCC)) || // ~A & B - (control == static_cast(~0xF0 & 0xAA)) || // ~A & C - (control == static_cast(~0xCC & 0xF0)) || // ~B & A - (control == static_cast(~0xCC & 0xAA)) || // ~B & C - (control == static_cast(~0xAA & 0xF0)) || // ~C & A - (control == static_cast(~0xAA & 0xCC))); // ~C & B + if ((control == static_cast(~0xCC & 0xF0)) || // ~B & A + (control == static_cast(~0xAA & 0xF0)) || // ~C & A + (control == static_cast(~0xAA & 0xCC))) // ~C & B + { + // We're normalizing to ~B & C, so we need another swap + std::swap(*val2, *val3); + } + else + { + assert((control == static_cast(~0xF0 & 0xCC)) || // ~A & B + (control == static_cast(~0xF0 & 0xAA)) || // ~A & C + (control == static_cast(~0xCC & 0xAA))); // ~B & C + } assert(unusedVal1); assert(!unusedVal2); @@ -3340,12 +3348,19 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { assert(info.oper2 == TernaryLogicOperKind::Or); - assert((control == static_cast(~0xF0 | 0xCC)) || // ~A | B - (control == static_cast(~0xF0 | 0xAA)) || // ~A | C - (control == static_cast(~0xCC | 0xF0)) || // ~B | A - (control == static_cast(~0xCC | 0xAA)) || // ~B | C - (control == static_cast(~0xAA | 0xF0)) || // ~C | A - (control == static_cast(~0xAA | 0xCC))); // ~C | B + if ((control == static_cast(~0xCC | 0xF0)) || // ~B | A + (control == static_cast(~0xAA | 0xF0)) || // ~C | A + (control == static_cast(~0xAA | 0xCC))) // ~C | B + { + // We're normalizing to ~B & C, so we need another swap + std::swap(*val2, *val3); + } + else + { + assert((control == static_cast(~0xF0 | 0xCC)) || // ~A | B + (control == static_cast(~0xF0 | 0xAA)) || // ~A | C + (control == static_cast(~0xCC | 0xAA))); // ~B | C + } assert(unusedVal1); assert(!unusedVal2); @@ -3355,6 +3370,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { *val1 = gtNewZeroConNode(retType); } + + op4->AsIntCon()->gtIconVal = static_cast(~0xCC | 0xAA); } break; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index bab558e617f97..8feecca46ad62 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1311,11 +1311,11 @@ ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "ReciprocalSqrt14Scalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "result[i] != firstOp[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] << 1) | (firstOp[i] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] << 1) | (firstOp[i] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}), @@ -1323,11 +1323,11 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "((firstOp[0] >>> 1) | (firstOp[0] << (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] >>> 1) | (firstOp[i] << (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] >>> 1) | (firstOp[0] << (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] >>> 1) | (firstOp[i] << (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(left[i], (int)(right[i])) != result[i]"}), @@ -1405,7 +1405,7 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* B */ ["Imm"] = "204", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op2[0]", ["ValidateRemainingResults"] = "result[i] != op2[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* C */ ["Imm"] = "170", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op3[0]", ["ValidateRemainingResults"] = "result[i] != op3[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* True */ ["Imm"] = "255", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != -1", ["ValidateRemainingResults"] = "result[i] != -1"}), - ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "255", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "0", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~A */ ["Imm"] = "15", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op1[0]", ["ValidateRemainingResults"] = "result[i] != ~op1[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~B */ ["Imm"] = "51", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op2[0]", ["ValidateRemainingResults"] = "result[i] != ~op2[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F", ["LoadIsa"] = "Avx512F", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector512", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector512", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector512", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector512", ["Op3BaseType"] = "Int32", /* ~C */ ["Imm"] = "85", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op3[0]", ["ValidateRemainingResults"] = "result[i] != ~op3[i]"}), @@ -1540,11 +1540,11 @@ ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] << 1) | (firstOp[i] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}), @@ -1552,11 +1552,11 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "((firstOp[0] >>> 1) | (firstOp[0] << (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] >>> 1) | (firstOp[i] << (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] >>> 1) | (firstOp[0] << (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] >>> 1) | (firstOp[i] << (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(left[i], (int)(right[i])) != result[i]"}), @@ -1585,7 +1585,7 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* B */ ["Imm"] = "204", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op2[0]", ["ValidateRemainingResults"] = "result[i] != op2[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* C */ ["Imm"] = "170", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op3[0]", ["ValidateRemainingResults"] = "result[i] != op3[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* True */ ["Imm"] = "255", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != -1", ["ValidateRemainingResults"] = "result[i] != -1"}), - ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "255", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "0", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~A */ ["Imm"] = "15", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op1[0]", ["ValidateRemainingResults"] = "result[i] != ~op1[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~B */ ["Imm"] = "51", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op2[0]", ["ValidateRemainingResults"] = "result[i] != ~op2[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Int32", /* ~C */ ["Imm"] = "85", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op3[0]", ["ValidateRemainingResults"] = "result[i] != ~op3[i]"}), @@ -1693,11 +1693,11 @@ ("SimpleUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "ReciprocalSqrt14", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "Avx512Verify.ValidateReciprocalSqrt14(result[0], firstOp[0])", ["ValidateRemainingResults"] = "Avx512Verify.ValidateReciprocalSqrt14(result[i], firstOp[i])"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] << 1) | (firstOp[i] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] << 1) | (firstOp[i] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}), @@ -1705,11 +1705,11 @@ ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt64() & 63)", ["ValidateFirstResult"] = "ulong.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "int.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "long.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "long.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "((firstOp[0] >>> 1) | (firstOp[0] << (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] >>> 1) | (firstOp[i] << (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "ulong.RotateRight(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "ulong.RotateRight(firstOp[i], 1) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] >>> 1) | (firstOp[0] << (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] >>> 1) | (firstOp[i] << (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRight", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateRight(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "RotateRightVariable", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateRight(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateRight(left[i], (int)(right[i])) != result[i]"}), @@ -1738,7 +1738,7 @@ ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* B */ ["Imm"] = "204", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op2[0]", ["ValidateRemainingResults"] = "result[i] != op2[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* C */ ["Imm"] = "170", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != op3[0]", ["ValidateRemainingResults"] = "result[i] != op3[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* True */ ["Imm"] = "255", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != -1", ["ValidateRemainingResults"] = "result[i] != -1"}), - ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "255", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), + ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* False */ ["Imm"] = "0", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 0"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~A */ ["Imm"] = "15", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op1[0]", ["ValidateRemainingResults"] = "result[i] != ~op1[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~B */ ["Imm"] = "51", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op2[0]", ["ValidateRemainingResults"] = "result[i] != ~op2[i]"}), ("ImmTernOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Avx", ["Method"] = "TernaryLogic", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector256", ["Op3BaseType"] = "Int32", /* ~C */ ["Imm"] = "85", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidateFirstResult"] = "result[0] != ~op3[0]", ["ValidateRemainingResults"] = "result[i] != ~op3[i]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template b/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template index 1b403ffcc0256..1356d7c99ca96 100644 --- a/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template +++ b/src/tests/JIT/HardwareIntrinsics/X86/Shared/ImmUnOpTest.template @@ -275,7 +275,7 @@ namespace JIT.HardwareIntrinsics.X86 if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}><9>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>.{Imm}): {method} failed:"); TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); TestLibrary.TestFramework.LogInformation(string.Empty); From e751e9c5d7cd39ff8ec7c6fa49a963eca4d88d72 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 10 May 2023 06:22:28 -0700 Subject: [PATCH 21/21] Ensure ValidateRemaining uses firstOp[i] --- .../GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs index 8feecca46ad62..912d89ab83ff1 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_X86.cs @@ -1544,7 +1544,7 @@ ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "uint.RotateLeft(firstOp[0], 1) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(firstOp[i], 1) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), - ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[i]"}), + ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "((firstOp[0] << 1) | (firstOp[0] >>> (64 - 1))) != result[0]", ["ValidateRemainingResults"] = "((firstOp[i] << 1) | (firstOp[i] >>> (64 - 1))) != result[i]"}), ("ImmUnOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeft", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "firstOp[i] != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "int.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "int.RotateLeft(left[i], (int)(right[i])) != result[i]"}), ("SimpleBinOpTest.template", new Dictionary { ["Isa"] = "Avx512F.VL", ["LoadIsa"] = "Sse2", ["Method"] = "RotateLeftVariable", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "(TestLibrary.Generator.GetUInt32() & 31)", ["ValidateFirstResult"] = "uint.RotateLeft(left[0], (int)(right[0])) != result[0]", ["ValidateRemainingResults"] = "uint.RotateLeft(left[i], (int)(right[i])) != result[i]"}),