Convert Sse2 tests PackSignedSaturate, PackUnsignedSaturate, UnpackHigh and UnpackLow...
authorJacek Blaszczynski <biosciencenow@outlook.com>
Thu, 20 Sep 2018 23:09:36 +0000 (01:09 +0200)
committerTanner Gooding <tagoo@outlook.com>
Thu, 20 Sep 2018 23:09:36 +0000 (16:09 -0700)
*  Convert PackSignedSaturate, PackUnsignedSaturate, UnpackHigh, UnpackLow tests to template based

* Add generated Sse2 Pack***Saturate, UnpackHigh, UnpackLow tests, remove replaced tests

*  Remove deleted Sse2 Pack** Unpack** tests from Test.lst files for arm and arm64 Windows targets

39 files changed:
tests/arm/Tests.lst
tests/arm64/Tests.lst
tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh_ro.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs [new file with mode: 0644]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.cs [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow_r.csproj [deleted file]
tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow_ro.csproj [deleted file]

index 26257ae..bf868fe 100644 (file)
@@ -1,9 +1,9 @@
 ## This list file has been produced automatically. Any changes
 ## are subject to being overwritten when reproducing this file.
-## 
+##
 ## Last Updated: 09-May-2018 17:42:09
 ## Commit: aa8dd0d8a9b1bb47e00fcd694342ed5defb46508
-## 
+##
 [int8_il_r.cmd_1]
 RelativePath=JIT\Directed\shift\int8_il_r\int8_il_r.cmd
 WorkingDir=JIT\Directed\shift\int8_il_r
@@ -91364,14 +91364,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[UnpackLow_ro.cmd_11532]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro\UnpackLow_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadAlignedVector128_ro.cmd_11533]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\LoadAlignedVector128_ro\LoadAlignedVector128_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\LoadAlignedVector128_ro
@@ -91820,22 +91812,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[UnpackHigh_r.cmd_11596]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_r\UnpackHigh_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[PackSignedSaturate_r.cmd_11597]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_r\PackSignedSaturate_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Sqrt_ro.cmd_11598]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\Sqrt_ro\Sqrt_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\Sqrt_ro
@@ -92380,14 +92356,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[PackUnsignedSaturate_ro.cmd_11679]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_ro\PackUnsignedSaturate_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Equality.cmd_11680]
 RelativePath=JIT\opt\Types\Equality\Equality.cmd
 WorkingDir=JIT\opt\Types\Equality
@@ -93212,14 +93180,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[PackSignedSaturate_ro.cmd_11804]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro\PackSignedSaturate_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [HorizontalAdd_r.cmd_11805]
 RelativePath=JIT\HardwareIntrinsics\X86\Avx\HorizontalAdd_r\HorizontalAdd_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Avx\HorizontalAdd_r
@@ -93468,14 +93428,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[UnpackLow_r.cmd_11838]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r\UnpackLow_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ReciprocalSqrtScalar_r.cmd_11839]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\ReciprocalSqrtScalar_r\ReciprocalSqrtScalar_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\ReciprocalSqrtScalar_r
@@ -93524,14 +93476,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[UnpackHigh_ro.cmd_11845]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_ro\UnpackHigh_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ConvertToVector128_r.cmd_11846]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse41\ConvertToVector128_r\ConvertToVector128_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse41\ConvertToVector128_r
@@ -93612,14 +93556,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[PackUnsignedSaturate_r.cmd_11858]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_r\PackUnsignedSaturate_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [genericcontext.cmd_11859]
 RelativePath=Regressions\coreclr\15241\genericcontext\genericcontext.cmd
 WorkingDir=Regressions\coreclr\15241\genericcontext
index 8bb2287..5bd7cde 100644 (file)
@@ -1,9 +1,9 @@
 ## This list file has been produced automatically. Any changes
 ## are subject to being overwritten when reproducing this file.
-## 
+##
 ## Last Updated: 09-May-2018 17:46:52
 ## Commit: aa8dd0d8a9b1bb47e00fcd694342ed5defb46508
-## 
+##
 [Dev10_535767.cmd_0]
 RelativePath=baseservices\compilerservices\dynamicobjectproperties\Dev10_535767\Dev10_535767.cmd
 WorkingDir=baseservices\compilerservices\dynamicobjectproperties\Dev10_535767
@@ -91364,14 +91364,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[UnpackLow_ro.cmd_11849]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro\UnpackLow_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [LoadAlignedVector128_ro.cmd_11850]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse2\LoadAlignedVector128_ro\LoadAlignedVector128_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\LoadAlignedVector128_ro
@@ -91828,22 +91820,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[UnpackHigh_r.cmd_11913]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_r\UnpackHigh_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
-[PackSignedSaturate_r.cmd_11914]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_r\PackSignedSaturate_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Sqrt_ro.cmd_11915]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\Sqrt_ro\Sqrt_ro.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\Sqrt_ro
@@ -92388,14 +92364,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[PackUnsignedSaturate_ro.cmd_11997]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_ro\PackUnsignedSaturate_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [Equality.cmd_11998]
 RelativePath=JIT\opt\Types\Equality\Equality.cmd
 WorkingDir=JIT\opt\Types\Equality
@@ -93228,14 +93196,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[PackSignedSaturate_ro.cmd_12123]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro\PackSignedSaturate_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackSignedSaturate_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [eventsourcetrace.cmd_12124]
 RelativePath=tracing\eventsourcetrace\eventsourcetrace\eventsourcetrace.cmd
 WorkingDir=tracing\eventsourcetrace\eventsourcetrace
@@ -93452,14 +93412,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[UnpackLow_r.cmd_12153]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r\UnpackLow_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackLow_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ReciprocalSqrtScalar_r.cmd_12154]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse\ReciprocalSqrtScalar_r\ReciprocalSqrtScalar_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse\ReciprocalSqrtScalar_r
@@ -93508,14 +93460,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
-[UnpackHigh_ro.cmd_12160]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_ro\UnpackHigh_ro.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\UnpackHigh_ro
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [ConvertToVector128_r.cmd_12161]
 RelativePath=JIT\HardwareIntrinsics\X86\Sse41\ConvertToVector128_r\ConvertToVector128_r.cmd
 WorkingDir=JIT\HardwareIntrinsics\X86\Sse41\ConvertToVector128_r
@@ -93580,14 +93524,6 @@ MaxAllowedDurationSeconds=600
 Categories=EXPECTED_PASS;NEW;EXCLUDED
 HostStyle=0
 
-[PackUnsignedSaturate_r.cmd_12172]
-RelativePath=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_r\PackUnsignedSaturate_r.cmd
-WorkingDir=JIT\HardwareIntrinsics\X86\Sse2\PackUnsignedSaturate_r
-Expected=0
-MaxAllowedDurationSeconds=600
-Categories=EXPECTED_PASS;NEW;EXCLUDED
-HostStyle=0
-
 [genericcontext.cmd_12173]
 RelativePath=Regressions\coreclr\15241\genericcontext\genericcontext.cmd
 WorkingDir=Regressions\coreclr\15241\genericcontext
index 191d0bf..469dddb 100644 (file)
@@ -203,6 +203,9 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "(ushort)(left[0] | right[0]) != result[0]",                                                                                          ["ValidateRemainingResults"] = "(ushort)(left[i] | right[i]) != result[i]"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "(uint)(left[0] | right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(uint)(left[i] | right[i]) != result[i]"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or",                                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "(ulong)(left[0] | right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(ulong)(left[i] | right[i]) != result[i]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "PackSignedSaturate",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["ValidateFirstResult"] = "result[0] != (short)Math.Min(Math.Max(left[0], short.MinValue), short.MaxValue)",                                                    ["ValidateRemainingResults"] = "result[i] != ((i < 4) ? (short)Math.Min(Math.Max(left[i], short.MinValue), short.MaxValue) : (short)Math.Min(Math.Max(right[i%4], short.MinValue), short.MaxValue))"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "PackSignedSaturate",                       ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "result[0] != (sbyte)Math.Min(Math.Max(left[0], sbyte.MinValue), sbyte.MaxValue)",                                                    ["ValidateRemainingResults"] = "result[i] != ((i < 8) ? (sbyte)Math.Min(Math.Max(left[i], sbyte.MinValue), sbyte.MaxValue) : (sbyte)Math.Min(Math.Max(right[i%8], sbyte.MinValue), sbyte.MaxValue))"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "PackUnsignedSaturate",                     ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "result[0] != (byte)Math.Min(Math.Max(left[0], byte.MinValue), byte.MaxValue)",                                                       ["ValidateRemainingResults"] = "result[i] != ((i < 8) ? (byte)Math.Min(Math.Max(left[i], byte.MinValue), byte.MaxValue) : (byte)Math.Min(Math.Max(right[i%8], byte.MinValue), byte.MaxValue))"}),
     ("ScalarSimdUnOpTest.template",     new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",                                                                                                         ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",                                                           ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
     ("ScalarSimdUnOpTest.template",     new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
     ("ScalarSimdUnOpTest.template",     new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128",                          ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",                                                                                                        ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",                                                          ["ValidateFirstResult"] = "result[0] != firstOp",                                                                                                               ["ValidateRemainingResults"] = "result[i] != firstOp"}),
@@ -270,6 +273,24 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate",                         ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "Sse2Verify.SubtractSaturate(left[0], right[0], result[0])",                                                                          ["ValidateRemainingResults"] = "Sse2Verify.SubtractSaturate(left[i], right[i], result[i])"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractSaturate",                         ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "Sse2Verify.SubtractSaturate(left[0], right[0], result[0])",                                                                          ["ValidateRemainingResults"] = "Sse2Verify.SubtractSaturate(left[i], right[i], result[i])"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SubtractScalar",                           ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])",                                    ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[1])",                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i/2+1]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[(i - 1)/2 + 1])"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["ValidateFirstResult"] = "result[0] != left[1] || result[1] != right[1]",                                                                                      ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 1] : result[i] != right[(i - 1)/2 + 1]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[1] || result[1] != right[1]",                                                                                      ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 1] : result[i] != right[(i - 1)/2 + 1]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["ValidateFirstResult"] = "result[0] != left[2]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 2] : result[i] != right[(i - 1)/2 + 2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[2]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 2] : result[i] != right[(i - 1)/2 + 2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "result[0] != left[4]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 4] : result[i] != right[(i - 1)/2 + 4]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != left[4]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 4] : result[i] != right[(i - 1)/2 + 4]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["ValidateFirstResult"] = "result[0] != left[8]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 8] : result[i] != right[(i - 1)/2 + 8]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackHigh",                               ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "result[0] != left[8]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2 + 8] : result[i] != right[(i - 1)/2 + 8]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[0])",                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i/2]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[(i - 1)/2])"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",  ["ValidateFirstResult"] = "result[0] != left[0] || result[1] != right[0]",                                                                                      ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "result[0] != left[0] || result[1] != right[0]",                                                                                      ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",  ["ValidateFirstResult"] = "result[0] != left[0]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateFirstResult"] = "result[0] != left[0]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "result[0] != left[0]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateFirstResult"] = "result[0] != left[0]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()",  ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()",  ["ValidateFirstResult"] = "result[0] != left[0]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
+    ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "UnpackLow",                                ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "result[0] != left[0]",                                                                                                               ["ValidateRemainingResults"] = "(i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2]"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double",                                          ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateFirstResult"] = "(BitConverter.DoubleToInt64Bits(left[0]) ^ BitConverter.DoubleToInt64Bits(right[0])) != BitConverter.DoubleToInt64Bits(result[0])",  ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(left[i]) ^ BitConverter.DoubleToInt64Bits(right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte",   ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte",   ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte",                                            ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()",   ["NextValueOp2"] = "TestLibrary.Generator.GetByte()",   ["ValidateFirstResult"] = "(byte)(left[0] ^ right[0]) != result[0]",                                                                                            ["ValidateRemainingResults"] = "(byte)(left[i] ^ right[i]) != result[i]"}),
     ("SimpleBinOpTest.template",        new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor",                                      ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16",  ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16",  ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16",                                           ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",  ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",  ["ValidateFirstResult"] = "(short)(left[0] ^ right[0]) != result[0]",                                                                                           ["ValidateRemainingResults"] = "(short)(left[i] ^ right[i]) != result[i]"}),
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs
new file mode 100644 (file)
index 0000000..02b94e9
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 PackSignedSaturateInt16()
+        {
+            var test = new SimpleBinaryOpTest__PackSignedSaturateInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__PackSignedSaturateInt16
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int32> _fld1;
+            public Vector128<Int32> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__PackSignedSaturateInt16 testClass)
+            {
+                var result = Sse2.PackSignedSaturate(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+
+        private static Int32[] _data1 = new Int32[Op1ElementCount];
+        private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+        private static Vector128<Int32> _clsVar1;
+        private static Vector128<Int32> _clsVar2;
+
+        private Vector128<Int32> _fld1;
+        private Vector128<Int32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int16, Int32, Int32> _dataTable;
+
+        static SimpleBinaryOpTest__PackSignedSaturateInt16()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+        }
+
+        public SimpleBinaryOpTest__PackSignedSaturateInt16()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int32, Int32>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.PackSignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.PackSignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.PackSignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackSignedSaturate), 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<Int16>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackSignedSaturate), 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<Int16>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackSignedSaturate), 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<Int16>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.PackSignedSaturate(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+            var result = Sse2.PackSignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.PackSignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.PackSignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__PackSignedSaturateInt16();
+            var result = Sse2.PackSignedSaturate(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.PackSignedSaturate(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.PackSignedSaturate(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int32[] inArray2 = new Int32[Op2ElementCount];
+            Int16[] outArray = new Int16[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int32[] inArray1 = new Int32[Op1ElementCount];
+            Int32[] inArray2 = new Int32[Op2ElementCount];
+            Int16[] outArray = new Int16[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int32[] left, Int32[] right, Int16[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != (short)Math.Min(Math.Max(left[0], short.MinValue), short.MaxValue))
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if (result[i] != ((i < 4) ? (short)Math.Min(Math.Max(left[i], short.MinValue), short.MaxValue) : (short)Math.Min(Math.Max(right[i%4], short.MinValue), short.MaxValue)))
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.PackSignedSaturate)}<Int16>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs
new file mode 100644 (file)
index 0000000..7f02656
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 PackSignedSaturateSByte()
+        {
+            var test = new SimpleBinaryOpTest__PackSignedSaturateSByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__PackSignedSaturateSByte
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int16> _fld1;
+            public Vector128<Int16> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__PackSignedSaturateSByte testClass)
+            {
+                var result = Sse2.PackSignedSaturate(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+
+        private static Int16[] _data1 = new Int16[Op1ElementCount];
+        private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+        private static Vector128<Int16> _clsVar1;
+        private static Vector128<Int16> _clsVar2;
+
+        private Vector128<Int16> _fld1;
+        private Vector128<Int16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<SByte, Int16, Int16> _dataTable;
+
+        static SimpleBinaryOpTest__PackSignedSaturateSByte()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+        }
+
+        public SimpleBinaryOpTest__PackSignedSaturateSByte()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<SByte, Int16, Int16>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.PackSignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.PackSignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.PackSignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackSignedSaturate), 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<SByte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackSignedSaturate), 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<SByte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackSignedSaturate), 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<SByte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.PackSignedSaturate(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+            var result = Sse2.PackSignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.PackSignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.PackSignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__PackSignedSaturateSByte();
+            var result = Sse2.PackSignedSaturate(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.PackSignedSaturate(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.PackSignedSaturate(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            SByte[] outArray = new SByte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int16[] inArray1 = new Int16[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            SByte[] outArray = new SByte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int16[] left, Int16[] right, SByte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != (sbyte)Math.Min(Math.Max(left[0], sbyte.MinValue), sbyte.MaxValue))
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if (result[i] != ((i < 8) ? (sbyte)Math.Min(Math.Max(left[i], sbyte.MinValue), sbyte.MaxValue) : (sbyte)Math.Min(Math.Max(right[i%8], sbyte.MinValue), sbyte.MaxValue)))
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.PackSignedSaturate)}<SByte>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.cs
deleted file mode 100644 (file)
index ebe447d..0000000
+++ /dev/null
@@ -1,123 +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;
-
-        internal static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.PackSignedSaturate);
-
-            if (Sse2.IsSupported)
-            {
-                using (var intTable = TestTableSse2<int, short>.Create(testsCount, 0.5))
-                using (var shortTable = TestTableSse2<short, sbyte>.Create(testsCount, 0.5))
-                {
-                    intTable.Initialize(InitMode.NumberFirstVectors);
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<int>, Vector128<int>) value = intTable[i];
-                        Vector128<short> result = Sse2.PackSignedSaturate(value.Item1, value.Item2);
-                        intTable.SetOutArrayU(result, i);
-                    }
-
-                    shortTable.Initialize(InitMode.NumberFirstVectors);
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<short>, Vector128<short>) value = shortTable[i];
-                        Vector128<sbyte> result = Sse2.PackSignedSaturate(value.Item1, value.Item2);
-                        shortTable.SetOutArrayU(result);
-                    }
-
-                    CheckMethodSix<int, short> checkInt32 =
-                        (ValueTuple<int, int, int, int> x, ValueTuple<int, int, int, int> y,
-                        ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> z,
-                        ref short a1, ref short a2, ref short a3, ref short a4, ref short a5, ref short a6, ref short a7, ref short a8) =>
-                        {
-                            a1 = ToInt16Saturate(x.Item1);
-                            a2 = ToInt16Saturate(x.Item2);
-                            a3 = ToInt16Saturate(x.Item3);
-                            a4 = ToInt16Saturate(x.Item4);
-                            a5 = ToInt16Saturate(y.Item1);
-                            a6 = ToInt16Saturate(y.Item2);
-                            a7 = ToInt16Saturate(y.Item3);
-                            a8 = ToInt16Saturate(y.Item4);
-                            return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4 &&
-                                a5 == z.Item5 && a6 == z.Item6 && a7 == z.Item7 && a8 == z.Item8;
-                        };
-
-                    if (!intTable.CheckPackSaturate(checkInt32))
-                    {
-                        PrintError(intTable, methodUnderTestName, "CheckPackSaturate", checkInt32);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodSixteen<short, sbyte> checkInt16 =
-                        (ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> x,
-                         ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> y,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> z1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> z2,
-                        ref sbyte a1, ref sbyte a2, ref sbyte a3, ref sbyte a4, ref sbyte a5, ref sbyte a6, ref sbyte a7, ref sbyte a8,
-                        ref sbyte a9, ref sbyte a10, ref sbyte a11, ref sbyte a12, ref sbyte a13, ref sbyte a14, ref sbyte a15, ref sbyte a16) =>
-                        {
-                            a1 = ToSByteSaturate(x.Item1);
-                            a2 = ToSByteSaturate(x.Item2);
-                            a3 = ToSByteSaturate(x.Item3);
-                            a4 = ToSByteSaturate(x.Item4);
-                            a5 = ToSByteSaturate(x.Item5);
-                            a6 = ToSByteSaturate(x.Item6);
-                            a7 = ToSByteSaturate(x.Item7);
-                            a8 = ToSByteSaturate(x.Item8);
-                            a9 = ToSByteSaturate(y.Item1);
-                            a10 = ToSByteSaturate(y.Item2);
-                            a11 = ToSByteSaturate(y.Item3);
-                            a12 = ToSByteSaturate(y.Item4);
-                            a13 = ToSByteSaturate(y.Item5);
-                            a14 = ToSByteSaturate(y.Item6);
-                            a15 = ToSByteSaturate(y.Item7);
-                            a16 = ToSByteSaturate(y.Item8);
-
-                            return a1 == z1.Item1 && a2 == z1.Item2 && a3 == z1.Item3 && a4 == z1.Item4 &&
-                                a5 == z1.Item5 && a6 == z1.Item6 && a7 == z1.Item7 && a8 == z1.Item8 &&
-                                a9 == z2.Item1 && a10 == z2.Item2 && a11 == z2.Item3 && a12 == z2.Item4 &&
-                                a13 == z2.Item5 && a14 == z2.Item6 && a15 == z2.Item7 && a16 == z2.Item8;
-                        };
-
-
-                    if (!shortTable.CheckPackSaturate(checkInt16))
-                    {
-                        PrintError(shortTable, methodUnderTestName, "CheckPackSaturate", checkInt16);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-            return testResult;
-        }
-
-        private static short ToInt16Saturate(int value)
-        {
-            return (short)(value > short.MaxValue ? short.MaxValue : value < short.MinValue ? short.MinValue : value);
-        }
-
-        private static sbyte ToSByteSaturate(short value)
-        {
-            return (sbyte)(value > sbyte.MaxValue ? sbyte.MaxValue : value < sbyte.MinValue ? sbyte.MinValue : value);
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate_r.csproj
deleted file mode 100644 (file)
index 6d91074..0000000
+++ /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>{A0B71B98-843A-4CEB-84D5-EF1058A4830D}</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>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="PackSignedSaturate.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/PackSignedSaturate_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate_ro.csproj
deleted file mode 100644 (file)
index 7ee2401..0000000
+++ /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>{A1A59671-D8A9-4580-9211-9DCB9CDC338F}</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>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="PackSignedSaturate.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/PackUnsignedSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs
new file mode 100644 (file)
index 0000000..2157563
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 PackUnsignedSaturateByte()
+        {
+            var test = new SimpleBinaryOpTest__PackUnsignedSaturateByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__PackUnsignedSaturateByte
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int16> _fld1;
+            public Vector128<Int16> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__PackUnsignedSaturateByte testClass)
+            {
+                var result = Sse2.PackUnsignedSaturate(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+
+        private static Int16[] _data1 = new Int16[Op1ElementCount];
+        private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+        private static Vector128<Int16> _clsVar1;
+        private static Vector128<Int16> _clsVar2;
+
+        private Vector128<Int16> _fld1;
+        private Vector128<Int16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Byte, Int16, Int16> _dataTable;
+
+        static SimpleBinaryOpTest__PackUnsignedSaturateByte()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+        }
+
+        public SimpleBinaryOpTest__PackUnsignedSaturateByte()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Int16, Int16>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.PackUnsignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.PackUnsignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.PackUnsignedSaturate(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackUnsignedSaturate), 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<Byte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackUnsignedSaturate), 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<Byte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunReflectionScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.PackUnsignedSaturate), 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<Byte>)(result));
+            ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+        }
+
+        public void RunClsVarScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.PackUnsignedSaturate(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+            var result = Sse2.PackUnsignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.PackUnsignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.PackUnsignedSaturate(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__PackUnsignedSaturateByte();
+            var result = Sse2.PackUnsignedSaturate(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.PackUnsignedSaturate(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.PackUnsignedSaturate(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int16[] inArray1 = new Int16[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int16[] left, Int16[] right, Byte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != (byte)Math.Min(Math.Max(left[0], byte.MinValue), byte.MaxValue))
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if (result[i] != ((i < 8) ? (byte)Math.Min(Math.Max(left[i], byte.MinValue), byte.MaxValue) : (byte)Math.Min(Math.Max(right[i%8], byte.MinValue), byte.MaxValue)))
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.PackUnsignedSaturate)}<Byte>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.cs
deleted file mode 100644 (file)
index c0e6a08..0000000
+++ /dev/null
@@ -1,85 +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;
-
-        internal static unsafe int Main(string[] args)
-        {
-            int testResult = Pass;
-            int testsCount = 21;
-            string methodUnderTestName = nameof(Sse2.PackUnsignedSaturate);
-
-            if (Sse2.IsSupported)
-            {
-                using (var shortTable = TestTableSse2<short, byte>.Create(testsCount, 0.5))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<short>, Vector128<short>) value = shortTable[i];
-                        Vector128<byte> result = Sse2.PackUnsignedSaturate(value.Item1, value.Item2);
-                        shortTable.SetOutArrayU(result);
-                    }
-
-                    CheckMethodSixteen<short, byte> checkInt16 =
-                        (ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> x,
-                        ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> y,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> z1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> z2,
-                        ref byte a1, ref byte a2, ref byte a3, ref byte a4, ref byte a5, ref byte a6, ref byte a7, ref byte a8,
-                        ref byte a9, ref byte a10, ref byte a11, ref byte a12, ref byte a13, ref byte a14, ref byte a15, ref byte a16) =>
-                    {
-                        a1 = ToByteSaturate(x.Item1);
-                        a2 = ToByteSaturate(x.Item2);
-                        a3 = ToByteSaturate(x.Item3);
-                        a4 = ToByteSaturate(x.Item4);
-                        a5 = ToByteSaturate(x.Item5);
-                        a6 = ToByteSaturate(x.Item6);
-                        a7 = ToByteSaturate(x.Item7);
-                        a8 = ToByteSaturate(x.Item8);
-                        a9 = ToByteSaturate(y.Item1);
-                        a10 = ToByteSaturate(y.Item2);
-                        a11 = ToByteSaturate(y.Item3);
-                        a12 = ToByteSaturate(y.Item4);
-                        a13 = ToByteSaturate(y.Item5);
-                        a14 = ToByteSaturate(y.Item6);
-                        a15 = ToByteSaturate(y.Item7);
-                        a16 = ToByteSaturate(y.Item8);
-
-                        return a1 == z1.Item1 && a2 == z1.Item2 && a3 == z1.Item3 && a4 == z1.Item4 &&
-                            a5 == z1.Item5 && a6 == z1.Item6 && a7 == z1.Item7 && a8 == z1.Item8 &&
-                            a9 == z2.Item1 && a10 == z2.Item2 && a11 == z2.Item3 && a12 == z2.Item4 &&
-                            a13 == z2.Item5 && a14 == z2.Item6 && a15 == z2.Item7 && a16 == z2.Item8;
-                    };
-
-                    if (!shortTable.CheckPackSaturate(checkInt16))
-                    {
-                        PrintError(shortTable, methodUnderTestName, "CheckPackSaturate", checkInt16);
-                        testResult = Fail;
-                    }
-                }
-            }
-            else
-            {
-                Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
-            }
-
-            return testResult;
-        }
-
-        private static byte ToByteSaturate(short value)
-        {
-            return (byte)(value > byte.MaxValue ? byte.MaxValue : value < 0 ? 0 : value);
-        }
-    }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate_r.csproj
deleted file mode 100644 (file)
index 18ba828..0000000
+++ /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>{A11D2E47-7AA7-4D13-9087-39785BB82D7C}</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>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="PackUnsignedSaturate.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/PackUnsignedSaturate_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate_ro.csproj
deleted file mode 100644 (file)
index 382124d..0000000
+++ /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>{C8295B8E-35C4-4A29-8BF7-44A1F9525ACC}</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>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="PackUnsignedSaturate.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
index d654dff..aacdaa3 100644 (file)
@@ -138,6 +138,9 @@ namespace JIT.HardwareIntrinsics.X86
                 ["Or.UInt16"] = OrUInt16,
                 ["Or.UInt32"] = OrUInt32,
                 ["Or.UInt64"] = OrUInt64,
+                ["PackSignedSaturate.Int16"] = PackSignedSaturateInt16,
+                ["PackSignedSaturate.SByte"] = PackSignedSaturateSByte,
+                ["PackUnsignedSaturate.Byte"] = PackUnsignedSaturateByte,
                 ["SetAllVector128.Byte"] = SetAllVector128Byte,
                 ["SetAllVector128.SByte"] = SetAllVector128SByte,
                 ["SetAllVector128.Int16"] = SetAllVector128Int16,
@@ -205,6 +208,24 @@ namespace JIT.HardwareIntrinsics.X86
                 ["SubtractSaturate.Int16"] = SubtractSaturateInt16,
                 ["SubtractSaturate.UInt16"] = SubtractSaturateUInt16,
                 ["SubtractScalar.Double"] = SubtractScalarDouble,
+                ["UnpackHigh.Double"] = UnpackHighDouble,
+                ["UnpackHigh.Int64"] = UnpackHighInt64,
+                ["UnpackHigh.UInt64"] = UnpackHighUInt64,
+                ["UnpackHigh.Int32"] = UnpackHighInt32,
+                ["UnpackHigh.UInt32"] = UnpackHighUInt32,
+                ["UnpackHigh.Int16"] = UnpackHighInt16,
+                ["UnpackHigh.UInt16"] = UnpackHighUInt16,
+                ["UnpackHigh.SByte"] = UnpackHighSByte,
+                ["UnpackHigh.Byte"] = UnpackHighByte,
+                ["UnpackLow.Double"] = UnpackLowDouble,
+                ["UnpackLow.Int64"] = UnpackLowInt64,
+                ["UnpackLow.UInt64"] = UnpackLowUInt64,
+                ["UnpackLow.Int32"] = UnpackLowInt32,
+                ["UnpackLow.UInt32"] = UnpackLowUInt32,
+                ["UnpackLow.Int16"] = UnpackLowInt16,
+                ["UnpackLow.UInt16"] = UnpackLowUInt16,
+                ["UnpackLow.SByte"] = UnpackLowSByte,
+                ["UnpackLow.Byte"] = UnpackLowByte,
                 ["Xor.Double"] = XorDouble,
                 ["Xor.Byte"] = XorByte,
                 ["Xor.Int16"] = XorInt16,
index 982745a..b9101fc 100644 (file)
@@ -40,7 +40,7 @@
     <Compile Include="AddSaturate.SByte.cs"/>
     <Compile Include="AddSaturate.Int16.cs"/>
     <Compile Include="AddSaturate.UInt16.cs"/>
-    <Compile Include="AddScalar.Double.cs"/>        
+    <Compile Include="AddScalar.Double.cs"/>
     <Compile Include="And.Double.cs" />
     <Compile Include="And.Byte.cs" />
     <Compile Include="And.Int16.cs" />
     <Compile Include="Or.UInt16.cs" />
     <Compile Include="Or.UInt32.cs" />
     <Compile Include="Or.UInt64.cs" />
+    <Compile Include="PackSignedSaturate.Int16.cs" />
+    <Compile Include="PackSignedSaturate.SByte.cs" />
+    <Compile Include="PackUnsignedSaturate.Byte.cs" />
     <Compile Include="SetAllVector128.Byte.cs" />
     <Compile Include="SetAllVector128.SByte.cs" />
     <Compile Include="SetAllVector128.Int16.cs" />
     <Compile Include="SubtractSaturate.SByte.cs"/>
     <Compile Include="SubtractSaturate.Int16.cs"/>
     <Compile Include="SubtractSaturate.UInt16.cs"/>
-    <Compile Include="SubtractScalar.Double.cs" />     
+    <Compile Include="SubtractScalar.Double.cs" />
+    <Compile Include="UnpackHigh.Double.cs" />
+    <Compile Include="UnpackHigh.Int64.cs" />
+    <Compile Include="UnpackHigh.UInt64.cs" />
+    <Compile Include="UnpackHigh.Int32.cs" />
+    <Compile Include="UnpackHigh.UInt32.cs" />
+    <Compile Include="UnpackHigh.Int16.cs" />
+    <Compile Include="UnpackHigh.UInt16.cs" />
+    <Compile Include="UnpackHigh.SByte.cs" />
+    <Compile Include="UnpackHigh.Byte.cs" />
+    <Compile Include="UnpackLow.Double.cs" />
+    <Compile Include="UnpackLow.Int64.cs" />
+    <Compile Include="UnpackLow.UInt64.cs" />
+    <Compile Include="UnpackLow.Int32.cs" />
+    <Compile Include="UnpackLow.UInt32.cs" />
+    <Compile Include="UnpackLow.Int16.cs" />
+    <Compile Include="UnpackLow.UInt16.cs" />
+    <Compile Include="UnpackLow.SByte.cs" />
+    <Compile Include="UnpackLow.Byte.cs" />
     <Compile Include="Xor.Double.cs" />
     <Compile Include="Xor.Byte.cs" />
     <Compile Include="Xor.Int16.cs" />
     <Compile Include="Xor.UInt64.cs" />
     <Compile Include="Program.Sse2.cs" />
     <Compile Include="..\Shared\Program.cs" />
-    <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />    
+    <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />
     <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
     <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
     <Compile Include="..\Shared\ScalarSimdUnOpTest_DataTable.cs" />
index 0aef213..563bc43 100644 (file)
@@ -40,7 +40,7 @@
     <Compile Include="AddSaturate.Int16.cs"/>
     <Compile Include="AddSaturate.SByte.cs"/>
     <Compile Include="AddSaturate.UInt16.cs"/>
-    <Compile Include="AddScalar.Double.cs"/> 
+    <Compile Include="AddScalar.Double.cs"/>
     <Compile Include="And.Byte.cs" />
     <Compile Include="And.Double.cs" />
     <Compile Include="And.Int16.cs" />
@@ -60,7 +60,7 @@
     <Compile Include="AndNot.UInt32.cs" />
     <Compile Include="AndNot.UInt64.cs" />
     <Compile Include="Average.Byte.cs"/>
-    <Compile Include="Average.UInt16.cs"/> 
+    <Compile Include="Average.UInt16.cs"/>
     <Compile Include="CompareEqual.Byte.cs" />
     <Compile Include="CompareEqual.Double.cs" />
     <Compile Include="CompareEqual.Int16.cs" />
     <Compile Include="ConvertToVector128Int32WithTruncation.Vector128Double.cs" />
     <Compile Include="ConvertToVector128Int32WithTruncation.Vector128Single.cs" />
     <Compile Include="ConvertToVector128Single.Vector128Double.cs" />
-    <Compile Include="ConvertToVector128Single.Vector128Int32.cs" />    
+    <Compile Include="ConvertToVector128Single.Vector128Int32.cs" />
     <Compile Include="Divide.Double.cs" />
     <Compile Include="DivideScalar.Double.cs" />
     <Compile Include="Extract.UInt16.1.cs" />
     <Compile Include="Or.UInt16.cs" />
     <Compile Include="Or.UInt32.cs" />
     <Compile Include="Or.UInt64.cs" />
+    <Compile Include="PackSignedSaturate.Int16.cs" />
+    <Compile Include="PackSignedSaturate.SByte.cs" />
+    <Compile Include="PackUnsignedSaturate.Byte.cs" />
     <Compile Include="Program.Sse2.cs" />
     <Compile Include="SetAllVector128.Byte.cs" />
-    <Compile Include="SetAllVector128.Double.cs" /> 
+    <Compile Include="SetAllVector128.Double.cs" />
     <Compile Include="SetAllVector128.Int16.cs" />
     <Compile Include="SetAllVector128.Int32.cs" />
     <Compile Include="SetAllVector128.Int64.cs" />
     <Compile Include="SubtractSaturate.Int16.cs"/>
     <Compile Include="SubtractSaturate.SByte.cs"/>
     <Compile Include="SubtractSaturate.UInt16.cs"/>
-    <Compile Include="SubtractScalar.Double.cs" /> 
+    <Compile Include="SubtractScalar.Double.cs" />
+    <Compile Include="UnpackHigh.Double.cs" />
+    <Compile Include="UnpackHigh.Int64.cs" />
+    <Compile Include="UnpackHigh.UInt64.cs" />
+    <Compile Include="UnpackHigh.Int32.cs" />
+    <Compile Include="UnpackHigh.UInt32.cs" />
+    <Compile Include="UnpackHigh.Int16.cs" />
+    <Compile Include="UnpackHigh.UInt16.cs" />
+    <Compile Include="UnpackHigh.SByte.cs" />
+    <Compile Include="UnpackHigh.Byte.cs" />
+    <Compile Include="UnpackLow.Double.cs" />
+    <Compile Include="UnpackLow.Int64.cs" />
+    <Compile Include="UnpackLow.UInt64.cs" />
+    <Compile Include="UnpackLow.Int32.cs" />
+    <Compile Include="UnpackLow.UInt32.cs" />
+    <Compile Include="UnpackLow.Int16.cs" />
+    <Compile Include="UnpackLow.UInt16.cs" />
+    <Compile Include="UnpackLow.SByte.cs" />
+    <Compile Include="UnpackLow.Byte.cs" />
     <Compile Include="Xor.Byte.cs" />
     <Compile Include="Xor.Double.cs" />
     <Compile Include="Xor.Int16.cs" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs
new file mode 100644 (file)
index 0000000..c2b1de0
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighByte()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighByte
+    {
+        private struct TestStruct
+        {
+            public Vector128<Byte> _fld1;
+            public Vector128<Byte> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighByte testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+
+        private static Byte[] _data1 = new Byte[Op1ElementCount];
+        private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+        private static Vector128<Byte> _clsVar1;
+        private static Vector128<Byte> _clsVar2;
+
+        private Vector128<Byte> _fld1;
+        private Vector128<Byte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighByte()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighByte()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighByte();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Byte[] inArray2 = new Byte[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Byte[] inArray1 = new Byte[Op1ElementCount];
+            Byte[] inArray2 = new Byte[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[8])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 8] : result[i] != right[(i - 1)/2 + 8])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs
new file mode 100644 (file)
index 0000000..04babb5
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighDouble()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighDouble testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighDouble();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[1]))
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i/2+1]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[(i - 1)/2 + 1]))
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs
new file mode 100644 (file)
index 0000000..ab6dc39
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighInt16()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighInt16
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int16> _fld1;
+            public Vector128<Int16> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighInt16 testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+
+        private static Int16[] _data1 = new Int16[Op1ElementCount];
+        private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+        private static Vector128<Int16> _clsVar1;
+        private static Vector128<Int16> _clsVar2;
+
+        private Vector128<Int16> _fld1;
+        private Vector128<Int16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighInt16()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighInt16()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighInt16();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            Int16[] outArray = new Int16[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int16[] inArray1 = new Int16[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            Int16[] outArray = new Int16[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[4])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 4] : result[i] != right[(i - 1)/2 + 4])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs
new file mode 100644 (file)
index 0000000..4d6994b
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighInt32()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighInt32();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighInt32
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int32> _fld1;
+            public Vector128<Int32> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighInt32 testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+
+        private static Int32[] _data1 = new Int32[Op1ElementCount];
+        private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+        private static Vector128<Int32> _clsVar1;
+        private static Vector128<Int32> _clsVar2;
+
+        private Vector128<Int32> _fld1;
+        private Vector128<Int32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighInt32()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighInt32()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighInt32();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int32[] inArray2 = new Int32[Op2ElementCount];
+            Int32[] outArray = new Int32[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int32[] inArray1 = new Int32[Op1ElementCount];
+            Int32[] inArray2 = new Int32[Op2ElementCount];
+            Int32[] outArray = new Int32[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[2])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 2] : result[i] != right[(i - 1)/2 + 2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs
new file mode 100644 (file)
index 0000000..8c6cfca
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighInt64()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighInt64();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighInt64
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighInt64 testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
+
+        private static Int64[] _data1 = new Int64[Op1ElementCount];
+        private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+        private static Vector128<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighInt64()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighInt64()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighInt64();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int64[] inArray2 = new Int64[Op2ElementCount];
+            Int64[] outArray = new Int64[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int64[] inArray1 = new Int64[Op1ElementCount];
+            Int64[] inArray2 = new Int64[Op2ElementCount];
+            Int64[] outArray = new Int64[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[1] || result[1] != right[1])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 1] : result[i] != right[(i - 1)/2 + 1])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs
new file mode 100644 (file)
index 0000000..098acf7
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighSByte()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighSByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighSByte
+    {
+        private struct TestStruct
+        {
+            public Vector128<SByte> _fld1;
+            public Vector128<SByte> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighSByte testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+
+        private static SByte[] _data1 = new SByte[Op1ElementCount];
+        private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+        private static Vector128<SByte> _clsVar1;
+        private static Vector128<SByte> _clsVar2;
+
+        private Vector128<SByte> _fld1;
+        private Vector128<SByte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighSByte()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighSByte()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighSByte();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            SByte[] inArray2 = new SByte[Op2ElementCount];
+            SByte[] outArray = new SByte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            SByte[] inArray1 = new SByte[Op1ElementCount];
+            SByte[] inArray2 = new SByte[Op2ElementCount];
+            SByte[] outArray = new SByte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[8])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 8] : result[i] != right[(i - 1)/2 + 8])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs
new file mode 100644 (file)
index 0000000..cc2939a
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighUInt16()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighUInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighUInt16
+    {
+        private struct TestStruct
+        {
+            public Vector128<UInt16> _fld1;
+            public Vector128<UInt16> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighUInt16 testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
+
+        private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+        private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+        private static Vector128<UInt16> _clsVar1;
+        private static Vector128<UInt16> _clsVar2;
+
+        private Vector128<UInt16> _fld1;
+        private Vector128<UInt16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighUInt16()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighUInt16()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighUInt16();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            UInt16[] inArray2 = new UInt16[Op2ElementCount];
+            UInt16[] outArray = new UInt16[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            UInt16[] inArray1 = new UInt16[Op1ElementCount];
+            UInt16[] inArray2 = new UInt16[Op2ElementCount];
+            UInt16[] outArray = new UInt16[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[4])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 4] : result[i] != right[(i - 1)/2 + 4])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs
new file mode 100644 (file)
index 0000000..7ca7a2e
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighUInt32()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighUInt32();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighUInt32
+    {
+        private struct TestStruct
+        {
+            public Vector128<UInt32> _fld1;
+            public Vector128<UInt32> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighUInt32 testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
+
+        private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+        private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+        private static Vector128<UInt32> _clsVar1;
+        private static Vector128<UInt32> _clsVar2;
+
+        private Vector128<UInt32> _fld1;
+        private Vector128<UInt32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighUInt32()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighUInt32()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighUInt32();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            UInt32[] inArray2 = new UInt32[Op2ElementCount];
+            UInt32[] outArray = new UInt32[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            UInt32[] inArray1 = new UInt32[Op1ElementCount];
+            UInt32[] inArray2 = new UInt32[Op2ElementCount];
+            UInt32[] outArray = new UInt32[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[2])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 2] : result[i] != right[(i - 1)/2 + 2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs
new file mode 100644 (file)
index 0000000..83e0d92
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackHighUInt64()
+        {
+            var test = new SimpleBinaryOpTest__UnpackHighUInt64();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackHighUInt64
+    {
+        private struct TestStruct
+        {
+            public Vector128<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackHighUInt64 testClass)
+            {
+                var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
+
+        private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+        private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+        private static Vector128<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackHighUInt64()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackHighUInt64()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackHigh(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackHigh), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackHigh(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackHigh(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackHighUInt64();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackHigh(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackHigh(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            UInt64[] inArray2 = new UInt64[Op2ElementCount];
+            UInt64[] outArray = new UInt64[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            UInt64[] inArray1 = new UInt64[Op1ElementCount];
+            UInt64[] inArray2 = new UInt64[Op2ElementCount];
+            UInt64[] outArray = new UInt64[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[1] || result[1] != right[1])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2 + 1] : result[i] != right[(i - 1)/2 + 1])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackHigh)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.cs
deleted file mode 100644 (file)
index 768299f..0000000
+++ /dev/null
@@ -1,302 +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.UnpackHigh);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableSse2<double, double>.Create(testsCount, 1.0))
-                using (var longTable = TestTableSse2<long, long>.Create(testsCount, 1.0))
-                using (var ulongTable = TestTableSse2<ulong, ulong>.Create(testsCount, 1.0))
-                using (var intTable = TestTableSse2<int, int>.Create(testsCount, 1.0))
-                using (var uintTable = TestTableSse2<uint, uint>.Create(testsCount, 1.0))
-                using (var shortTable = TestTableSse2<short, short>.Create(testsCount, 1.0))
-                using (var ushortTable = TestTableSse2<ushort, ushort>.Create(testsCount, 1.0))
-                using (var sbyteTable = TestTableSse2<sbyte, sbyte>.Create(testsCount, 1.0))
-                using (var byteTable = TestTableSse2<byte, byte>.Create(testsCount, 1.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        Vector128<double> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<long>, Vector128<long>) value = longTable[i];
-                        Vector128<long> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        longTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
-                        Vector128<ulong> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        ulongTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<int>, Vector128<int>) value = intTable[i];
-                        Vector128<int> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        intTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<uint>, Vector128<uint>) value = uintTable[i];
-                        Vector128<uint> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        uintTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<short>, Vector128<short>) value = shortTable[i];
-                        Vector128<short> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        shortTable.SetOutArray(result);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
-                        Vector128<ushort> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        ushortTable.SetOutArray(result);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
-                        Vector128<sbyte> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        sbyteTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<byte>, Vector128<byte>) value = byteTable[i];
-                        Vector128<byte> result = Sse2.UnpackHigh(value.Item1, value.Item2);
-                        byteTable.SetOutArray(result, i);
-                    }
-
-                    CheckMethodFive<double, double> checkDouble = (double x1, double x2, double y1, double y2, double z1, double z2, ref double a1, ref double a2) =>
-                    {
-                        return (a1 = x2) == z1 && (a2 = y2) == z2;
-                    };
-
-                    if (!doubleTable.CheckUnpackHiDouble(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseXor(x, y)) == z", checkDouble);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFive<long, long> checkLong = (long x1, long x2, long y1, long y2, long z1, long z2, ref long a1, ref long a2) =>
-                    {
-                        return (a1 = x2) == z1 && (a2 = y2) == z2;
-                    };
-
-                    if (!longTable.CheckUnpackHiDouble(checkLong))
-                    {
-                        PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x ^ y) == z", checkLong);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFive<ulong, ulong> checkUlong = (ulong x1, ulong x2, ulong y1, ulong y2, ulong z1, ulong z2, ref ulong a1, ref ulong a2) =>
-                    {
-                        return (a1 = x2) == z1 && (a2 = y2) == z2;
-                    };
-
-                    if (!longTable.CheckUnpackHiDouble(checkLong))
-                    {
-                        PrintError(ulongTable, methodUnderTestName, "(ulong x1, ulong x2, ulong y1, ulong y2, ulong z1, ulong z2, ref ulong a1, ref ulong a2) => (a1 = x2) == z1 && (a2 = y2) == z2", checkUlong);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFourTFourU<int, int> checkInt32 =
-                        (ValueTuple<int, int, int, int> x, ValueTuple<int, int, int, int> y,
-                        ValueTuple<int, int, int, int> z,
-                        ref int a1, ref int a2, ref int a3, ref int a4) =>
-                    {
-                        a1 = x.Item3;
-                        a2 = y.Item3;
-                        a3 = x.Item4;
-                        a4 = y.Item4;
-                        return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4;
-                    };
-
-                    if (!intTable.CheckUnpack(checkInt32))
-                    {
-                        PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x ^ y) == z", checkInt32);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFourTFourU<uint, uint> checkUInt32 =
-                        (ValueTuple<uint, uint, uint, uint> x, ValueTuple<uint, uint, uint, uint> y,
-                        ValueTuple<uint, uint, uint, uint> z,
-                        ref uint a1, ref uint a2, ref uint a3, ref uint a4) =>
-                        {
-                            a1 = x.Item3;
-                            a2 = y.Item3;
-                            a3 = x.Item4;
-                            a4 = y.Item4;
-                            return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4;
-                        };
-
-                    if (!uintTable.CheckUnpack(checkUInt32))
-                    {
-                        PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x ^ y) == z", checkUInt32);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodEightOfTEightOfU<short, short> checkInt16 =
-                        (ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> x,
-                        ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> y,
-                        ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> z,
-                        ref short a1, ref short a2, ref short a3, ref short a4, ref short a5, ref short a6, ref short a7, ref short a8) =>
-                    {
-                        a1 = x.Item5;
-                        a2 = y.Item5;
-                        a3 = x.Item6;
-                        a4 = y.Item6;
-                        a5 = x.Item7;
-                        a6 = y.Item7;
-                        a7 = x.Item8;
-                        a8 = y.Item8;
-                        return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4 &&
-                            a5 == z.Item5 && a6 == z.Item6 && a7 == z.Item7 && a8 == z.Item8;
-                    };
-
-                    if (!shortTable.CheckUnpack(checkInt16))
-                    {
-                        PrintError(shortTable, methodUnderTestName, "CheckUnpack(CheckMethodEightOfTEightOfU<short, short>)", checkInt16);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodEightOfTEightOfU<ushort, ushort> checkUInt16 =
-                        (ValueTuple<ushort, ushort, ushort, ushort, ushort, ushort, ushort, ValueTuple<ushort>> x,
-                        ValueTuple<ushort, ushort, ushort, ushort, ushort, ushort, ushort, ValueTuple<ushort>> y,
-                        ValueTuple<ushort, ushort, ushort, ushort, ushort, ushort, ushort, ValueTuple<ushort>> z,
-                        ref ushort a1, ref ushort a2, ref ushort a3, ref ushort a4, ref ushort a5, ref ushort a6, ref ushort a7, ref ushort a8) =>
-                    {
-                        a1 = x.Item5;
-                        a2 = y.Item5;
-                        a3 = x.Item6;
-                        a4 = y.Item6;
-                        a5 = x.Item7;
-                        a6 = y.Item7;
-                        a7 = x.Item8;
-                        a8 = y.Item8;
-                        return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4 &&
-                            a5 == z.Item5 && a6 == z.Item6 && a7 == z.Item7 && a8 == z.Item8;
-                    };
-
-                    if (!ushortTable.CheckUnpack(checkUInt16))
-                    {
-                        PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x ^ y)) == z", checkUInt16);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodSixteenOfAll<sbyte, sbyte> checkSByte =
-                        (ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> x1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> x,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> y1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> y,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> z1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> z2,
-                        ref sbyte a1, ref sbyte a2, ref sbyte a3, ref sbyte a4, ref sbyte a5, ref sbyte a6, ref sbyte a7, ref sbyte a8,
-                        ref sbyte a9, ref sbyte a10, ref sbyte a11, ref sbyte a12, ref sbyte a13, ref sbyte a14, ref sbyte a15, ref sbyte a16) =>
-                    {
-                        a1 = x.Item1;
-                        a2 = y.Item1;
-                        a3 = x.Item2;
-                        a4 = y.Item2;
-                        a5 = x.Item3;
-                        a6 = y.Item3;
-                        a7 = x.Item4;
-                        a8 = y.Item4;
-                        a9 = x.Item5;
-                        a10 = y.Item5;
-                        a11 = x.Item6;
-                        a12 = y.Item6;
-                        a13 = x.Item7;
-                        a14 = y.Item7;
-                        a15 = x.Item8;
-                        a16 = y.Item8;
-
-                        return a1 == z1.Item1 && a2 == z1.Item2 && a3 == z1.Item3 && a4 == z1.Item4 &&
-                            a5 == z1.Item5 && a6 == z1.Item6 && a7 == z1.Item7 && a8 == z1.Item8 &&
-                            a9 == z2.Item1 && a10 == z2.Item2 && a11 == z2.Item3 && a12 == z2.Item4 &&
-                            a13 == z2.Item5 && a14 == z2.Item6 && a15 == z2.Item7 && a16 == z2.Item8;
-                    };
-
-                    if (!sbyteTable.CheckUnpack(checkSByte))
-                    {
-                        PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x ^ y)) == z", checkSByte);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodSixteenOfAll<byte, byte> checkByte =
-                        (ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> x1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> x,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> y1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> y,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> z1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> z2,
-                        ref byte a1, ref byte a2, ref byte a3, ref byte a4, ref byte a5, ref byte a6, ref byte a7, ref byte a8,
-                        ref byte a9, ref byte a10, ref byte a11, ref byte a12, ref byte a13, ref byte a14, ref byte a15, ref byte a16) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            a5 = x.Item3;
-                            a6 = y.Item3;
-                            a7 = x.Item4;
-                            a8 = y.Item4;
-                            a9 = x.Item5;
-                            a10 = y.Item5;
-                            a11 = x.Item6;
-                            a12 = y.Item6;
-                            a13 = x.Item7;
-                            a14 = y.Item7;
-                            a15 = x.Item8;
-                            a16 = y.Item8;
-
-                            return a1 == z1.Item1 && a2 == z1.Item2 && a3 == z1.Item3 && a4 == z1.Item4 &&
-                                a5 == z1.Item5 && a6 == z1.Item6 && a7 == z1.Item7 && a8 == z1.Item8 &&
-                                a9 == z2.Item1 && a10 == z2.Item2 && a11 == z2.Item3 && a12 == z2.Item4 &&
-                                a13 == z2.Item5 && a14 == z2.Item6 && a15 == z2.Item7 && a16 == z2.Item8;
-                        };
-
-                    if (!byteTable.CheckUnpack(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/UnpackHigh_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh_r.csproj
deleted file mode 100644 (file)
index 25dd8fd..0000000
+++ /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>{1D430B7E-0A5B-4D0F-8F6F-7138D12FD57E}</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>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="TestTableSse2.cs" />
-    <Compile Include="UnpackHigh.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/UnpackHigh_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh_ro.csproj
deleted file mode 100644 (file)
index c5ebd44..0000000
+++ /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>{D72FD8F6-CCE9-4026-ABA8-67862FE5ECB8}</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>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="TestTableSse2.cs" />
-    <Compile Include="UnpackHigh.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/UnpackLow.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs
new file mode 100644 (file)
index 0000000..4815b01
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowByte()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowByte
+    {
+        private struct TestStruct
+        {
+            public Vector128<Byte> _fld1;
+            public Vector128<Byte> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowByte testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
+
+        private static Byte[] _data1 = new Byte[Op1ElementCount];
+        private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+        private static Vector128<Byte> _clsVar1;
+        private static Vector128<Byte> _clsVar2;
+
+        private Vector128<Byte> _fld1;
+        private Vector128<Byte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowByte()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowByte()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowByte();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Byte[] inArray2 = new Byte[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Byte[] inArray1 = new Byte[Op1ElementCount];
+            Byte[] inArray2 = new Byte[Op2ElementCount];
+            Byte[] outArray = new Byte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs
new file mode 100644 (file)
index 0000000..8287924
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowDouble()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowDouble();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowDouble
+    {
+        private struct TestStruct
+        {
+            public Vector128<Double> _fld1;
+            public Vector128<Double> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowDouble testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
+
+        private static Double[] _data1 = new Double[Op1ElementCount];
+        private static Double[] _data2 = new Double[Op2ElementCount];
+
+        private static Vector128<Double> _clsVar1;
+        private static Vector128<Double> _clsVar2;
+
+        private Vector128<Double> _fld1;
+        private Vector128<Double> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowDouble()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowDouble()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowDouble();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Double[] inArray1 = new Double[Op1ElementCount];
+            Double[] inArray2 = new Double[Op2ElementCount];
+            Double[] outArray = new Double[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+        {
+            if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[0]))
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i/2]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[(i - 1)/2]))
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs
new file mode 100644 (file)
index 0000000..97b939b
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowInt16()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowInt16
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int16> _fld1;
+            public Vector128<Int16> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowInt16 testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
+
+        private static Int16[] _data1 = new Int16[Op1ElementCount];
+        private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+        private static Vector128<Int16> _clsVar1;
+        private static Vector128<Int16> _clsVar2;
+
+        private Vector128<Int16> _fld1;
+        private Vector128<Int16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowInt16()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowInt16()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowInt16();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            Int16[] outArray = new Int16[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int16[] inArray1 = new Int16[Op1ElementCount];
+            Int16[] inArray2 = new Int16[Op2ElementCount];
+            Int16[] outArray = new Int16[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs
new file mode 100644 (file)
index 0000000..f31b341
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowInt32()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowInt32();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowInt32
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int32> _fld1;
+            public Vector128<Int32> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowInt32 testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
+
+        private static Int32[] _data1 = new Int32[Op1ElementCount];
+        private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+        private static Vector128<Int32> _clsVar1;
+        private static Vector128<Int32> _clsVar2;
+
+        private Vector128<Int32> _fld1;
+        private Vector128<Int32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowInt32()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowInt32()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowInt32();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int32[] inArray2 = new Int32[Op2ElementCount];
+            Int32[] outArray = new Int32[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int32[] inArray1 = new Int32[Op1ElementCount];
+            Int32[] inArray2 = new Int32[Op2ElementCount];
+            Int32[] outArray = new Int32[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs
new file mode 100644 (file)
index 0000000..8cd4d81
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowInt64()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowInt64();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowInt64
+    {
+        private struct TestStruct
+        {
+            public Vector128<Int64> _fld1;
+            public Vector128<Int64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowInt64 testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
+
+        private static Int64[] _data1 = new Int64[Op1ElementCount];
+        private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+        private static Vector128<Int64> _clsVar1;
+        private static Vector128<Int64> _clsVar2;
+
+        private Vector128<Int64> _fld1;
+        private Vector128<Int64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowInt64()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowInt64()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowInt64();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            Int64[] inArray2 = new Int64[Op2ElementCount];
+            Int64[] outArray = new Int64[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            Int64[] inArray1 = new Int64[Op1ElementCount];
+            Int64[] inArray2 = new Int64[Op2ElementCount];
+            Int64[] outArray = new Int64[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0] || result[1] != right[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs
new file mode 100644 (file)
index 0000000..77a11e2
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowSByte()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowSByte();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowSByte
+    {
+        private struct TestStruct
+        {
+            public Vector128<SByte> _fld1;
+            public Vector128<SByte> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowSByte testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
+
+        private static SByte[] _data1 = new SByte[Op1ElementCount];
+        private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+        private static Vector128<SByte> _clsVar1;
+        private static Vector128<SByte> _clsVar2;
+
+        private Vector128<SByte> _fld1;
+        private Vector128<SByte> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowSByte()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowSByte()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowSByte();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            SByte[] inArray2 = new SByte[Op2ElementCount];
+            SByte[] outArray = new SByte[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            SByte[] inArray1 = new SByte[Op1ElementCount];
+            SByte[] inArray2 = new SByte[Op2ElementCount];
+            SByte[] outArray = new SByte[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs
new file mode 100644 (file)
index 0000000..0cbe160
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowUInt16()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowUInt16();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowUInt16
+    {
+        private struct TestStruct
+        {
+            public Vector128<UInt16> _fld1;
+            public Vector128<UInt16> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowUInt16 testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
+
+        private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+        private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+        private static Vector128<UInt16> _clsVar1;
+        private static Vector128<UInt16> _clsVar2;
+
+        private Vector128<UInt16> _fld1;
+        private Vector128<UInt16> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowUInt16()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowUInt16()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowUInt16();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            UInt16[] inArray2 = new UInt16[Op2ElementCount];
+            UInt16[] outArray = new UInt16[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            UInt16[] inArray1 = new UInt16[Op1ElementCount];
+            UInt16[] inArray2 = new UInt16[Op2ElementCount];
+            UInt16[] outArray = new UInt16[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs
new file mode 100644 (file)
index 0000000..420afbb
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowUInt32()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowUInt32();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowUInt32
+    {
+        private struct TestStruct
+        {
+            public Vector128<UInt32> _fld1;
+            public Vector128<UInt32> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowUInt32 testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
+
+        private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+        private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+        private static Vector128<UInt32> _clsVar1;
+        private static Vector128<UInt32> _clsVar2;
+
+        private Vector128<UInt32> _fld1;
+        private Vector128<UInt32> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowUInt32()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowUInt32()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowUInt32();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            UInt32[] inArray2 = new UInt32[Op2ElementCount];
+            UInt32[] outArray = new UInt32[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            UInt32[] inArray1 = new UInt32[Op1ElementCount];
+            UInt32[] inArray2 = new UInt32[Op2ElementCount];
+            UInt32[] outArray = new UInt32[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs
new file mode 100644 (file)
index 0000000..756c03e
--- /dev/null
@@ -0,0 +1,403 @@
+// 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 UnpackLowUInt64()
+        {
+            var test = new SimpleBinaryOpTest__UnpackLowUInt64();
+
+            if (test.IsSupported)
+            {
+                // Validates basic functionality works, using Unsafe.Read
+                test.RunBasicScenario_UnsafeRead();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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();
+
+                if (Sse2.IsSupported)
+                {
+                    // 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 class works
+                test.RunClassLclFldScenario();
+
+                // Validates passing an instance member of a class works
+                test.RunClassFldScenario();
+
+                // Validates passing the field of a local struct works
+                test.RunStructLclFldScenario();
+
+                // Validates passing an instance member of a struct works
+                test.RunStructFldScenario();
+            }
+            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__UnpackLowUInt64
+    {
+        private struct TestStruct
+        {
+            public Vector128<UInt64> _fld1;
+            public Vector128<UInt64> _fld2;
+
+            public static TestStruct Create()
+            {
+                var testStruct = new TestStruct();
+
+                for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+                for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+                Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+                return testStruct;
+            }
+
+            public void RunStructFldScenario(SimpleBinaryOpTest__UnpackLowUInt64 testClass)
+            {
+                var result = Sse2.UnpackLow(_fld1, _fld2);
+
+                Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+                testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+            }
+        }
+
+        private static readonly int LargestVectorSize = 16;
+
+        private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
+        private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
+        private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
+
+        private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+        private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+        private static Vector128<UInt64> _clsVar1;
+        private static Vector128<UInt64> _clsVar2;
+
+        private Vector128<UInt64> _fld1;
+        private Vector128<UInt64> _fld2;
+
+        private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+        static SimpleBinaryOpTest__UnpackLowUInt64()
+        {
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+        }
+
+        public SimpleBinaryOpTest__UnpackLowUInt64()
+        {
+            Succeeded = true;
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+            for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
+            _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+        }
+
+        public bool IsSupported => Sse2.IsSupported;
+
+        public bool Succeeded { get; set; }
+
+        public void RunBasicScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
+
+            var result = Sse2.UnpackLow(
+                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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
+
+            var result = typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), 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()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
+
+            var result = Sse2.UnpackLow(
+                _clsVar1,
+                _clsVar2
+            );
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_UnsafeRead()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
+
+            var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+            var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_Load()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
+
+            var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunLclVarScenario_LoadAligned()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
+
+            var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+            var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+            var result = Sse2.UnpackLow(left, right);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(left, right, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
+
+            var test = new SimpleBinaryOpTest__UnpackLowUInt64();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunClassFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
+
+            var result = Sse2.UnpackLow(_fld1, _fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructLclFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
+
+            var test = TestStruct.Create();
+            var result = Sse2.UnpackLow(test._fld1, test._fld2);
+
+            Unsafe.Write(_dataTable.outArrayPtr, result);
+            ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+        }
+
+        public void RunStructFldScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
+
+            var test = TestStruct.Create();
+            test.RunStructFldScenario(this);
+        }
+
+        public void RunUnsupportedScenario()
+        {
+            TestLibrary.TestFramework.BeginScenario(nameof(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[Op1ElementCount];
+            UInt64[] inArray2 = new UInt64[Op2ElementCount];
+            UInt64[] outArray = new UInt64[RetElementCount];
+
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
+            Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+        {
+            UInt64[] inArray1 = new UInt64[Op1ElementCount];
+            UInt64[] inArray2 = new UInt64[Op2ElementCount];
+            UInt64[] outArray = new UInt64[RetElementCount];
+
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+            Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+
+            ValidateResult(inArray1, inArray2, outArray, method);
+        }
+
+        private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+        {
+            if (result[0] != left[0] || result[1] != right[0])
+            {
+                Succeeded = false;
+            }
+            else
+            {
+                for (var i = 1; i < RetElementCount; i++)
+                {
+                    if ((i % 2 == 0) ? result[i] != left[i/2] : result[i] != right[(i - 1)/2])
+                    {
+                        Succeeded = false;
+                        break;
+                    }
+                }
+            }
+
+            if (!Succeeded)
+            {
+                TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.UnpackLow)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
+                TestLibrary.TestFramework.LogInformation($"    left: ({string.Join(", ", left)})");
+                TestLibrary.TestFramework.LogInformation($"   right: ({string.Join(", ", right)})");
+                TestLibrary.TestFramework.LogInformation($"  result: ({string.Join(", ", result)})");
+                TestLibrary.TestFramework.LogInformation(string.Empty);
+            }
+        }
+    }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.cs
deleted file mode 100644 (file)
index 91a716c..0000000
+++ /dev/null
@@ -1,302 +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.UnpackLow);
-
-            if (Sse2.IsSupported)
-            {
-                using (var doubleTable = TestTableSse2<double, double>.Create(testsCount, 1.0))
-                using (var longTable = TestTableSse2<long, long>.Create(testsCount, 1.0))
-                using (var ulongTable = TestTableSse2<ulong, ulong>.Create(testsCount, 1.0))
-                using (var intTable = TestTableSse2<int, int>.Create(testsCount, 1.0))
-                using (var uintTable = TestTableSse2<uint, uint>.Create(testsCount, 1.0))
-                using (var shortTable = TestTableSse2<short, short>.Create(testsCount, 1.0))
-                using (var ushortTable = TestTableSse2<ushort, ushort>.Create(testsCount, 1.0))
-                using (var sbyteTable = TestTableSse2<sbyte, sbyte>.Create(testsCount, 1.0))
-                using (var byteTable = TestTableSse2<byte, byte>.Create(testsCount, 1.0))
-                {
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<double>, Vector128<double>) value = doubleTable[i];
-                        Vector128<double> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        doubleTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<long>, Vector128<long>) value = longTable[i];
-                        Vector128<long> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        longTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<ulong>, Vector128<ulong>) value = ulongTable[i];
-                        Vector128<ulong> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        ulongTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<int>, Vector128<int>) value = intTable[i];
-                        Vector128<int> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        intTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<uint>, Vector128<uint>) value = uintTable[i];
-                        Vector128<uint> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        uintTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<short>, Vector128<short>) value = shortTable[i];
-                        Vector128<short> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        shortTable.SetOutArray(result);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
-                        Vector128<ushort> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        ushortTable.SetOutArray(result);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
-                        Vector128<sbyte> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        sbyteTable.SetOutArray(result, i);
-                    }
-
-                    for (int i = 0; i < testsCount; i++)
-                    {
-                        (Vector128<byte>, Vector128<byte>) value = byteTable[i];
-                        Vector128<byte> result = Sse2.UnpackLow(value.Item1, value.Item2);
-                        byteTable.SetOutArray(result, i);
-                    }
-
-                    CheckMethodFive<double, double> checkDouble = (double x1, double x2, double y1, double y2, double z1, double z2, ref double a1, ref double a2) =>
-                    {
-                        return (a1 = x1) == z1 && (a2 = y1) == z2;
-                    };
-
-                    if (!doubleTable.CheckUnpackHiDouble(checkDouble))
-                    {
-                        PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseXor(x, y)) == z", checkDouble);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFive<long, long> checkLong = (long x1, long x2, long y1, long y2, long z1, long z2, ref long a1, ref long a2) =>
-                    {
-                        return (a1 = x1) == z1 && (a2 = y1) == z2;
-                    };
-
-                    if (!longTable.CheckUnpackHiDouble(checkLong))
-                    {
-                        PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x ^ y) == z", checkLong);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFive<ulong, ulong> checkUlong = (ulong x1, ulong x2, ulong y1, ulong y2, ulong z1, ulong z2, ref ulong a1, ref ulong a2) =>
-                    {
-                        return (a1 = x1) == z1 && (a2 = y1) == z2;
-                    };
-
-                    if (!longTable.CheckUnpackHiDouble(checkLong))
-                    {
-                        PrintError(ulongTable, methodUnderTestName, "(ulong x1, ulong x2, ulong y1, ulong y2, ulong z1, ulong z2, ref ulong a1, ref ulong a2) => (a1 = x2) == z1 && (a2 = y2) == z2", checkUlong);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFourTFourU<int, int> checkInt32 =
-                        (ValueTuple<int, int, int, int> x, ValueTuple<int, int, int, int> y,
-                        ValueTuple<int, int, int, int> z,
-                        ref int a1, ref int a2, ref int a3, ref int a4) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4;
-                        };
-
-                    if (!intTable.CheckUnpack(checkInt32))
-                    {
-                        PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x ^ y) == z", checkInt32);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodFourTFourU<uint, uint> checkUInt32 =
-                        (ValueTuple<uint, uint, uint, uint> x, ValueTuple<uint, uint, uint, uint> y,
-                        ValueTuple<uint, uint, uint, uint> z,
-                        ref uint a1, ref uint a2, ref uint a3, ref uint a4) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4;
-                        };
-
-                    if (!uintTable.CheckUnpack(checkUInt32))
-                    {
-                        PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x ^ y) == z", checkUInt32);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodEightOfTEightOfU<short, short> checkInt16 =
-                        (ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> x,
-                        ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> y,
-                        ValueTuple<short, short, short, short, short, short, short, ValueTuple<short>> z,
-                        ref short a1, ref short a2, ref short a3, ref short a4, ref short a5, ref short a6, ref short a7, ref short a8) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            a5 = x.Item3;
-                            a6 = y.Item3;
-                            a7 = x.Item4;
-                            a8 = y.Item4;
-                            return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4 &&
-                                a5 == z.Item5 && a6 == z.Item6 && a7 == z.Item7 && a8 == z.Item8;
-                        };
-
-                    if (!shortTable.CheckUnpack(checkInt16))
-                    {
-                        PrintError(shortTable, methodUnderTestName, "CheckUnpack(CheckMethodEightOfTEightOfU<short, short>)", checkInt16);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodEightOfTEightOfU<ushort, ushort> checkUInt16 =
-                        (ValueTuple<ushort, ushort, ushort, ushort, ushort, ushort, ushort, ValueTuple<ushort>> x,
-                        ValueTuple<ushort, ushort, ushort, ushort, ushort, ushort, ushort, ValueTuple<ushort>> y,
-                        ValueTuple<ushort, ushort, ushort, ushort, ushort, ushort, ushort, ValueTuple<ushort>> z,
-                        ref ushort a1, ref ushort a2, ref ushort a3, ref ushort a4, ref ushort a5, ref ushort a6, ref ushort a7, ref ushort a8) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            a5 = x.Item3;
-                            a6 = y.Item3;
-                            a7 = x.Item4;
-                            a8 = y.Item4;
-                            return a1 == z.Item1 && a2 == z.Item2 && a3 == z.Item3 && a4 == z.Item4 &&
-                                a5 == z.Item5 && a6 == z.Item6 && a7 == z.Item7 && a8 == z.Item8;
-                        };
-
-                    if (!ushortTable.CheckUnpack(checkUInt16))
-                    {
-                        PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x ^ y)) == z", checkUInt16);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodSixteenOfAll<sbyte, sbyte> checkSByte =
-                        (ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> x,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> x1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> y,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> y1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> z1,
-                        ValueTuple<sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, sbyte, ValueTuple<sbyte>> z2,
-                        ref sbyte a1, ref sbyte a2, ref sbyte a3, ref sbyte a4, ref sbyte a5, ref sbyte a6, ref sbyte a7, ref sbyte a8,
-                        ref sbyte a9, ref sbyte a10, ref sbyte a11, ref sbyte a12, ref sbyte a13, ref sbyte a14, ref sbyte a15, ref sbyte a16) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            a5 = x.Item3;
-                            a6 = y.Item3;
-                            a7 = x.Item4;
-                            a8 = y.Item4;
-                            a9 = x.Item5;
-                            a10 = y.Item5;
-                            a11 = x.Item6;
-                            a12 = y.Item6;
-                            a13 = x.Item7;
-                            a14 = y.Item7;
-                            a15 = x.Item8;
-                            a16 = y.Item8;
-
-                            return a1 == z1.Item1 && a2 == z1.Item2 && a3 == z1.Item3 && a4 == z1.Item4 &&
-                                a5 == z1.Item5 && a6 == z1.Item6 && a7 == z1.Item7 && a8 == z1.Item8 &&
-                                a9 == z2.Item1 && a10 == z2.Item2 && a11 == z2.Item3 && a12 == z2.Item4 &&
-                                a13 == z2.Item5 && a14 == z2.Item6 && a15 == z2.Item7 && a16 == z2.Item8;
-                        };
-
-                    if (!sbyteTable.CheckUnpack(checkSByte))
-                    {
-                        PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x ^ y)) == z", checkSByte);
-                        testResult = Fail;
-                    }
-
-                    CheckMethodSixteenOfAll<byte, byte> checkByte =
-                        (ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> x,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> x1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> y,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> y1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> z1,
-                        ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<byte>> z2,
-                        ref byte a1, ref byte a2, ref byte a3, ref byte a4, ref byte a5, ref byte a6, ref byte a7, ref byte a8,
-                        ref byte a9, ref byte a10, ref byte a11, ref byte a12, ref byte a13, ref byte a14, ref byte a15, ref byte a16) =>
-                        {
-                            a1 = x.Item1;
-                            a2 = y.Item1;
-                            a3 = x.Item2;
-                            a4 = y.Item2;
-                            a5 = x.Item3;
-                            a6 = y.Item3;
-                            a7 = x.Item4;
-                            a8 = y.Item4;
-                            a9 = x.Item5;
-                            a10 = y.Item5;
-                            a11 = x.Item6;
-                            a12 = y.Item6;
-                            a13 = x.Item7;
-                            a14 = y.Item7;
-                            a15 = x.Item8;
-                            a16 = y.Item8;
-
-                            return a1 == z1.Item1 && a2 == z1.Item2 && a3 == z1.Item3 && a4 == z1.Item4 &&
-                                a5 == z1.Item5 && a6 == z1.Item6 && a7 == z1.Item7 && a8 == z1.Item8 &&
-                                a9 == z2.Item1 && a10 == z2.Item2 && a11 == z2.Item3 && a12 == z2.Item4 &&
-                                a13 == z2.Item5 && a14 == z2.Item6 && a15 == z2.Item7 && a16 == z2.Item8;
-                        };
-
-                    if (!byteTable.CheckUnpack(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/UnpackLow_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow_r.csproj
deleted file mode 100644 (file)
index 7b2ad44..0000000
+++ /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>{FC28F10A-3F47-43E8-AEE5-DFCE881F19EF}</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>Embedded</DebugType>
-    <Optimize></Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="TestTableSse2.cs" />
-    <Compile Include="UnpackLow.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/UnpackLow_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow_ro.csproj
deleted file mode 100644 (file)
index 030ee6f..0000000
+++ /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>{929ECE5C-8D63-4677-B5A6-C52543F41798}</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>Embedded</DebugType>
-    <Optimize>True</Optimize>
-  </PropertyGroup>
-  <ItemGroup>
-    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="TestTableSse2.cs" />
-    <Compile Include="UnpackLow.cs" />
-  </ItemGroup>
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
-  </PropertyGroup>
-</Project>
\ No newline at end of file