summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2018-03-14 10:08:31 -0700
committerGitHub <noreply@github.com>2018-03-14 10:08:31 -0700
commit0ce9863ae18ce7af09599cfe052a9169a3f3c5a0 (patch)
treeff55b7221927d1a25a332f634117bee5fec1a1cd
parent23e144fa178fb2ed37da5801f7bb8ac2762aaf17 (diff)
parent71cccea772abbcf4a78124ab56962c18fc717c0e (diff)
downloadcoreclr-0ce9863ae18ce7af09599cfe052a9169a3f3c5a0.tar.gz
coreclr-0ce9863ae18ce7af09599cfe052a9169a3f3c5a0.tar.bz2
coreclr-0ce9863ae18ce7af09599cfe052a9169a3f3c5a0.zip
Merge pull request #16797 from dotnetrt/SetAllVector128_Managed
Managed implementation of SetAllVector128 SSE2 helper HW intrinsic
-rw-r--r--src/jit/hwintrinsiclistxarch.h1
-rw-r--r--src/jit/hwintrinsicxarch.cpp11
-rw-r--r--src/jit/namedintrinsiclist.h4
-rw-r--r--src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs195
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs301
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/TestTableSse2.cs23
9 files changed, 563 insertions, 79 deletions
diff --git a/src/jit/hwintrinsiclistxarch.h b/src/jit/hwintrinsiclistxarch.h
index 2a43cc46a9..88cfb97389 100644
--- a/src/jit/hwintrinsiclistxarch.h
+++ b/src/jit/hwintrinsiclistxarch.h
@@ -100,7 +100,6 @@ HARDWARE_INTRINSIC(SSE_Reciprocal, "Reciprocal
HARDWARE_INTRINSIC(SSE_ReciprocalScalar, "ReciprocalScalar", SSE, -1, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rcpss, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
HARDWARE_INTRINSIC(SSE_ReciprocalSqrt, "ReciprocalSqrt", SSE, -1, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rsqrtps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE_ReciprocalSqrtScalar, "ReciprocalSqrtScalar", SSE, -1, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_rsqrtss, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
-HARDWARE_INTRINSIC(SSE_SetAllVector128, "SetAllVector128", SSE, -1, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE_SetScalarVector128, "SetScalarVector128", SSE, -1, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_invalid}, HW_Category_Helper, HW_Flag_MultiIns|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE_SetZeroVector128, "SetZeroVector128", SSE, -1, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_xorps, INS_invalid}, HW_Category_Helper, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(SSE_Shuffle, "Shuffle", SSE, -1, 16, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_shufps, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM)
diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp
index 869361770c..fd228d71fc 100644
--- a/src/jit/hwintrinsicxarch.cpp
+++ b/src/jit/hwintrinsicxarch.cpp
@@ -124,7 +124,7 @@ InstructionSet Compiler::lookupHWIntrinsicISA(const char* className)
// isa -- instruction set of the intrinsic.
//
// Return Value:
-// Id for the hardware intrinsic.
+// Id for the hardware intrinsic
//
// TODO-Throughput: replace sequential search by binary search
NamedIntrinsic Compiler::lookupHWIntrinsic(const char* methodName, InstructionSet isa)
@@ -137,6 +137,7 @@ NamedIntrinsic Compiler::lookupHWIntrinsic(const char* methodName, InstructionSe
if (isa == hwIntrinsicInfoArray[i].isa && strcmp(methodName, hwIntrinsicInfoArray[i].intrinsicName) == 0)
{
result = hwIntrinsicInfoArray[i].intrinsicID;
+ break;
}
}
}
@@ -929,14 +930,6 @@ GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_SSE_SetAllVector128:
- assert(sig->numArgs == 1);
- assert(getBaseTypeOfSIMDType(sig->retTypeSigClass) == TYP_FLOAT);
- op1 = impPopStack().val;
- retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op1, gtCloneExpr(op1), gtNewIconNode(0), NI_SSE_Shuffle,
- TYP_FLOAT, simdSize);
- break;
-
case NI_SSE_StoreFence:
assert(sig->numArgs == 0);
assert(JITtype2varType(sig->retType) == TYP_VOID);
diff --git a/src/jit/namedintrinsiclist.h b/src/jit/namedintrinsiclist.h
index 91c9720580..f4d7cb2a88 100644
--- a/src/jit/namedintrinsiclist.h
+++ b/src/jit/namedintrinsiclist.h
@@ -27,8 +27,8 @@ enum NamedIntrinsic : unsigned int
#define HARDWARE_INTRINSIC(id, isa, name, form, ins0, ins1, ins2, flags) id,
#include "hwintrinsiclistArm64.h"
#endif // !defined(_TARGET_XARCH_) && !defined(_TARGET_ARM64_)
- NI_HW_INTRINSIC_END
-#endif
+ NI_HW_INTRINSIC_END,
+#endif // FEATURE_HW_INTRINSICS
};
#if defined(FEATURE_HW_INTRINSICS) && defined(_TARGET_XARCH_)
diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs
index f07bf4ac99..ecece0bd0a 100644
--- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs
+++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace System.Runtime.Intrinsics.X86
@@ -465,6 +466,25 @@ namespace System.Runtime.Intrinsics.X86
public static Vector128<float> ReciprocalSqrtScalar(Vector128<float> upper, Vector128<float> value) => ReciprocalSqrtScalar(upper, value);
/// <summary>
+ /// __m128 _mm_set1_ps (float a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<float> SetAllVector128(float value)
+ {
+ // Zero vector and load value et index 0
+ Vector128<float> vector = SetScalarVector128(value);
+ // Create { vl vl vl vl } and return result
+ return Shuffle(vector, vector, 0);
+ }
+
+ /// <summary>
+ /// __m128 _mm_set_ss (float a)
+ /// HELPER
+ /// </summary>
+ public static Vector128<float> SetScalarVector128(float value) => SetScalarVector128(value);
+
+ /// <summary>
/// __m128 _mm_set_ps (float e3, float e2, float e1, float e0)
/// </summary>
public static unsafe Vector128<float> SetVector128(float e3, float e2, float e1, float e0)
@@ -485,18 +505,6 @@ namespace System.Runtime.Intrinsics.X86
}
/// <summary>
- /// __m128 _mm_set_ss (float a)
- /// HELPER
- /// </summary>
- public static Vector128<float> SetScalarVector128(float value) => SetScalarVector128(value);
-
- /// <summary>
- /// __m128 _mm_set1_ps (float a)
- /// HELPER
- /// </summary>
- public static Vector128<float> SetAllVector128(float value) => SetAllVector128(value);
-
- /// <summary>
/// __m128d _mm_setzero_ps (void)
/// HELPER - XORPS
/// </summary>
diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs
index 23d8c93493..d0eb9ef4da 100644
--- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs
+++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs
@@ -969,6 +969,149 @@ namespace System.Runtime.Intrinsics.X86
public static Vector128<byte> PackUnsignedSaturate(Vector128<short> left, Vector128<short> right) => PackUnsignedSaturate(left, right);
/// <summary>
+ /// __m128i _mm_set1_epi8 (char a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<byte> SetAllVector128(byte value)
+ {
+ // Zero vector and load value et index 0
+ Vector128<byte> vector1 = Sse.StaticCast<uint, byte>(ConvertScalarToVector128UInt32(value));
+ // Create { -- -- -- -- -- -- -- -- -- -- -- -- -- -- vl vl }
+ Vector128<ushort> tmpVector1 = Sse.StaticCast<byte, ushort>(UnpackLow(vector1, vector1));
+ // Create { -- -- -- -- -- -- -- -- -- -- -- -- vl vl vl vl }
+ Vector128<uint> tmpVector2 = Sse.StaticCast<ushort, uint>(UnpackLow(tmpVector1, tmpVector1));
+ // Create { vl vl vl vl vl vl vl vl vl vl vl vl vl vl vl vl } and return result
+ return Sse.StaticCast<uint, byte>(Shuffle(tmpVector2, 0));
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi8 (char a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<sbyte> SetAllVector128(sbyte value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<sbyte> vector = Sse.StaticCast<int, sbyte>(ConvertScalarToVector128Int32(value));
+ // Create { -- -- -- -- -- -- -- -- -- -- -- -- -- -- vl vl }
+ Vector128<short> tmpVector1 = Sse.StaticCast<sbyte, short>(UnpackLow(vector, vector));
+ // Create { -- -- -- -- -- -- -- -- -- -- -- -- vl vl vl vl }
+ Vector128<int> tmpVector2 = Sse.StaticCast<short, int>(UnpackLow(tmpVector1, tmpVector1));
+ // Create { vl vl vl vl vl vl vl vl vl vl vl vl vl vl vl vl } and return result
+ return Sse.StaticCast<int, sbyte>(Shuffle(tmpVector2, 0));
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi16 (short a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<short> SetAllVector128(short value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<short> vector = Sse.StaticCast<int, short>(ConvertScalarToVector128Int32(value));
+ // Create { -- -- -- -- -- -- vl vl }
+ Vector128<int> tmpVector = Sse.StaticCast<short, int>(UnpackLow(vector, vector));
+ // Create { vl vl vl vl vl vl vl vl } and return result
+ return Sse.StaticCast<int, short>(Shuffle(tmpVector, (byte)0));
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi16 (short a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<ushort> SetAllVector128(ushort value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<ushort> vector = Sse.StaticCast<uint, ushort>(ConvertScalarToVector128UInt32(value));
+ // Create { -- -- -- -- -- -- vl vl }
+ Vector128<uint> tmpVector = Sse.StaticCast<ushort, uint>(UnpackLow(vector, vector));
+ // Create { vl vl vl vl vl vl vl vl } and return result
+ return Sse.StaticCast<uint, ushort>(Shuffle(tmpVector, (byte)0));
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi32 (int a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<int> SetAllVector128(int value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<int> vector = ConvertScalarToVector128Int32(value);
+ // Create { vl vl vl vl } and return result
+ return Shuffle(vector, 0);
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi32 (int a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<uint> SetAllVector128(uint value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<uint> vector = ConvertScalarToVector128UInt32(value);
+ // Create { vl vl vl vl } and return result
+ return Shuffle(vector, 0);
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi64x (long long a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<long> SetAllVector128(long value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<long> vector = ConvertScalarToVector128Int64(value);
+ // Create { vl vl } and return result
+ return UnpackLow(vector, vector);
+ }
+ /// <summary>
+ /// __m128i _mm_set1_epi64x (long long a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<ulong> SetAllVector128(ulong value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<ulong> vector = ConvertScalarToVector128UInt64(value);
+ // Create { vl vl } and return result
+ return UnpackLow(vector, vector);
+ }
+ /// <summary>
+ /// __m128d _mm_set1_pd (double a)
+ /// HELPER
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector128<double> SetAllVector128(double value)
+ {
+ // TODO-CQ Optimize algorithm choice based on benchmarks
+
+ // Zero vector and load value et index 0
+ Vector128<double> vector = SetScalarVector128(value);
+ // Create { vl vl } and return result
+ return UnpackLow(vector, vector);
+ }
+
+ /// <summary>
+ /// __m128d _mm_set_sd (double a)
+ /// HELPER
+ /// </summary>
+ public static Vector128<double> SetScalarVector128(double value) => SetScalarVector128(value);
+
+ /// <summary>
/// ___m128i _mm_set_epi8 (char e15, char e14, char e13, char e12, char e11, char e10, char e9, char e8, char e7, char e6, char e5, char e4, char e3, char e2, char e1, char e0)
/// HELPER
/// </summary>
@@ -1159,58 +1302,6 @@ namespace System.Runtime.Intrinsics.X86
}
/// <summary>
- /// __m128d _mm_set_sd (double a)
- /// HELPER
- /// </summary>
- public static Vector128<double> SetScalarVector128(double value) => SetScalarVector128(value);
-
- /// <summary>
- /// __m128i _mm_set1_epi8 (char a)
- /// HELPER
- /// </summary>
- public static Vector128<byte> SetAllVector128(byte value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi8 (char a)
- /// HELPER
- /// </summary>
- public static Vector128<sbyte> SetAllVector128(sbyte value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi16 (short a)
- /// HELPER
- /// </summary>
- public static Vector128<short> SetAllVector128(short value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi16 (short a)
- /// HELPER
- /// </summary>
- public static Vector128<ushort> SetAllVector128(ushort value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi32 (int a)
- /// HELPER
- /// </summary>
- public static Vector128<int> SetAllVector128(int value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi32 (int a)
- /// HELPER
- /// </summary>
- public static Vector128<uint> SetAllVector128(uint value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi64x (long long a)
- /// HELPER
- /// </summary>
- public static Vector128<long> SetAllVector128(long value) => SetAllVector128(value);
- /// <summary>
- /// __m128i _mm_set1_epi64x (long long a)
- /// HELPER
- /// </summary>
- public static Vector128<ulong> SetAllVector128(ulong value) => SetAllVector128(value);
- /// <summary>
- /// __m128d _mm_set1_pd (double a)
- /// HELPER
- /// </summary>
- public static Vector128<double> SetAllVector128(double value) => SetAllVector128(value);
-
- /// <summary>
/// __m128i _mm_setzero_si128 ()
/// HELPER: PXOR
/// __m128d _mm_setzero_pd (void)
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs
new file mode 100644
index 0000000000..d379720ddf
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs
@@ -0,0 +1,301 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+using System;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace IntelHardwareIntrinsicTest
+{
+ internal static partial class Program
+ {
+ private const int Pass = 100;
+ private const int Fail = 0;
+
+ static unsafe int Main(string[] args)
+ {
+ int testResult = Pass;
+ int testsCount = 21;
+ string methodUnderTestName = nameof(Sse2.SetAllVector128);
+
+ if (Sse2.IsSupported)
+ {
+ using (var doubleTable = TestTableSse2<double>.Create(testsCount))
+ using (var longTable = TestTableSse2<long>.Create(testsCount))
+ using (var ulongTable = TestTableSse2<ulong>.Create(testsCount))
+ using (var intTable = TestTableSse2<int>.Create(testsCount))
+ using (var uintTable = TestTableSse2<uint>.Create(testsCount))
+ using (var shortTable = TestTableSse2<short>.Create(testsCount))
+ using (var ushortTable = TestTableSse2<ushort>.Create(testsCount))
+ using (var sbyteTable = TestTableSse2<sbyte>.Create(testsCount))
+ using (var byteTable = TestTableSse2<byte>.Create(testsCount))
+ {
+ for (double i = 0; i < testsCount; i += 1)
+ {
+ Vector128<double> result = Sse2.SetAllVector128(i);
+ doubleTable.SetOutArray(result, (int)i);
+ }
+
+ if (Environment.Is64BitProcess)
+ {
+ for (long i = 0; i < testsCount; i++)
+ {
+ Vector128<long> result = Sse2.SetAllVector128(i);
+ longTable.SetOutArray(result, (int)i);
+ }
+
+ for (ulong i = 0; i < (ulong)testsCount; i++)
+ {
+ Vector128<ulong> result = Sse2.SetAllVector128(i);
+ ulongTable.SetOutArray(result, (int)i);
+ }
+ }
+ else
+ {
+ try
+ {
+ var vd = Sse2.SetAllVector128((long)0xffffl);
+ testResult = Fail;
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)} failed for long: expected PlatformNotSupportedException exception.");
+ }
+ catch (PlatformNotSupportedException)
+ {
+
+ }
+
+ try
+ {
+ var vd = Sse2.SetAllVector128((ulong)0xfffful);
+ testResult = Fail;
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)} failed for ulong: expected PlatformNotSupportedException exception.");
+ }
+ catch (PlatformNotSupportedException)
+ {
+
+ }
+ }
+
+
+
+ for (int i = 0; i < testsCount; i++)
+ {
+ Vector128<int> result = Sse2.SetAllVector128((int)i);
+ intTable.SetOutArray(result, i);
+ }
+
+ for (uint i = 0; i < testsCount; i++)
+ {
+ Vector128<uint> result = Sse2.SetAllVector128(i);
+ uintTable.SetOutArray(result, (int)i);
+ }
+
+ for (int i = 0; i < testsCount; i++)
+ {
+ Vector128<short> result = Sse2.SetAllVector128((short)i);
+ shortTable.SetOutArray(result, i);
+ }
+
+ for (int i = 0; i < testsCount; i++)
+ {
+ Vector128<ushort> result = Sse2.SetAllVector128((ushort)i);
+ ushortTable.SetOutArray(result, i);
+ }
+
+ for (int i = 0; i < testsCount; i++)
+ {
+ Vector128<sbyte> result = Sse2.SetAllVector128((sbyte)i);
+ sbyteTable.SetOutArray(result, i);
+ }
+
+ for (int i = 0; i < testsCount; i++)
+ {
+ Vector128<byte> result = Sse2.SetAllVector128((byte)i);
+ byteTable.SetOutArray(result, i);
+ }
+
+ double doubleCounter = 0.0;
+ CheckMethodSpan<double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != doubleCounter)
+ result = false;
+ }
+ doubleCounter += 1;
+ return result;
+ };
+
+ if (!doubleTable.CheckResult(checkDouble))
+ {
+ PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseXor(x, y)) == z", checkDouble);
+ testResult = Fail;
+ }
+
+ if (Environment.Is64BitProcess)
+ {
+ long longCounter = 0;
+ CheckMethodSpan<long> checkInt64 = (Span<long> x, Span<long> y, Span<long> z, Span<long> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != longCounter)
+ result = false;
+ }
+ longCounter++;
+ return result;
+ };
+
+ if (!longTable.CheckResult(checkInt64))
+ {
+ PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x ^ y) == z", checkInt64);
+ testResult = Fail;
+ }
+
+ ulong ulongCounter = 0;
+ CheckMethodSpan<ulong> checkUInt64 = (Span<ulong> x, Span<ulong> y, Span<ulong> z, Span<ulong> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != ulongCounter)
+ result = false;
+ }
+ ulongCounter++;
+ return result;
+ };
+
+ if (!ulongTable.CheckResult(checkUInt64))
+ {
+ PrintError(ulongTable, methodUnderTestName, "(Span<ulong> x, Span<ulong> y, Span<ulong> z, Span<ulong> a) => SetAllVector128", checkUInt64);
+ testResult = Fail;
+ }
+ }
+
+ int intCounter = 0;
+ CheckMethodSpan<int> checkInt32 = (Span<int> x, Span<int> y, Span<int> z, Span<int> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != intCounter)
+ result = false;
+ }
+ intCounter++;
+ return result;
+ };
+
+ if (!intTable.CheckResult(checkInt32))
+ {
+ PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x ^ y) == z", checkInt32);
+ testResult = Fail;
+ }
+
+ uint uintCounter = 0;
+ CheckMethodSpan<uint> checkUInt32 = (Span<uint> x, Span<uint> y, Span<uint> z, Span<uint> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != uintCounter)
+ result = false;
+ }
+ uintCounter++;
+ return result;
+ };
+
+ if (!uintTable.CheckResult(checkUInt32))
+ {
+ PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x ^ y) == z", checkUInt32);
+ testResult = Fail;
+ }
+
+ int shortCounter = 0;
+ CheckMethodSpan<short> checkInt16 = (Span<short> x, Span<short> y, Span<short> z, Span<short> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != shortCounter)
+ result = false;
+ }
+ shortCounter++;
+ return result;
+ };
+
+ if (!shortTable.CheckResult(checkInt16))
+ {
+ PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x ^ y)) == z", checkInt16);
+ testResult = Fail;
+ }
+
+ int ushortCounter = 0;
+ CheckMethodSpan<ushort> checkUInt16 = (Span<ushort> x, Span<ushort> y, Span<ushort> z, Span<ushort> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != ushortCounter)
+ result = false;
+ }
+ ushortCounter++;
+ return result;
+ };
+
+ if (!ushortTable.CheckResult(checkUInt16))
+ {
+ PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x ^ y)) == z", checkUInt16);
+ testResult = Fail;
+ }
+
+ int sbyteCounter = 0;
+ CheckMethodSpan<sbyte> checkSByte = (Span<sbyte> x, Span<sbyte> y, Span<sbyte> z, Span<sbyte> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < z.Length; i++)
+ {
+ if (z[i] != sbyteCounter)
+ result = false;
+ }
+ sbyteCounter++;
+ return result;
+ };
+
+ if (!sbyteTable.CheckResult(checkSByte))
+ {
+ PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x ^ y)) == z", checkSByte);
+ testResult = Fail;
+ }
+
+ int byteCounter = 0;
+ CheckMethodSpan<byte> checkByte = (Span<byte> x, Span<byte> y, Span<byte> z, Span<byte> a) =>
+ {
+ bool result = true;
+ for (int i = 0; i < x.Length; i++)
+ {
+ if (z[i] != byteCounter)
+ result = false;
+ }
+ byteCounter++;
+ return result;
+ };
+
+ if (!byteTable.CheckResult(checkByte))
+ {
+ PrintError(byteTable, methodUnderTestName, "(byte x, byte y, byte z, ref byte a) => (a = (byte)(x ^ y)) == z", checkByte);
+ testResult = Fail;
+ }
+ }
+ }
+ else
+ {
+ Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
+ }
+
+ return testResult;
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj
new file mode 100644
index 0000000000..8ff187b439
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{8156C540-D3A7-4B4A-B513-3C638EC9088A}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>
+ </Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SetAllVector128.cs" />
+ <Compile Include="TestTableSse2.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj
new file mode 100644
index 0000000000..f63ed35b08
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4A5D16DC-6AFD-4BCC-929F-08EFDF76298E}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SetAllVector128.cs" />
+ <Compile Include="TestTableSse2.cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/TestTableSse2.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/TestTableSse2.cs
index ffba0a0613..23a63db28b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/TestTableSse2.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/TestTableSse2.cs
@@ -95,6 +95,7 @@ namespace IntelHardwareIntrinsicTest
{
private const int _stepSize = 16;
private int _scalarStepSize;
+ private int _lengthInVectors;
public static int ElementCount;
private GCHandle _inHandle1;
@@ -117,12 +118,27 @@ namespace IntelHardwareIntrinsicTest
public Vector128<T> Vector1 => Unsafe.Read<Vector128<T>>((byte*)InArray1Ptr + (_index * _stepSize));
public Vector128<T> Vector2 => Unsafe.Read<Vector128<T>>((byte*)InArray2Ptr + (_index * _stepSize));
public Vector128<T> Vector3 => Unsafe.Read<Vector128<T>>((byte*)OutArrayPtr + (_index * _stepSize));
- public int Index { get => _index; set => _index = value; }
+
+ public int Index
+ {
+ get => _index;
+ set
+ {
+ if (value < 0 || value >= _lengthInVectors)
+ {
+ throw new IndexOutOfRangeException();
+ }
+ else
+ {
+ _index = value;
+ }
+ }
+ }
public void SetOutArray(Vector128<T> value, int index = -1)
{
- index = index < 0 ? _index : index;
- Unsafe.Write((byte*)OutArrayPtr + (index * _stepSize), value);
+ Index = index < 0 ? Index : index;
+ Unsafe.Write((byte*)OutArrayPtr + (Index * _stepSize), value);
}
public void SetOutArray(bool value1, Vector128<T> value2, int index = -1)
@@ -164,6 +180,7 @@ namespace IntelHardwareIntrinsicTest
public TestTableSse2(int lengthInVectors)
{
_scalarStepSize = Marshal.SizeOf<T>();
+ _lengthInVectors = lengthInVectors;
ElementCount = _stepSize / _scalarStepSize;
int length = ElementCount * lengthInVectors;
inArray1 = new T[length];