summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2018-02-03 14:32:27 -0800
committerTanner Gooding <tagoo@outlook.com>2018-02-05 17:23:26 -0800
commit4578505a521bb4cbcf16d2361d87d24a9cacd25f (patch)
tree9ad895d95aafb1f7875a741ac7a9af4227e3f4f5
parent691c7a0b0f1941a6186f4dbc1a04ccbc98d74c33 (diff)
downloadcoreclr-4578505a521bb4cbcf16d2361d87d24a9cacd25f.tar.gz
coreclr-4578505a521bb4cbcf16d2361d87d24a9cacd25f.tar.bz2
coreclr-4578505a521bb4cbcf16d2361d87d24a9cacd25f.zip
Moving a number of the Sse2 hwintrinsic tests to use the test template.
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx99
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs137
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.cs187
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.cs187
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_r.csproj41
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.cs150
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.cs105
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.cs104
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.cs56
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.cs62
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.cs62
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.cs51
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.cs83
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.cs83
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.cs16
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.cs187
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs77
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj81
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj81
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.cs179
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs315
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.cs187
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_ro.csproj37
152 files changed, 25955 insertions, 3718 deletions
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
index 5848273cc3..60bf0604c7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
@@ -77,16 +77,93 @@ private static readonly (string templateFileName, string[] templateData)[] SseIn
private static readonly (string templateFileName, string[] templateData)[] Sse2Inputs = new []
{
- // TemplateName Isa, LoadIsa, Method, BaseType, VectorType, VectorSize, NextValue, ValidateFirstResult, ValidateRemainingResults
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] + right[0]) != result[0]", "(byte)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] + right[0]) != result[0]", "(short)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] + right[0]) != result[0]", "(int)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] + right[0]) != result[0]", "(long)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] + right[0]) != result[0]", "(sbyte)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] + right[0]) != result[0]", "(ushort)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] + right[0]) != result[0]", "(uint)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] + right[0]) != result[0]", "(ulong)(left[i] + right[i]) != result[i]"}),
+ // TemplateName Isa, LoadIsa, Method, BaseType, VectorType, VectorSize, NextValue, ValidateFirstResult, ValidateRemainingResults
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] + right[0]) != result[0]", "(byte)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] + right[0]) != result[0]", "(short)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] + right[0]) != result[0]", "(int)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] + right[0]) != result[0]", "(long)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] + right[0]) != result[0]", "(sbyte)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] + right[0]) != result[0]", "(ushort)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] + right[0]) != result[0]", "(uint)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Add", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] + right[0]) != result[0]", "(ulong)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "Double", "Vector128", "16", "(double)(random.NextDouble())", "(BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])", "(BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] & right[0]) != result[0]", "(byte)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] & right[0]) != result[0]", "(short)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] & right[0]) != result[0]", "(int)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] & right[0]) != result[0]", "(long)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] & right[0]) != result[0]", "(sbyte)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] & right[0]) != result[0]", "(ushort)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] & right[0]) != result[0]", "(uint)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "And", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] & right[0]) != result[0]", "(ulong)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "Double", "Vector128", "16", "(double)(random.NextDouble())", "(~BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])", "(~BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(~left[0] & right[0]) != result[0]", "(byte)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(~left[0] & right[0]) != result[0]", "(short)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(~left[0] & right[0]) != result[0]", "(int)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(~left[0] & right[0]) != result[0]", "(long)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(~left[0] & right[0]) != result[0]", "(sbyte)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(~left[0] & right[0]) != result[0]", "(ushort)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(~left[0] & right[0]) != result[0]", "(uint)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "AndNot", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(~left[0] & right[0]) != result[0]", "(ulong)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] == right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "result[0] != ((left[0] == right[0]) ? unchecked((byte)(-1)) : 0)", "result[i] != ((left[i] == right[i]) ? unchecked((byte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "result[0] != ((left[0] == right[0]) ? unchecked((short)(-1)) : 0)", "result[i] != ((left[i] == right[i]) ? unchecked((short)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "result[0] != ((left[0] == right[0]) ? unchecked((int)(-1)) : 0)", "result[i] != ((left[i] == right[i]) ? unchecked((int)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "result[0] != ((left[0] == right[0]) ? unchecked((sbyte)(-1)) : 0)", "result[i] != ((left[i] == right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "result[0] != ((left[0] == right[0]) ? unchecked((ushort)(-1)) : 0)", "result[i] != ((left[i] == right[i]) ? unchecked((ushort)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareEqual", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "result[0] != ((left[0] == right[0]) ? unchecked((uint)(-1)) : 0)", "result[i] != ((left[i] == right[i]) ? unchecked((uint)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareGreaterThan", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] > right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareGreaterThan", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "result[0] != ((left[0] > right[0]) ? unchecked((short)(-1)) : 0)", "result[i] != ((left[i] > right[i]) ? unchecked((short)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareGreaterThan", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "result[0] != ((left[0] > right[0]) ? unchecked((int)(-1)) : 0)", "result[i] != ((left[i] > right[i]) ? unchecked((int)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareGreaterThan", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "result[0] != ((left[0] > right[0]) ? unchecked((sbyte)(-1)) : 0)", "result[i] != ((left[i] > right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareGreaterThanOrEqual", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] >= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareLessThan", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] < right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareLessThan", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "result[0] != ((left[0] < right[0]) ? unchecked((short)(-1)) : 0)", "result[i] != ((left[i] < right[i]) ? unchecked((short)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareLessThan", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "result[0] != ((left[0] < right[0]) ? unchecked((int)(-1)) : 0)", "result[i] != ((left[i] < right[i]) ? unchecked((int)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareLessThan", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "result[0] != ((left[0] < right[0]) ? unchecked((sbyte)(-1)) : 0)", "result[i] != ((left[i] < right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareLessThanOrEqual", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] <= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareNotEqual", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] != right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareNotGreaterThan", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] > right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareNotGreaterThanOrEqual", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] >= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareNotLessThan", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] < right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareNotLessThanOrEqual", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] <= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareOrdered", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((!double.IsNaN(left[0]) && !double.IsNaN(right[0])) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((!double.IsNaN(left[i]) && !double.IsNaN(right[i])) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "CompareUnordered", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(result[0]) != ((double.IsNaN(left[0]) || double.IsNaN(right[0])) ? -1 : 0)", "BitConverter.DoubleToInt64Bits(result[i]) != ((double.IsNaN(left[i]) || double.IsNaN(right[i])) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Divide", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(left[i] / right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Max", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(Math.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(Math.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Max", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "Math.Max(left[0], right[0]) != result[0]", "Math.Max(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Max", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "Math.Max(left[0], right[0]) != result[0]", "Math.Max(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Min", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(Math.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(Math.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Min", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MinValue))", "Math.Min(left[0], right[0]) != result[0]", "Math.Min(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Min", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MinValue))", "Math.Min(left[0], right[0]) != result[0]", "Math.Min(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Multiply", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(left[i] * right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "Double", "Vector128", "16", "(double)(random.NextDouble())", "(BitConverter.DoubleToInt64Bits(left[0]) | BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])", "(BitConverter.DoubleToInt64Bits(left[i]) | BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] | right[0]) != result[0]", "(byte)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] | right[0]) != result[0]", "(short)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] | right[0]) != result[0]", "(int)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] | right[0]) != result[0]", "(long)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] | right[0]) != result[0]", "(sbyte)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] | right[0]) != result[0]", "(ushort)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] | right[0]) != result[0]", "(uint)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Or", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] | right[0]) != result[0]", "(ulong)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "Double", "Vector128", "16", "(double)(random.NextDouble())", "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])", "BitConverter.DoubleToInt64Bits(left[i] - right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] - right[0]) != result[0]", "(byte)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] - right[0]) != result[0]", "(short)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] - right[0]) != result[0]", "(int)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] - right[0]) != result[0]", "(long)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] - right[0]) != result[0]", "(sbyte)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] - right[0]) != result[0]", "(ushort)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] - right[0]) != result[0]", "(uint)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Subtract", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] - right[0]) != result[0]", "(ulong)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Double", "Vector128", "16", "(double)(random.NextDouble())", "(BitConverter.DoubleToInt64Bits(left[0]) ^ BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])", "(BitConverter.DoubleToInt64Bits(left[i]) ^ BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Byte", "Vector128", "16", "(byte)(random.Next(0, byte.MaxValue))", "(byte)(left[0] ^ right[0]) != result[0]", "(byte)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Int16", "Vector128", "16", "(short)(random.Next(short.MinValue, short.MaxValue))", "(short)(left[0] ^ right[0]) != result[0]", "(short)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Int32", "Vector128", "16", "(int)(random.Next(int.MinValue, int.MaxValue))", "(int)(left[0] ^ right[0]) != result[0]", "(int)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "Int64", "Vector128", "16", "(long)(random.Next(int.MinValue, int.MaxValue))", "(long)(left[0] ^ right[0]) != result[0]", "(long)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "SByte", "Vector128", "16", "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", "(sbyte)(left[0] ^ right[0]) != result[0]", "(sbyte)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "UInt16", "Vector128", "16", "(ushort)(random.Next(0, ushort.MaxValue))", "(ushort)(left[0] ^ right[0]) != result[0]", "(ushort)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "UInt32", "Vector128", "16", "(uint)(random.Next(0, int.MaxValue))", "(uint)(left[0] ^ right[0]) != result[0]", "(uint)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new string[] { "Sse2", "Sse2", "Xor", "UInt64", "Vector128", "16", "(ulong)(random.Next(0, int.MaxValue))", "(ulong)(left[0] ^ right[0]) != result[0]", "(ulong)(left[i] ^ right[i]) != result[i]"}),
};
private static readonly (string templateFileName, string[] templateData)[] AvxInputs = new []
@@ -163,8 +240,8 @@ private static void ProcessInput(StreamWriter testListFile, (string templateFile
}
ProcessInputs("Sse", SseInputs);
+ProcessInputs("Sse2", Sse2Inputs);
// TODO-XArch: Re-enable after the Load and LoadAligned intrinsics are implemented for SSE2 and AVX
-// ProcessInputs("Sse2", Sse2Inputs);
// ProcessInputs("Avx", AvxInputs);
// ProcessInputs("Avx2", Avx2Inputs);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs
index 191101a046..fec58076dd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, Byte[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[ElementCount];
Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs
index 63eb9250a0..a6a2d771ee 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, Double[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[ElementCount];
Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs
index 78aae6eb43..a4e17a627f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, Int16[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[ElementCount];
Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs
index 9bd209494d..2b6916f82b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, Int32[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[ElementCount];
Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs
index 1d0e18e1fb..09812f4270 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, Int64[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[ElementCount];
Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs
index e496ae47e1..6db15f6a8f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, SByte[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[ElementCount];
SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs
index 549c99f219..b26b1dc64d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, UInt16[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[ElementCount];
UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs
index 7e94c2f133..753093a392 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, UInt32[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[ElementCount];
UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs
index efc23590cd..23ee721995 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs
@@ -25,17 +25,35 @@ namespace JIT.HardwareIntrinsics.X86
if (test.IsSupported)
{
- // Validates basic functionality works
- test.RunBasicScenario();
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
- // Validates calling via reflection works
- test.RunReflectionScenario();
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
// Validates passing a static member works
test.RunClsVarScenario();
- // Validates passing a local works
- test.RunLclVarScenario();
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
// Validates passing the field of a local works
test.RunLclFldScenario();
@@ -92,14 +110,14 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount]);
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount], VectorSize);
}
public bool IsSupported => Sse2.IsSupported;
public bool Succeeded { get; set; }
- public void RunBasicScenario()
+ public void RunBasicScenario_UnsafeRead()
{
var result = Sse2.Add(
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
@@ -107,10 +125,32 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Add(
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
- public void RunReflectionScenario()
+ public void RunReflectionScenario_UnsafeRead()
{
var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
@@ -119,7 +159,31 @@ namespace JIT.HardwareIntrinsics.X86
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
- ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Add), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -130,17 +194,37 @@ namespace JIT.HardwareIntrinsics.X86
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
- public void RunLclVarScenario()
+ public void RunLclVarScenario_UnsafeRead()
{
var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
var result = Sse2.Add(left, right);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArray);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
}
public void RunLclFldScenario()
@@ -149,7 +233,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunFldScenario()
@@ -157,7 +241,7 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse2.Add(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArray);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunUnsupportedScenario()
@@ -166,7 +250,7 @@ namespace JIT.HardwareIntrinsics.X86
try
{
- RunBasicScenario();
+ RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
@@ -174,15 +258,30 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, UInt64[] result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[ElementCount];
UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs
new file mode 100644
index 0000000000..9841e66e57
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndByte()
+ {
+ var test = new SimpleBinaryOpTest__AndByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__AndByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndByte();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs
new file mode 100644
index 0000000000..2f6f0d79c6
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndDouble()
+ {
+ var test = new SimpleBinaryOpTest__AndDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__AndDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndDouble();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if ((BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs
new file mode 100644
index 0000000000..d5c18eeaf5
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndInt16()
+ {
+ var test = new SimpleBinaryOpTest__AndInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__AndInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndInt16();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((short)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((short)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs
new file mode 100644
index 0000000000..f440ef540c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndInt32()
+ {
+ var test = new SimpleBinaryOpTest__AndInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__AndInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndInt32();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((int)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((int)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs
new file mode 100644
index 0000000000..f6c22b36de
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndInt64()
+ {
+ var test = new SimpleBinaryOpTest__AndInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[ElementCount];
+ private static Int64[] _data2 = new Int64[ElementCount];
+
+ private static Vector128<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector128<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+ static SimpleBinaryOpTest__AndInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndInt64();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((long)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((long)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<Int64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs
new file mode 100644
index 0000000000..6bef767cfb
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndSByte()
+ {
+ var test = new SimpleBinaryOpTest__AndSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__AndSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndSByte();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((sbyte)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((sbyte)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs
new file mode 100644
index 0000000000..550dd341f7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndUInt16()
+ {
+ var test = new SimpleBinaryOpTest__AndUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndUInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector128<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector128<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__AndUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndUInt16();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ushort)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs
new file mode 100644
index 0000000000..aa2329e740
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndUInt32()
+ {
+ var test = new SimpleBinaryOpTest__AndUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndUInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector128<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector128<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__AndUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndUInt32();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((uint)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((uint)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs
new file mode 100644
index 0000000000..dbfbbf68fc
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndUInt64()
+ {
+ var test = new SimpleBinaryOpTest__AndUInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndUInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[ElementCount];
+ private static UInt64[] _data2 = new UInt64[ElementCount];
+
+ private static Vector128<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector128<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__AndUInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndUInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.And(
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.And(
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.And(
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.And), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.And(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndUInt64();
+ var result = Sse2.And(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.And(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((ulong)(left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ulong)(left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.And)}<UInt64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.cs
deleted file mode 100644
index 2a54745135..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.And);
-
- 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 (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<long>, Vector128<long>, Vector128<long>) value = longTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- longTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ulong>, Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- ulongTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<uint>, Vector128<uint>, Vector128<uint>) value = uintTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- uintTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.And(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = BinaryAnd(x, y)) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BinaryAnd(x, y)) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<long> checkLong = (long x, long y, long z, ref long a) => (a = x & y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x & y) == z", checkLong);
- testResult = Fail;
- }
-
- CheckMethod<ulong> checkUlong = (ulong x, ulong y, ulong z, ref ulong a) => (a = x & y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(ulongTable, methodUnderTestName, "(ulong x, ulong y, ulong z, ref ulong a) => (a = x & y) == z", checkUlong);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x & y) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x & y) == z", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<uint> checkUInt32 = (uint x, uint y, uint z, ref uint a) => (a = x & y) == z;
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x & y) == z", checkUInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)(x & y)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x & y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x & y)) == z;
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x & y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x & y)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x & y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = (byte)(x & y)) == z;
-
- 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;
- }
-
- public static unsafe double BinaryAnd(double x, double y)
- {
- var xUlong = BitConverter.ToUInt64(BitConverter.GetBytes(x));
- var yUlong = BitConverter.ToUInt64(BitConverter.GetBytes(y));
- var longAnd = xUlong & yUlong;
- return BitConverter.ToDouble(BitConverter.GetBytes(longAnd));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs
new file mode 100644
index 0000000000..ae9c583b95
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotByte()
+ {
+ var test = new SimpleBinaryOpTest__AndNotByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotByte();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs
new file mode 100644
index 0000000000..9a072eebce
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotDouble()
+ {
+ var test = new SimpleBinaryOpTest__AndNotDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotDouble();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if ((~BitConverter.DoubleToInt64Bits(left[0]) & BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((~BitConverter.DoubleToInt64Bits(left[i]) & BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs
new file mode 100644
index 0000000000..695826926f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotInt16()
+ {
+ var test = new SimpleBinaryOpTest__AndNotInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotInt16();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((short)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((short)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs
new file mode 100644
index 0000000000..e381266bee
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotInt32()
+ {
+ var test = new SimpleBinaryOpTest__AndNotInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotInt32();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((int)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((int)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs
new file mode 100644
index 0000000000..652825cb3a
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotInt64()
+ {
+ var test = new SimpleBinaryOpTest__AndNotInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[ElementCount];
+ private static Int64[] _data2 = new Int64[ElementCount];
+
+ private static Vector128<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector128<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotInt64();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((long)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((long)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<Int64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs
new file mode 100644
index 0000000000..0082496555
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotSByte()
+ {
+ var test = new SimpleBinaryOpTest__AndNotSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotSByte();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((sbyte)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((sbyte)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs
new file mode 100644
index 0000000000..ab2ed5f277
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotUInt16()
+ {
+ var test = new SimpleBinaryOpTest__AndNotUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotUInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector128<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector128<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotUInt16();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ushort)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs
new file mode 100644
index 0000000000..6f87e8757e
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotUInt32()
+ {
+ var test = new SimpleBinaryOpTest__AndNotUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotUInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector128<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector128<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotUInt32();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((uint)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((uint)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs
new file mode 100644
index 0000000000..64d975b4f5
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void AndNotUInt64()
+ {
+ var test = new SimpleBinaryOpTest__AndNotUInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AndNotUInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[ElementCount];
+ private static UInt64[] _data2 = new UInt64[ElementCount];
+
+ private static Vector128<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector128<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__AndNotUInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AndNotUInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AndNot(
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AndNot(
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AndNot), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AndNot(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AndNotUInt64();
+ var result = Sse2.AndNot(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AndNot(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((ulong)(~left[0] & right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ulong)(~left[i] & right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AndNot)}<UInt64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.cs
deleted file mode 100644
index a757419f6f..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.AndNot);
-
- 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 (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<long>, Vector128<long>, Vector128<long>) value = longTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- longTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ulong>, Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- ulongTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<uint>, Vector128<uint>, Vector128<uint>) value = uintTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- uintTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.AndNot(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = BinaryAndNot(x, y)) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BinaryAndNot(x, y)) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<long> checkLong = (long x, long y, long z, ref long a) => (a = (~x) & y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = (~x) & y) == z", checkLong);
- testResult = Fail;
- }
-
- CheckMethod<ulong> checkUlong = (ulong x, ulong y, ulong z, ref ulong a) => (a = (~x) & y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(ulongTable, methodUnderTestName, "(ulong x, ulong y, ulong z, ref ulong a) => (a = (~x) & y) == z", checkUlong);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = (~x) & y) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = (~x) & y) == z", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<uint> checkUInt32 = (uint x, uint y, uint z, ref uint a) => (a = (~x) & y) == z;
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = (~x) & y) == z", checkUInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)((~x) & y)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)((~x) & y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)((~x) & y)) == z;
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)((~x) & y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)((~x) & y)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) =>(a = (sbyte)((~x) & y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = (byte)((~x) & y)) == z;
-
- 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;
- }
-
- public static double BinaryAndNot(double x, double y)
- {
- var xLong = BitConverter.ToInt64(BitConverter.GetBytes(x));
- var yLong = BitConverter.ToInt64(BitConverter.GetBytes(y));
- xLong = ((~xLong) & yLong);
- return BitConverter.ToDouble(BitConverter.GetBytes(xLong));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_r.csproj
deleted file mode 100644
index 0b2fce0a87..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_r.csproj
+++ /dev/null
@@ -1,41 +0,0 @@
-<?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>{1FEAE9EB-3D81-4367-8B88-91348178128D}</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>
- <PropertyGroup>
- <LangVersion>7.1</LangVersion>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AndNot.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/AndNot_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_ro.csproj
deleted file mode 100644
index 72b237b743..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{39F85E0C-902F-4426-B91D-5190B280A7F5}</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="AndNot.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/And_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And_r.csproj
deleted file mode 100644
index c5983931a8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</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="And.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/And_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And_ro.csproj
deleted file mode 100644
index 49cb64ba34..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{76498BB3-401E-45B1-8A11-818B392E2003}</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="And.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/CompareEqual.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs
new file mode 100644
index 0000000000..a97e76c268
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualByte()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualByte();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] == right[0]) ? unchecked((byte)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] == right[i]) ? unchecked((byte)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs
new file mode 100644
index 0000000000..8f2305cc5b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualDouble();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] == right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs
new file mode 100644
index 0000000000..567cecb4f7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualInt16()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualInt16();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] == right[0]) ? unchecked((short)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] == right[i]) ? unchecked((short)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs
new file mode 100644
index 0000000000..7844d3f4e8
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualInt32()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualInt32();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] == right[0]) ? unchecked((int)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] == right[i]) ? unchecked((int)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs
new file mode 100644
index 0000000000..55199d8902
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualSByte()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualSByte();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] == right[0]) ? unchecked((sbyte)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] == right[i]) ? unchecked((sbyte)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs
new file mode 100644
index 0000000000..a61d1dc218
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualUInt16()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector128<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector128<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualUInt16();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] == right[0]) ? unchecked((ushort)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] == right[i]) ? unchecked((ushort)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs
new file mode 100644
index 0000000000..e9c2db3767
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareEqualUInt32()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector128<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector128<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__CompareEqualUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareEqualUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareEqual(
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareEqual(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareEqual), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareEqualUInt32();
+ var result = Sse2.CompareEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] == right[0]) ? unchecked((uint)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] == right[i]) ? unchecked((uint)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareEqual)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.cs
deleted file mode 100644
index 45ac941fe0..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-// 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.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.CompareEqual);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.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 (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<uint>, Vector128<uint>, Vector128<uint>) value = uintTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- uintTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.CompareEqual(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = x == y ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x == y ? -1l : 0) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x == y ? -1 : 0) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x == y ? -1 : 0) == z);", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<uint> checkUInt32 = (uint x, uint y, uint z, ref uint a) => (a = x == y ? 0xffffffff : 0) == z;
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x == y ? 0xffffffff : 0) == z", checkUInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)(x == y ? -1 : 0)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x == y ? -1 : 0)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x == y ? 0xffff : 0)) == z;
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x == y ? 0xffff : 0)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte) (x == y ? -1 : 0)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte) (x == y ? -1 : 0) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = (byte)(x == y ? 0xff : 0)) == z;
-
- if (!byteTable.CheckResult(checkByte))
- {
- PrintError(byteTable, methodUnderTestName, "(byte x, byte y, byte z, ref byte a) => (a = (byte)(x == y ? 0xff : 0)) == 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/CompareEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual_r.csproj
deleted file mode 100644
index 8cde1ea422..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{EB82DD03-0CB7-41E2-8879-63C128833B6E}</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="CompareEqual.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/CompareEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual_ro.csproj
deleted file mode 100644
index 6b4082ff8e..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{81E414C4-4281-4C1F-BC30-EACDCD551D1D}</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="CompareEqual.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/CompareGreaterThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs
new file mode 100644
index 0000000000..bdc6052cf4
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareGreaterThanDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareGreaterThanDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareGreaterThanDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareGreaterThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanDouble();
+ var result = Sse2.CompareGreaterThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareGreaterThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] > right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThan)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs
new file mode 100644
index 0000000000..4f5f5e6292
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareGreaterThanInt16()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__CompareGreaterThanInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareGreaterThanInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareGreaterThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanInt16();
+ var result = Sse2.CompareGreaterThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareGreaterThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] > right[0]) ? unchecked((short)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] > right[i]) ? unchecked((short)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThan)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs
new file mode 100644
index 0000000000..e6c2541e4b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareGreaterThanInt32()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__CompareGreaterThanInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareGreaterThanInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareGreaterThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanInt32();
+ var result = Sse2.CompareGreaterThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareGreaterThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] > right[0]) ? unchecked((int)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] > right[i]) ? unchecked((int)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThan)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs
new file mode 100644
index 0000000000..56f523f98b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareGreaterThanSByte()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__CompareGreaterThanSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareGreaterThanSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareGreaterThan(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThan), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareGreaterThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanSByte();
+ var result = Sse2.CompareGreaterThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareGreaterThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] > right[0]) ? unchecked((sbyte)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] > right[i]) ? unchecked((sbyte)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThan)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.cs
deleted file mode 100644
index 04290ac010..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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.CompareGreaterThan);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- using (var intTable = TestTableSse2<int>.Create(testsCount))
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var sbyteTable = TestTableSse2<sbyte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareGreaterThan(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.CompareGreaterThan(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.CompareGreaterThan(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.CompareGreaterThan(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = x > y ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = x > y ? double.NaN : 0) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x > y ? -1 : 0) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(x, y, z, a) => (a = x > y ? -1 : 0) == z", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a)
- => (a = (short)(x > y ? -1 : 0)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(x, y, z) => (x > y ? -1 : 0) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a)
- => (a = (sbyte)(x > y ? -1 : 0)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(x, y, z) => (x > y ? -1 : 0) == z", checkSByte);
- 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/CompareGreaterThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs
new file mode 100644
index 0000000000..2af59f78d0
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareGreaterThanOrEqualDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareGreaterThanOrEqual(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareGreaterThanOrEqual(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareGreaterThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareGreaterThanOrEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble();
+ var result = Sse2.CompareGreaterThanOrEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareGreaterThanOrEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] >= right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareGreaterThanOrEqual)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.cs
deleted file mode 100644
index 1555ff2b5f..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.CompareGreaterThanOrEqual);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareGreaterThanOrEqual(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = x >= y ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = x > y ? double.NaN : 0) == z", checkDouble);
- 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/CompareGreaterThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual_r.csproj
deleted file mode 100644
index 725f16813e..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{87F2B90D-85D3-4304-99D3-355F109BE961}</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="CompareGreaterThanOrEqual.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/CompareGreaterThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual_ro.csproj
deleted file mode 100644
index 08c738606d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{A9EBC815-0839-4047-8602-7AB7AFB9C876}</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="CompareGreaterThanOrEqual.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/CompareGreaterThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan_r.csproj
deleted file mode 100644
index f93b43835c..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{C28A4AAF-7F4E-4FC2-B7E8-AB856A453C8F}</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="CompareGreaterThan.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/CompareGreaterThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan_ro.csproj
deleted file mode 100644
index b07cf68973..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{083F679A-B810-4523-892B-B86CC2089A05}</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="CompareGreaterThan.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/CompareLessThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs
new file mode 100644
index 0000000000..937d4d8576
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareLessThanDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareLessThanDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareLessThanDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareLessThanDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareLessThan(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareLessThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanDouble();
+ var result = Sse2.CompareLessThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareLessThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] < right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThan)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs
new file mode 100644
index 0000000000..77bf3a4347
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareLessThanInt16()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareLessThanInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__CompareLessThanInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareLessThanInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareLessThan(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareLessThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanInt16();
+ var result = Sse2.CompareLessThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareLessThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] < right[0]) ? unchecked((short)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] < right[i]) ? unchecked((short)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThan)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs
new file mode 100644
index 0000000000..29042f122f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareLessThanInt32()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareLessThanInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__CompareLessThanInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareLessThanInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareLessThan(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareLessThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanInt32();
+ var result = Sse2.CompareLessThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareLessThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] < right[0]) ? unchecked((int)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] < right[i]) ? unchecked((int)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThan)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs
new file mode 100644
index 0000000000..17eb6f00b6
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareLessThanSByte()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareLessThanSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__CompareLessThanSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareLessThanSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareLessThan(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareLessThan(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThan), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareLessThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanSByte();
+ var result = Sse2.CompareLessThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareLessThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != ((left[0] < right[0]) ? unchecked((sbyte)(-1)) : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (result[i] != ((left[i] < right[i]) ? unchecked((sbyte)(-1)) : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThan)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.cs
deleted file mode 100644
index ad70faba3a..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-// 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.X86;
-using System.Runtime.Intrinsics;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
-
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.CompareLessThan);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- using (var intTable = TestTableSse2<int>.Create(testsCount))
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var sbyteTable = TestTableSse2<sbyte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareLessThan(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.CompareLessThan(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.CompareLessThan(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.CompareLessThan(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = x < y ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x < y ? BitConverter.Int64BitsToDouble(-1) : 0) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x < y ? -1 : 0) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x < y ? -1 : 0) == z;", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)(x < y ? -1 : 0)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x < y ? -1 : 0)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x < y ? -1 : 0)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x < y ? -1 : 0)) == z", checkSByte);
- 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/CompareLessThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs
new file mode 100644
index 0000000000..e8a2beb65f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareLessThanOrEqualDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanOrEqualDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareLessThanOrEqualDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareLessThanOrEqualDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareLessThanOrEqualDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareLessThanOrEqual(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareLessThanOrEqual(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareLessThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareLessThanOrEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareLessThanOrEqualDouble();
+ var result = Sse2.CompareLessThanOrEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareLessThanOrEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] <= right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareLessThanOrEqual)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.cs
deleted file mode 100644
index d56a55e29b..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.CompareLessThanOrEqual);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareLessThanOrEqual(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = x <= y ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = x <= y ? double.NaN : 0) == z", checkDouble);
- 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/CompareLessThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual_r.csproj
deleted file mode 100644
index a183a38f0d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{398DEA1A-16E3-4EE8-8668-54DFB80EB7AB}</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="CompareLessThanOrEqual.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/CompareLessThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual_ro.csproj
deleted file mode 100644
index 04147332c9..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{3AC17539-DEBA-4FFB-BE4A-4FCB21C37294}</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="CompareLessThanOrEqual.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/CompareLessThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan_r.csproj
deleted file mode 100644
index 4577a520d0..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{93E4851E-5200-4A1E-AC26-FD8B18476570}</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="CompareLessThan.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/CompareLessThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan_ro.csproj
deleted file mode 100644
index 4012f4e0b8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{EFB18286-69A8-4260-8AD9-94A576984ECB}</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="CompareLessThan.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/CompareNotEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs
new file mode 100644
index 0000000000..8f34fcc250
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareNotEqualDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotEqualDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareNotEqualDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareNotEqualDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareNotEqualDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareNotEqual(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareNotEqual(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareNotEqual(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareNotEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotEqualDouble();
+ var result = Sse2.CompareNotEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareNotEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] != right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareNotEqual)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.cs
deleted file mode 100644
index 6a4615e2a2..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.CompareNotEqual);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareNotEqual(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = x != y ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = x != y ? double.NaN : 0) == z", checkDouble);
- 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/CompareNotEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual_r.csproj
deleted file mode 100644
index b98123cbf8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{9E2D750B-1AD6-4CCB-8CEE-856A702714DB}</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="CompareNotEqual.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/CompareNotEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual_ro.csproj
deleted file mode 100644
index 341273a044..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{A51475EC-9B61-442A-B8E9-90817E8C5FF3}</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="CompareNotEqual.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/CompareNotGreaterThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs
new file mode 100644
index 0000000000..1aca451839
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareNotGreaterThanDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotGreaterThanDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareNotGreaterThanDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareNotGreaterThanDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareNotGreaterThan(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareNotGreaterThan(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareNotGreaterThan(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareNotGreaterThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotGreaterThanDouble();
+ var result = Sse2.CompareNotGreaterThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareNotGreaterThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] > right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareNotGreaterThan)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.cs
deleted file mode 100644
index 6fbeef8b3f..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.CompareNotGreaterThan);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareNotGreaterThan(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- // Exactly after Intel manual
- a = !(x > y) ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x > y) ? double.NaN : 0) == z", checkDouble);
- 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/CompareNotGreaterThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs
new file mode 100644
index 0000000000..9b34b59a4e
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareNotGreaterThanOrEqualDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareNotGreaterThanOrEqual(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareNotGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareNotGreaterThanOrEqual(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotGreaterThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareNotGreaterThanOrEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotGreaterThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble();
+ var result = Sse2.CompareNotGreaterThanOrEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareNotGreaterThanOrEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] >= right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareNotGreaterThanOrEqual)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.cs
deleted file mode 100644
index 42b8f27798..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.CompareNotGreaterThanOrEqual);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareNotGreaterThanOrEqual(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = !(x >= y) ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x >= y) ? double.NaN : 0) == z", checkDouble);
- 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/CompareNotGreaterThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual_r.csproj
deleted file mode 100644
index 841a9b5a7d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{9719321A-FA33-43E6-B01E-102879E77321}</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="CompareNotGreaterThanOrEqual.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/CompareNotGreaterThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual_ro.csproj
deleted file mode 100644
index 96d983e583..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{93C1DB28-D5A7-493D-8017-9E028D39E025}</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="CompareNotGreaterThanOrEqual.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/CompareNotGreaterThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan_r.csproj
deleted file mode 100644
index 3db7ae5e24..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{CE864D5D-9D54-4000-A5BE-EC7052673CE5}</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="CompareNotGreaterThan.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/CompareNotGreaterThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan_ro.csproj
deleted file mode 100644
index 16b5b586ce..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{8B32892C-136B-4809-A082-F4EEF0FD0A8F}</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="CompareNotGreaterThan.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/CompareNotLessThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs
new file mode 100644
index 0000000000..d2a124fa83
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareNotLessThanDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotLessThanDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareNotLessThanDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareNotLessThanDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareNotLessThan(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareNotLessThan(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareNotLessThan(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThan), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareNotLessThan(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThan(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotLessThanDouble();
+ var result = Sse2.CompareNotLessThan(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareNotLessThan(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] < right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareNotLessThan)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.cs
deleted file mode 100644
index cf48c68155..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.CompareNotLessThan);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareNotLessThan(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = !(x < y) ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x < y) ? double.NaN : 0) == z", checkDouble);
- 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/CompareNotLessThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs
new file mode 100644
index 0000000000..d889a84d01
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareNotLessThanOrEqualDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareNotLessThanOrEqual(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareNotLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareNotLessThanOrEqual(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareNotLessThanOrEqual), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareNotLessThanOrEqual(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotLessThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThanOrEqual(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble();
+ var result = Sse2.CompareNotLessThanOrEqual(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareNotLessThanOrEqual(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] <= right[i]) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareNotLessThanOrEqual)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.cs
deleted file mode 100644
index 2862717dbf..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.CompareNotLessThanOrEqual);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareNotLessThanOrEqual(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- a = !(x <= y) ? BitConverter.Int64BitsToDouble(-1) : 0;
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = !(x <= y) ? double.NaN : 0) == z", checkDouble);
- 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/CompareNotLessThanOrEqual_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual_r.csproj
deleted file mode 100644
index 6f02e3c022..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{608FCA63-FF4F-4A38-9503-9CF51D291BAB}</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="CompareNotLessThanOrEqual.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/CompareNotLessThanOrEqual_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual_ro.csproj
deleted file mode 100644
index 2fb947b06b..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{D61F7DC7-97A3-4A5A-8A49-B80195B7EBFA}</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="CompareNotLessThanOrEqual.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/CompareNotLessThan_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan_r.csproj
deleted file mode 100644
index 1a3549a24d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{BF772C6E-6EA2-4649-9618-D3DB0AE49F41}</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="CompareNotLessThan.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/CompareNotLessThan_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan_ro.csproj
deleted file mode 100644
index 61d7742464..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{44063F5C-8943-4FC0-AEDF-45ED4A744CA9}</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="CompareNotLessThan.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/CompareOrdered.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs
new file mode 100644
index 0000000000..a26d95d09d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareOrderedDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareOrderedDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareOrderedDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareOrderedDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareOrderedDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareOrdered(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareOrdered(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareOrdered(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareOrdered), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareOrdered), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareOrdered), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareOrdered(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareOrdered(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareOrdered(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareOrdered(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareOrderedDouble();
+ var result = Sse2.CompareOrdered(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareOrdered(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((!double.IsNaN(left[0]) && !double.IsNaN(right[0])) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((!double.IsNaN(left[i]) && !double.IsNaN(right[i])) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareOrdered)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.cs
deleted file mode 100644
index 03f9ee69d8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.CompareOrdered);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareOrdered(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- if (!double.IsNaN(x) && !double.IsNaN(y))
- {
- a = BitConverter.Int64BitsToDouble(-1);
- }
- else
- {
- a = 0;
- }
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = (!double.IsNaN(x) && !double.IsNaN(y)) ? double.NaN : 0) == z", checkDouble);
- 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/CompareOrdered_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered_r.csproj
deleted file mode 100644
index 1f76671f06..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{2099478C-8A85-4032-8F86-402DA54F8FA2}</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="CompareOrdered.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/CompareOrdered_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered_ro.csproj
deleted file mode 100644
index 9e9d5c5d4b..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{AA7AFEBE-8C40-4A22-8A1E-5FC39EDD9A51}</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="CompareOrdered.cs" />
- <Compile Include="TestTableSse2.cs" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs
new file mode 100644
index 0000000000..a213bb723c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void CompareUnorderedDouble()
+ {
+ var test = new SimpleBinaryOpTest__CompareUnorderedDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__CompareUnorderedDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__CompareUnorderedDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__CompareUnorderedDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.CompareUnordered(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.CompareUnordered(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.CompareUnordered(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareUnordered), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareUnordered), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.CompareUnordered), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.CompareUnordered(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareUnordered(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareUnordered(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareUnordered(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__CompareUnorderedDouble();
+ var result = Sse2.CompareUnordered(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.CompareUnordered(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != ((double.IsNaN(left[0]) || double.IsNaN(right[0])) ? -1 : 0))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(result[i]) != ((double.IsNaN(left[i]) || double.IsNaN(right[i])) ? -1 : 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.CompareUnordered)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.cs
deleted file mode 100644
index 036aac646d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.CompareUnordered);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.CompareUnordered(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) =>
- {
- if (double.IsNaN(x) || double.IsNaN(y))
- {
- a = BitConverter.Int64BitsToDouble(-1);
- }
- else
- {
- a = 0;
- }
- return BitConverter.DoubleToInt64Bits(a) == BitConverter.DoubleToInt64Bits(z);
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(x, y, z, ref a) => (a = (double.IsNaN(x) || double.IsNaN(y)) ? double.NaN : 0) == z", checkDouble);
- 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/CompareUnordered_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered_r.csproj
deleted file mode 100644
index 94f475da87..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{15931119-A410-40C5-9FCC-D7A714C68512}</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="CompareUnordered.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/CompareUnordered_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered_ro.csproj
deleted file mode 100644
index a994bc71c8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{66739F14-FEA4-4993-B0E7-3E9B0D824FED}</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="CompareUnordered.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/Divide.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs
new file mode 100644
index 0000000000..34315c1f5b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void DivideDouble()
+ {
+ var test = new SimpleBinaryOpTest__DivideDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__DivideDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__DivideDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__DivideDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Divide(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Divide(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Divide(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Divide), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Divide), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Divide), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Divide(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Divide(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Divide(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Divide(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__DivideDouble();
+ var result = Sse2.Divide(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Divide(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i] / right[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Divide)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.cs
deleted file mode 100644
index 764277a5c2..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.Divide);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.Divide(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = x / y) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x / y) == z", checkDouble);
- 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/Divide_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide_r.csproj
deleted file mode 100644
index 397815001b..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{87A3726E-381D-417E-B498-3C4FFB632544}</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="Divide.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/Divide_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide_ro.csproj
deleted file mode 100644
index eeacfa2d6e..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{8AABA105-3887-4CA6-83F9-3CD59DAAC7E8}</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="Divide.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/Max.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs
new file mode 100644
index 0000000000..d03267468f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MaxByte()
+ {
+ var test = new SimpleBinaryOpTest__MaxByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MaxByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__MaxByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MaxByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Max(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Max(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Max(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Max(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MaxByte();
+ var result = Sse2.Max(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Max(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (Math.Max(left[0], right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (Math.Max(left[i], right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Max)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs
new file mode 100644
index 0000000000..49df538161
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MaxDouble()
+ {
+ var test = new SimpleBinaryOpTest__MaxDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MaxDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__MaxDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MaxDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Max(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Max(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Max(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Max(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MaxDouble();
+ var result = Sse2.Max(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Max(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(Math.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(Math.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Max)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs
new file mode 100644
index 0000000000..20b2d6fe26
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MaxInt16()
+ {
+ var test = new SimpleBinaryOpTest__MaxInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MaxInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__MaxInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MaxInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Max(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Max(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Max(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Max), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Max(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MaxInt16();
+ var result = Sse2.Max(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Max(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (Math.Max(left[0], right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (Math.Max(left[i], right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Max)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.cs
deleted file mode 100644
index 996c1b525a..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.Max);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var byteTable = TestTableSse2<byte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.Max(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.Max(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.Max(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = x > y ? x : y) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x > y ? x : y) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = x > y ? x : y) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = x > y ? x : y) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = x > y ? x : y) == z;
-
- if (!byteTable.CheckResult(checkByte))
- {
- PrintError(byteTable, methodUnderTestName, "(byte x, byte y, byte z, ref byte a) => (a = x > y ? 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/Max_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max_r.csproj
deleted file mode 100644
index 756e49a858..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{E47ED2C4-6A89-43E3-AD1A-8FEDA7D8FA03}</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="Max.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/Max_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max_ro.csproj
deleted file mode 100644
index aa9defa8a8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{75455928-80BB-4905-956F-0D53BFC4D804}</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="Max.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/Min.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs
new file mode 100644
index 0000000000..73a6b915e8
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MinByte()
+ {
+ var test = new SimpleBinaryOpTest__MinByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MinByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__MinByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MinValue)); _data2[i] = (byte)(random.Next(0, byte.MinValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MinByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MinValue)); _data2[i] = (byte)(random.Next(0, byte.MinValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MinValue)); _data2[i] = (byte)(random.Next(0, byte.MinValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Min(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Min(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Min(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Min(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MinByte();
+ var result = Sse2.Min(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Min(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (Math.Min(left[0], right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (Math.Min(left[i], right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Min)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs
new file mode 100644
index 0000000000..4d8e914ff0
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MinDouble()
+ {
+ var test = new SimpleBinaryOpTest__MinDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MinDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__MinDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MinDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Min(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Min(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Min(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Min(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MinDouble();
+ var result = Sse2.Min(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Min(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(Math.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(Math.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Min)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs
new file mode 100644
index 0000000000..9019540d3d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MinInt16()
+ {
+ var test = new SimpleBinaryOpTest__MinInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MinInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__MinInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MinValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MinValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MinInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MinValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MinValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MinValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MinValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Min(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Min(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Min(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Min), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Min(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MinInt16();
+ var result = Sse2.Min(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Min(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (Math.Min(left[0], right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (Math.Min(left[i], right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Min)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.cs
deleted file mode 100644
index 29f6e90e56..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.Min);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var byteTable = TestTableSse2<byte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.Min(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.Min(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.Min(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = x > y ? y : x) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseOr(x, y)) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = x > y ? y : x) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x | y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = x > y ? y : x) == z;
-
- 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/Min_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min_r.csproj
deleted file mode 100644
index 3d28c6f10a..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{78A91B0F-6535-42D7-B64C-948DF295B6BB}</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="Min.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/Min_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min_ro.csproj
deleted file mode 100644
index 0e20e0106d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{C392B2A4-03ED-4A52-8419-C17085646869}</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="Min.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/Multiply.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Byte.cs
new file mode 100644
index 0000000000..8507e514bc
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MultiplyByte()
+ {
+ var test = new SimpleBinaryOpTest__MultiplyByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MultiplyByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__MultiplyByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MultiplyByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Multiply(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Multiply(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Multiply(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Multiply), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Multiply), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Multiply), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Multiply(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Multiply(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Multiply(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Multiply(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MultiplyByte();
+ var result = Sse2.Multiply(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Multiply(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(left[0] * right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(left[i] * right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Multiply)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs
new file mode 100644
index 0000000000..09fa36e52d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void MultiplyDouble()
+ {
+ var test = new SimpleBinaryOpTest__MultiplyDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MultiplyDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__MultiplyDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MultiplyDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Multiply(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Multiply(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Multiply(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Multiply), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Multiply), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Multiply), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Multiply(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Multiply(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Multiply(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Multiply(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MultiplyDouble();
+ var result = Sse2.Multiply(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Multiply(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i] * right[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Multiply)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.cs
index 701253b9dc..718cfea0b5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.cs
@@ -22,31 +22,15 @@ namespace IntelHardwareIntrinsicTest
if (Sse2.IsSupported)
{
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
using (var uintTable = TestTableSse2<uint, ulong>.Create(testsCount, 2.0))
{
for (int i = 0; i < testsCount; i++)
{
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.Multiply(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
(Vector128<uint>, Vector128<uint>) value = uintTable[i];
Vector128<ulong> result = Sse2.Multiply(value.Item1, value.Item2);
uintTable.SetOutArrayU(result);
}
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = x * y) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x * y) == z", checkDouble);
- testResult = Fail;
- }
-
CheckMethodFive<uint, ulong> checkUInt32 = (uint x1, uint x2, uint y1, uint y2, ulong z1, ulong z2, ref ulong a1, ref ulong a2) =>
{
a1 = (ulong)x1 * y1;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs
new file mode 100644
index 0000000000..6481107fab
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrByte()
+ {
+ var test = new SimpleBinaryOpTest__OrByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__OrByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrByte();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs
new file mode 100644
index 0000000000..bfa8d33473
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrDouble()
+ {
+ var test = new SimpleBinaryOpTest__OrDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__OrDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrDouble();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if ((BitConverter.DoubleToInt64Bits(left[0]) | BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((BitConverter.DoubleToInt64Bits(left[i]) | BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs
new file mode 100644
index 0000000000..2d3fe08199
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrInt16()
+ {
+ var test = new SimpleBinaryOpTest__OrInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__OrInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrInt16();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((short)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((short)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs
new file mode 100644
index 0000000000..fbe5b1ced9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrInt32()
+ {
+ var test = new SimpleBinaryOpTest__OrInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__OrInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrInt32();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((int)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((int)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs
new file mode 100644
index 0000000000..861aed23c9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrInt64()
+ {
+ var test = new SimpleBinaryOpTest__OrInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[ElementCount];
+ private static Int64[] _data2 = new Int64[ElementCount];
+
+ private static Vector128<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector128<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+ static SimpleBinaryOpTest__OrInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrInt64();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((long)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((long)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<Int64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs
new file mode 100644
index 0000000000..56a3cfb4aa
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrSByte()
+ {
+ var test = new SimpleBinaryOpTest__OrSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__OrSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrSByte();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((sbyte)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((sbyte)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs
new file mode 100644
index 0000000000..ea151578a3
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrUInt16()
+ {
+ var test = new SimpleBinaryOpTest__OrUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrUInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector128<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector128<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__OrUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrUInt16();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ushort)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs
new file mode 100644
index 0000000000..b03776135c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrUInt32()
+ {
+ var test = new SimpleBinaryOpTest__OrUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrUInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector128<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector128<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__OrUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrUInt32();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((uint)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((uint)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs
new file mode 100644
index 0000000000..40e22b43d7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void OrUInt64()
+ {
+ var test = new SimpleBinaryOpTest__OrUInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__OrUInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[ElementCount];
+ private static UInt64[] _data2 = new UInt64[ElementCount];
+
+ private static Vector128<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector128<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__OrUInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__OrUInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Or(
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Or(
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Or), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Or(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__OrUInt64();
+ var result = Sse2.Or(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Or(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((ulong)(left[0] | right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ulong)(left[i] | right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Or)}<UInt64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.cs
deleted file mode 100644
index 7958224a74..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.Or);
-
- 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 (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<long>, Vector128<long>, Vector128<long>) value = longTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- longTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ulong>, Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- ulongTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<uint>, Vector128<uint>, Vector128<uint>) value = uintTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- uintTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.Or(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = BitwiseOr(x, y)) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseOr(x, y)) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<long> checkLong = (long x, long y, long z, ref long a) => (a = x | y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x | y) == z", checkLong);
- testResult = Fail;
- }
-
- CheckMethod<ulong> checkUlong = (ulong x, ulong y, ulong z, ref ulong a) => (a = x | y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(ulongTable, methodUnderTestName, "(ulong x, ulong y, ulong z, ref ulong a) => (a = x | y) == z", checkUlong);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x | y) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x | y) == z", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<uint> checkUInt32 = (uint x, uint y, uint z, ref uint a) => (a = x | y) == z;
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x | y) == z", checkUInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)(x | y)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x | y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x | y)) == z;
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x | y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x | y)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x | y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = (byte)(x | y)) == z;
-
- 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;
- }
-
- public static unsafe double BitwiseOr(double x, double y)
- {
- var xUlong = BitConverter.ToUInt64(BitConverter.GetBytes(x));
- var yUlong = BitConverter.ToUInt64(BitConverter.GetBytes(y));
- var longAnd = xUlong | yUlong;
- return BitConverter.ToDouble(BitConverter.GetBytes(longAnd));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_r.csproj
deleted file mode 100644
index d0be377c15..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{44DBB8A7-5F29-4813-B2E3-7978EA45BED8}</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="Or.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/Or_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_ro.csproj
deleted file mode 100644
index abf2512272..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{3625F7C3-45E3-43A5-92B9-9028B9F9476B}</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="Or.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/Program.Sse2.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
index 6994fe61da..768e3adf08 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
@@ -21,6 +21,83 @@ namespace JIT.HardwareIntrinsics.X86
["Add.UInt16"] = AddUInt16,
["Add.UInt32"] = AddUInt32,
["Add.UInt64"] = AddUInt64,
+ ["And.Double"] = AndDouble,
+ ["And.Byte"] = AndByte,
+ ["And.Int16"] = AndInt16,
+ ["And.Int32"] = AndInt32,
+ ["And.Int64"] = AndInt64,
+ ["And.SByte"] = AndSByte,
+ ["And.UInt16"] = AndUInt16,
+ ["And.UInt32"] = AndUInt32,
+ ["And.UInt64"] = AndUInt64,
+ ["AndNot.Double"] = AndNotDouble,
+ ["AndNot.Byte"] = AndNotByte,
+ ["AndNot.Int16"] = AndNotInt16,
+ ["AndNot.Int32"] = AndNotInt32,
+ ["AndNot.Int64"] = AndNotInt64,
+ ["AndNot.SByte"] = AndNotSByte,
+ ["AndNot.UInt16"] = AndNotUInt16,
+ ["AndNot.UInt32"] = AndNotUInt32,
+ ["AndNot.UInt64"] = AndNotUInt64,
+ ["CompareEqual.Double"] = CompareEqualDouble,
+ ["CompareEqual.Byte"] = CompareEqualByte,
+ ["CompareEqual.Int16"] = CompareEqualInt16,
+ ["CompareEqual.Int32"] = CompareEqualInt32,
+ ["CompareEqual.SByte"] = CompareEqualSByte,
+ ["CompareEqual.UInt16"] = CompareEqualUInt16,
+ ["CompareEqual.UInt32"] = CompareEqualUInt32,
+ ["CompareGreaterThan.Double"] = CompareGreaterThanDouble,
+ ["CompareGreaterThan.Int16"] = CompareGreaterThanInt16,
+ ["CompareGreaterThan.Int32"] = CompareGreaterThanInt32,
+ ["CompareGreaterThan.SByte"] = CompareGreaterThanSByte,
+ ["CompareGreaterThanOrEqual.Double"] = CompareGreaterThanOrEqualDouble,
+ ["CompareLessThan.Double"] = CompareLessThanDouble,
+ ["CompareLessThan.Int16"] = CompareLessThanInt16,
+ ["CompareLessThan.Int32"] = CompareLessThanInt32,
+ ["CompareLessThan.SByte"] = CompareLessThanSByte,
+ ["CompareLessThanOrEqual.Double"] = CompareLessThanOrEqualDouble,
+ ["CompareNotEqual.Double"] = CompareNotEqualDouble,
+ ["CompareNotGreaterThan.Double"] = CompareNotGreaterThanDouble,
+ ["CompareNotGreaterThanOrEqual.Double"] = CompareNotGreaterThanOrEqualDouble,
+ ["CompareNotLessThan.Double"] = CompareNotLessThanDouble,
+ ["CompareNotLessThanOrEqual.Double"] = CompareNotLessThanOrEqualDouble,
+ ["CompareOrdered.Double"] = CompareOrderedDouble,
+ ["CompareUnordered.Double"] = CompareUnorderedDouble,
+ ["Divide.Double"] = DivideDouble,
+ ["Max.Double"] = MaxDouble,
+ ["Max.Byte"] = MaxByte,
+ ["Max.Int16"] = MaxInt16,
+ ["Min.Double"] = MinDouble,
+ ["Min.Byte"] = MinByte,
+ ["Min.Int16"] = MinInt16,
+ ["Multiply.Double"] = MultiplyDouble,
+ ["Or.Double"] = OrDouble,
+ ["Or.Byte"] = OrByte,
+ ["Or.Int16"] = OrInt16,
+ ["Or.Int32"] = OrInt32,
+ ["Or.Int64"] = OrInt64,
+ ["Or.SByte"] = OrSByte,
+ ["Or.UInt16"] = OrUInt16,
+ ["Or.UInt32"] = OrUInt32,
+ ["Or.UInt64"] = OrUInt64,
+ ["Subtract.Double"] = SubtractDouble,
+ ["Subtract.Byte"] = SubtractByte,
+ ["Subtract.Int16"] = SubtractInt16,
+ ["Subtract.Int32"] = SubtractInt32,
+ ["Subtract.Int64"] = SubtractInt64,
+ ["Subtract.SByte"] = SubtractSByte,
+ ["Subtract.UInt16"] = SubtractUInt16,
+ ["Subtract.UInt32"] = SubtractUInt32,
+ ["Subtract.UInt64"] = SubtractUInt64,
+ ["Xor.Double"] = XorDouble,
+ ["Xor.Byte"] = XorByte,
+ ["Xor.Int16"] = XorInt16,
+ ["Xor.Int32"] = XorInt32,
+ ["Xor.Int64"] = XorInt64,
+ ["Xor.SByte"] = XorSByte,
+ ["Xor.UInt16"] = XorUInt16,
+ ["Xor.UInt32"] = XorUInt32,
+ ["Xor.UInt64"] = XorUInt64,
};
}
}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
index f25b4907e9..2711acf0dd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
@@ -27,8 +27,8 @@
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
- <Compile Include="Add.Byte.cs" />
<Compile Include="Add.Double.cs" />
+ <Compile Include="Add.Byte.cs" />
<Compile Include="Add.Int16.cs" />
<Compile Include="Add.Int32.cs" />
<Compile Include="Add.Int64.cs" />
@@ -36,9 +36,86 @@
<Compile Include="Add.UInt16.cs" />
<Compile Include="Add.UInt32.cs" />
<Compile Include="Add.UInt64.cs" />
+ <Compile Include="And.Double.cs" />
+ <Compile Include="And.Byte.cs" />
+ <Compile Include="And.Int16.cs" />
+ <Compile Include="And.Int32.cs" />
+ <Compile Include="And.Int64.cs" />
+ <Compile Include="And.SByte.cs" />
+ <Compile Include="And.UInt16.cs" />
+ <Compile Include="And.UInt32.cs" />
+ <Compile Include="And.UInt64.cs" />
+ <Compile Include="AndNot.Double.cs" />
+ <Compile Include="AndNot.Byte.cs" />
+ <Compile Include="AndNot.Int16.cs" />
+ <Compile Include="AndNot.Int32.cs" />
+ <Compile Include="AndNot.Int64.cs" />
+ <Compile Include="AndNot.SByte.cs" />
+ <Compile Include="AndNot.UInt16.cs" />
+ <Compile Include="AndNot.UInt32.cs" />
+ <Compile Include="AndNot.UInt64.cs" />
+ <Compile Include="CompareEqual.Double.cs" />
+ <Compile Include="CompareEqual.Byte.cs" />
+ <Compile Include="CompareEqual.Int16.cs" />
+ <Compile Include="CompareEqual.Int32.cs" />
+ <Compile Include="CompareEqual.SByte.cs" />
+ <Compile Include="CompareEqual.UInt16.cs" />
+ <Compile Include="CompareEqual.UInt32.cs" />
+ <Compile Include="CompareGreaterThan.Double.cs" />
+ <Compile Include="CompareGreaterThan.Int16.cs" />
+ <Compile Include="CompareGreaterThan.Int32.cs" />
+ <Compile Include="CompareGreaterThan.SByte.cs" />
+ <Compile Include="CompareGreaterThanOrEqual.Double.cs" />
+ <Compile Include="CompareLessThan.Double.cs" />
+ <Compile Include="CompareLessThan.Int16.cs" />
+ <Compile Include="CompareLessThan.Int32.cs" />
+ <Compile Include="CompareLessThan.SByte.cs" />
+ <Compile Include="CompareLessThanOrEqual.Double.cs" />
+ <Compile Include="CompareNotEqual.Double.cs" />
+ <Compile Include="CompareNotGreaterThan.Double.cs" />
+ <Compile Include="CompareNotGreaterThanOrEqual.Double.cs" />
+ <Compile Include="CompareNotLessThan.Double.cs" />
+ <Compile Include="CompareNotLessThanOrEqual.Double.cs" />
+ <Compile Include="CompareOrdered.Double.cs" />
+ <Compile Include="CompareUnordered.Double.cs" />
+ <Compile Include="Divide.Double.cs" />
+ <Compile Include="Max.Double.cs" />
+ <Compile Include="Max.Byte.cs" />
+ <Compile Include="Max.Int16.cs" />
+ <Compile Include="Min.Double.cs" />
+ <Compile Include="Min.Byte.cs" />
+ <Compile Include="Min.Int16.cs" />
+ <Compile Include="Multiply.Double.cs" />
+ <Compile Include="Or.Double.cs" />
+ <Compile Include="Or.Byte.cs" />
+ <Compile Include="Or.Int16.cs" />
+ <Compile Include="Or.Int32.cs" />
+ <Compile Include="Or.Int64.cs" />
+ <Compile Include="Or.SByte.cs" />
+ <Compile Include="Or.UInt16.cs" />
+ <Compile Include="Or.UInt32.cs" />
+ <Compile Include="Or.UInt64.cs" />
+ <Compile Include="Subtract.Double.cs" />
+ <Compile Include="Subtract.Byte.cs" />
+ <Compile Include="Subtract.Int16.cs" />
+ <Compile Include="Subtract.Int32.cs" />
+ <Compile Include="Subtract.Int64.cs" />
+ <Compile Include="Subtract.SByte.cs" />
+ <Compile Include="Subtract.UInt16.cs" />
+ <Compile Include="Subtract.UInt32.cs" />
+ <Compile Include="Subtract.UInt64.cs" />
+ <Compile Include="Xor.Double.cs" />
+ <Compile Include="Xor.Byte.cs" />
+ <Compile Include="Xor.Int16.cs" />
+ <Compile Include="Xor.Int32.cs" />
+ <Compile Include="Xor.Int64.cs" />
+ <Compile Include="Xor.SByte.cs" />
+ <Compile Include="Xor.UInt16.cs" />
+ <Compile Include="Xor.UInt32.cs" />
+ <Compile Include="Xor.UInt64.cs" />
<Compile Include="Program.Sse2.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable_Aligned.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
index 003a20b285..2227b784b5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
@@ -27,8 +27,8 @@
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
- <Compile Include="Add.Byte.cs" />
<Compile Include="Add.Double.cs" />
+ <Compile Include="Add.Byte.cs" />
<Compile Include="Add.Int16.cs" />
<Compile Include="Add.Int32.cs" />
<Compile Include="Add.Int64.cs" />
@@ -36,9 +36,86 @@
<Compile Include="Add.UInt16.cs" />
<Compile Include="Add.UInt32.cs" />
<Compile Include="Add.UInt64.cs" />
+ <Compile Include="And.Double.cs" />
+ <Compile Include="And.Byte.cs" />
+ <Compile Include="And.Int16.cs" />
+ <Compile Include="And.Int32.cs" />
+ <Compile Include="And.Int64.cs" />
+ <Compile Include="And.SByte.cs" />
+ <Compile Include="And.UInt16.cs" />
+ <Compile Include="And.UInt32.cs" />
+ <Compile Include="And.UInt64.cs" />
+ <Compile Include="AndNot.Double.cs" />
+ <Compile Include="AndNot.Byte.cs" />
+ <Compile Include="AndNot.Int16.cs" />
+ <Compile Include="AndNot.Int32.cs" />
+ <Compile Include="AndNot.Int64.cs" />
+ <Compile Include="AndNot.SByte.cs" />
+ <Compile Include="AndNot.UInt16.cs" />
+ <Compile Include="AndNot.UInt32.cs" />
+ <Compile Include="AndNot.UInt64.cs" />
+ <Compile Include="CompareEqual.Double.cs" />
+ <Compile Include="CompareEqual.Byte.cs" />
+ <Compile Include="CompareEqual.Int16.cs" />
+ <Compile Include="CompareEqual.Int32.cs" />
+ <Compile Include="CompareEqual.SByte.cs" />
+ <Compile Include="CompareEqual.UInt16.cs" />
+ <Compile Include="CompareEqual.UInt32.cs" />
+ <Compile Include="CompareGreaterThan.Double.cs" />
+ <Compile Include="CompareGreaterThan.Int16.cs" />
+ <Compile Include="CompareGreaterThan.Int32.cs" />
+ <Compile Include="CompareGreaterThan.SByte.cs" />
+ <Compile Include="CompareGreaterThanOrEqual.Double.cs" />
+ <Compile Include="CompareLessThan.Double.cs" />
+ <Compile Include="CompareLessThan.Int16.cs" />
+ <Compile Include="CompareLessThan.Int32.cs" />
+ <Compile Include="CompareLessThan.SByte.cs" />
+ <Compile Include="CompareLessThanOrEqual.Double.cs" />
+ <Compile Include="CompareNotEqual.Double.cs" />
+ <Compile Include="CompareNotGreaterThan.Double.cs" />
+ <Compile Include="CompareNotGreaterThanOrEqual.Double.cs" />
+ <Compile Include="CompareNotLessThan.Double.cs" />
+ <Compile Include="CompareNotLessThanOrEqual.Double.cs" />
+ <Compile Include="CompareOrdered.Double.cs" />
+ <Compile Include="CompareUnordered.Double.cs" />
+ <Compile Include="Divide.Double.cs" />
+ <Compile Include="Max.Double.cs" />
+ <Compile Include="Max.Byte.cs" />
+ <Compile Include="Max.Int16.cs" />
+ <Compile Include="Min.Double.cs" />
+ <Compile Include="Min.Byte.cs" />
+ <Compile Include="Min.Int16.cs" />
+ <Compile Include="Multiply.Double.cs" />
+ <Compile Include="Or.Double.cs" />
+ <Compile Include="Or.Byte.cs" />
+ <Compile Include="Or.Int16.cs" />
+ <Compile Include="Or.Int32.cs" />
+ <Compile Include="Or.Int64.cs" />
+ <Compile Include="Or.SByte.cs" />
+ <Compile Include="Or.UInt16.cs" />
+ <Compile Include="Or.UInt32.cs" />
+ <Compile Include="Or.UInt64.cs" />
+ <Compile Include="Subtract.Double.cs" />
+ <Compile Include="Subtract.Byte.cs" />
+ <Compile Include="Subtract.Int16.cs" />
+ <Compile Include="Subtract.Int32.cs" />
+ <Compile Include="Subtract.Int64.cs" />
+ <Compile Include="Subtract.SByte.cs" />
+ <Compile Include="Subtract.UInt16.cs" />
+ <Compile Include="Subtract.UInt32.cs" />
+ <Compile Include="Subtract.UInt64.cs" />
+ <Compile Include="Xor.Double.cs" />
+ <Compile Include="Xor.Byte.cs" />
+ <Compile Include="Xor.Int16.cs" />
+ <Compile Include="Xor.Int32.cs" />
+ <Compile Include="Xor.Int64.cs" />
+ <Compile Include="Xor.SByte.cs" />
+ <Compile Include="Xor.UInt16.cs" />
+ <Compile Include="Xor.UInt32.cs" />
+ <Compile Include="Xor.UInt64.cs" />
<Compile Include="Program.Sse2.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable_Aligned.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs
new file mode 100644
index 0000000000..dcd9ed39fe
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractByte()
+ {
+ var test = new SimpleBinaryOpTest__SubtractByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractByte();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs
new file mode 100644
index 0000000000..0e8c22da1d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractDouble()
+ {
+ var test = new SimpleBinaryOpTest__SubtractDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractDouble();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i] - right[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs
new file mode 100644
index 0000000000..737fd780f0
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractInt16()
+ {
+ var test = new SimpleBinaryOpTest__SubtractInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractInt16();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((short)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((short)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs
new file mode 100644
index 0000000000..eb31b7ece7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractInt32()
+ {
+ var test = new SimpleBinaryOpTest__SubtractInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractInt32();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((int)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((int)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs
new file mode 100644
index 0000000000..f67c4f8604
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractInt64()
+ {
+ var test = new SimpleBinaryOpTest__SubtractInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[ElementCount];
+ private static Int64[] _data2 = new Int64[ElementCount];
+
+ private static Vector128<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector128<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractInt64();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((long)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((long)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<Int64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs
new file mode 100644
index 0000000000..c3fe70cbd6
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractSByte()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSByte();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((sbyte)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((sbyte)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs
new file mode 100644
index 0000000000..3ac3c7ff46
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractUInt16()
+ {
+ var test = new SimpleBinaryOpTest__SubtractUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractUInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector128<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector128<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractUInt16();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ushort)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs
new file mode 100644
index 0000000000..dd4ead9740
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractUInt32()
+ {
+ var test = new SimpleBinaryOpTest__SubtractUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractUInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector128<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector128<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractUInt32();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((uint)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((uint)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs
new file mode 100644
index 0000000000..992fe56faa
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void SubtractUInt64()
+ {
+ var test = new SimpleBinaryOpTest__SubtractUInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractUInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[ElementCount];
+ private static UInt64[] _data2 = new UInt64[ElementCount];
+
+ private static Vector128<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector128<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__SubtractUInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractUInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Subtract(
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Subtract(
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Subtract), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Subtract(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractUInt64();
+ var result = Sse2.Subtract(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Subtract(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((ulong)(left[0] - right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ulong)(left[i] - right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Subtract)}<UInt64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.cs
deleted file mode 100644
index ce786d6df8..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.Subtract);
-
- 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 (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<long>, Vector128<long>, Vector128<long>) value = longTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- longTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ulong>, Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- ulongTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<uint>, Vector128<uint>, Vector128<uint>) value = uintTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- uintTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.Subtract(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = x - y) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x - y) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<long> checkLong = (long x, long y, long z, ref long a) => (a = x - y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x - y) == z", checkLong);
- testResult = Fail;
- }
-
- CheckMethod<ulong> checkUlong = (ulong x, ulong y, ulong z, ref ulong a) => (a = x - y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(ulongTable, methodUnderTestName, "(ulong x, ulong y, ulong z, ref ulong a) => (a = x - y) == z", checkUlong);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x - y) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x - y) == z", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<uint> checkUInt32 = (uint x, uint y, uint z, ref uint a) => (a = x - y) == z;
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x - y) == z", checkUInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)(x - y)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x - y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x - y)) == z;
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x - y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x - y)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x - y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = (byte)(x - y)) == z;
-
- 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/Subtract_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract_r.csproj
deleted file mode 100644
index accd716b36..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{DDE1DDD6-B6BD-42D2-9D49-5BCE2E707442}</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="Subtract.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/Subtract_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract_ro.csproj
deleted file mode 100644
index 810f23330d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{7B7FCE02-0D75-4BE2-80C0-29F2D410FDF3}</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="Subtract.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/Xor.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs
new file mode 100644
index 0000000000..6d8ad708ba
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorByte()
+ {
+ var test = new SimpleBinaryOpTest__XorByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[ElementCount];
+ private static Byte[] _data2 = new Byte[ElementCount];
+
+ private static Vector128<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector128<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte> _dataTable;
+
+ static SimpleBinaryOpTest__XorByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte>(_data1, _data2, new Byte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorByte();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[ElementCount];
+ Byte[] inArray2 = new Byte[ElementCount];
+ Byte[] outArray = new Byte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((byte)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<Byte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs
new file mode 100644
index 0000000000..3bbf24a14f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorDouble()
+ {
+ var test = new SimpleBinaryOpTest__XorDouble();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorDouble
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[ElementCount];
+ private static Double[] _data2 = new Double[ElementCount];
+
+ private static Vector128<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector128<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double> _dataTable;
+
+ static SimpleBinaryOpTest__XorDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorDouble();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[ElementCount];
+ Double[] inArray2 = new Double[ElementCount];
+ Double[] outArray = new Double[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if ((BitConverter.DoubleToInt64Bits(left[0]) ^ BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((BitConverter.DoubleToInt64Bits(left[i]) ^ BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<Double>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs
new file mode 100644
index 0000000000..c14ac4d434
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorInt16()
+ {
+ var test = new SimpleBinaryOpTest__XorInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[ElementCount];
+ private static Int16[] _data2 = new Int16[ElementCount];
+
+ private static Vector128<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector128<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16> _dataTable;
+
+ static SimpleBinaryOpTest__XorInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16>(_data1, _data2, new Int16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorInt16();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[ElementCount];
+ Int16[] inArray2 = new Int16[ElementCount];
+ Int16[] outArray = new Int16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((short)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((short)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<Int16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs
new file mode 100644
index 0000000000..2a7970763b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorInt32()
+ {
+ var test = new SimpleBinaryOpTest__XorInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[ElementCount];
+ private static Int32[] _data2 = new Int32[ElementCount];
+
+ private static Vector128<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector128<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32> _dataTable;
+
+ static SimpleBinaryOpTest__XorInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (int)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (int)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32>(_data1, _data2, new Int32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorInt32();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[ElementCount];
+ Int32[] inArray2 = new Int32[ElementCount];
+ Int32[] outArray = new Int32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((int)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((int)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<Int32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs
new file mode 100644
index 0000000000..be2e77e03f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorInt64()
+ {
+ var test = new SimpleBinaryOpTest__XorInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[ElementCount];
+ private static Int64[] _data2 = new Int64[ElementCount];
+
+ private static Vector128<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector128<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64> _dataTable;
+
+ static SimpleBinaryOpTest__XorInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (long)(random.Next(int.MinValue, int.MaxValue)); _data2[i] = (long)(random.Next(int.MinValue, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64>(_data1, _data2, new Int64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorInt64();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[ElementCount];
+ Int64[] inArray2 = new Int64[ElementCount];
+ Int64[] outArray = new Int64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((long)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((long)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<Int64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs
new file mode 100644
index 0000000000..77d25337a2
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorSByte()
+ {
+ var test = new SimpleBinaryOpTest__XorSByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorSByte
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[ElementCount];
+ private static SByte[] _data2 = new SByte[ElementCount];
+
+ private static Vector128<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector128<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte> _dataTable;
+
+ static SimpleBinaryOpTest__XorSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte>(_data1, _data2, new SByte[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorSByte();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[ElementCount];
+ SByte[] inArray2 = new SByte[ElementCount];
+ SByte[] outArray = new SByte[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((sbyte)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((sbyte)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<SByte>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs
new file mode 100644
index 0000000000..89aad87dba
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorUInt16()
+ {
+ var test = new SimpleBinaryOpTest__XorUInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorUInt16
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[ElementCount];
+ private static UInt16[] _data2 = new UInt16[ElementCount];
+
+ private static Vector128<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector128<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__XorUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16>(_data1, _data2, new UInt16[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorUInt16();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[ElementCount];
+ UInt16[] inArray2 = new UInt16[ElementCount];
+ UInt16[] outArray = new UInt16[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ushort)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<UInt16>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs
new file mode 100644
index 0000000000..479b11151d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorUInt32()
+ {
+ var test = new SimpleBinaryOpTest__XorUInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorUInt32
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[ElementCount];
+ private static UInt32[] _data2 = new UInt32[ElementCount];
+
+ private static Vector128<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector128<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__XorUInt32()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorUInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32>(_data1, _data2, new UInt32[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorUInt32();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[ElementCount];
+ UInt32[] inArray2 = new UInt32[ElementCount];
+ UInt32[] outArray = new UInt32[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((uint)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((uint)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<UInt32>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs
new file mode 100644
index 0000000000..2a448a4c48
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs
@@ -0,0 +1,315 @@
+// 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.
+
+/******************************************************************************
+ * This file is auto-generated from a template file by the GenerateTests.csx *
+ * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
+ * changes, please update the corresponding template and run according to the *
+ * directions listed in the file. *
+ ******************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void XorUInt64()
+ {
+ var test = new SimpleBinaryOpTest__XorUInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates basic functionality works, using Load
+ test.RunBasicScenario_Load();
+
+ // Validates basic functionality works, using LoadAligned
+ test.RunBasicScenario_LoadAligned();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario_Load();
+
+ // Validates calling via reflection works, using LoadAligned
+ test.RunReflectionScenario_LoadAligned();
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing a local works, using Load
+ test.RunLclVarScenario_Load();
+
+ // Validates passing a local works, using LoadAligned
+ test.RunLclVarScenario_LoadAligned();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__XorUInt64
+ {
+ private const int VectorSize = 16;
+ private const int ElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[ElementCount];
+ private static UInt64[] _data2 = new UInt64[ElementCount];
+
+ private static Vector128<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector128<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__XorUInt64()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__XorUInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64>(_data1, _data2, new UInt64[ElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Xor(
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Xor(
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Xor), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Xor(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__XorUInt64();
+ var result = Sse2.Xor(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Xor(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[ElementCount];
+ UInt64[] inArray2 = new UInt64[ElementCount];
+ UInt64[] outArray = new UInt64[ElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((ulong)(left[0] ^ right[0]) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < left.Length; i++)
+ {
+ if ((ulong)(left[i] ^ right[i]) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Xor)}<UInt64>: {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.cs
deleted file mode 100644
index d2788b500a..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// 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
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.Xor);
-
- 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 (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>, Vector128<double>) value = doubleTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<long>, Vector128<long>, Vector128<long>) value = longTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- longTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ulong>, Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- ulongTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<int>, Vector128<int>, Vector128<int>) value = intTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- intTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<uint>, Vector128<uint>, Vector128<uint>) value = uintTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- uintTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.Xor(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<double> checkDouble = (double x, double y, double z, ref double a) => (a = BitwiseXor(x, y)) == z;
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseXor(x, y)) == z", checkDouble);
- testResult = Fail;
- }
-
- CheckMethod<long> checkLong = (long x, long y, long z, ref long a) => (a = x ^ y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x ^ y) == z", checkLong);
- testResult = Fail;
- }
-
- CheckMethod<ulong> checkUlong = (ulong x, ulong y, ulong z, ref ulong a) => (a = x ^ y) == z;
-
- if (!longTable.CheckResult(checkLong))
- {
- PrintError(ulongTable, methodUnderTestName, "(ulong x, ulong y, ulong z, ref ulong a) => (a = x ^ y) == z", checkUlong);
- testResult = Fail;
- }
-
- CheckMethod<int> checkInt32 = (int x, int y, int z, ref int a) => (a = x ^ y) == z;
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x ^ y) == z", checkInt32);
- testResult = Fail;
- }
-
- CheckMethod<uint> checkUInt32 = (uint x, uint y, uint z, ref uint a) => (a = x ^ y) == z;
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x ^ y) == z", checkUInt32);
- testResult = Fail;
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) => (a = (short)(x ^ y)) == z;
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x ^ y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x ^ y)) == z;
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x ^ y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x ^ y)) == z;
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x ^ y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) => (a = (byte)(x ^ y)) == z;
-
- 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;
- }
-
- public static unsafe double BitwiseXor(double x, double y)
- {
- var xUlong = BitConverter.ToUInt64(BitConverter.GetBytes(x));
- var yUlong = BitConverter.ToUInt64(BitConverter.GetBytes(y));
- var longAnd = xUlong ^ yUlong;
- return BitConverter.ToDouble(BitConverter.GetBytes(longAnd));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_r.csproj
deleted file mode 100644
index e354b97ae0..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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>{C2DA0767-1509-4FFE-BC4C-F58FC761413C}</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="Xor.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/Xor_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_ro.csproj
deleted file mode 100644
index 8af5c632ea..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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>{D926F753-0262-4EE2-BFA2-F0FDA0F51899}</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="Xor.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