summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Carlos Aguilera Mendez <juanam@microsoft.com>2018-03-16 09:50:50 -0700
committerJuan Carlos Aguilera Mendez <juanam@microsoft.com>2018-03-16 09:50:50 -0700
commitf7823fb541745735d7566dfb376d9fd7c750c7a8 (patch)
treead2c68d0ac2c2de568f88cd7dc96dd7c12695a01
parent8b54e0b93f795ba983ce2f4b99ed85769ef25d03 (diff)
parented49badc8baf90bca56b2df0b98eb20355d9a998 (diff)
downloadcoreclr-f7823fb541745735d7566dfb376d9fd7c750c7a8.tar.gz
coreclr-f7823fb541745735d7566dfb376d9fd7c750c7a8.tar.bz2
coreclr-f7823fb541745735d7566dfb376d9fd7c750c7a8.zip
Merge branch 'master' of https://github.com/dotnet/coreclr
-rw-r--r--ILAsmVersion.txt2
-rw-r--r--buildpipeline/pipelines.json204
-rw-r--r--buildpipeline/tests/test_pipelines.json8
-rw-r--r--dependencies.props10
-rw-r--r--src/jit/codegenlinear.h3
-rw-r--r--src/jit/compiler.h12
-rw-r--r--src/jit/hwintrinsiccodegenxarch.cpp114
-rw-r--r--src/jit/hwintrinsiclistxarch.h4
-rw-r--r--src/jit/hwintrinsicxarch.cpp63
-rw-r--r--src/jit/importer.cpp13
-rw-r--r--src/jit/instrsxarch.h4
-rw-r--r--src/jit/namedintrinsiclist.h9
-rw-r--r--src/mscorlib/shared/System.Private.CoreLib.Shared.projitems1
-rw-r--r--src/mscorlib/shared/System/Globalization/CompareInfo.cs34
-rw-r--r--src/mscorlib/shared/System/Globalization/TextInfo.cs70
-rw-r--r--src/mscorlib/shared/System/Marvin.cs115
-rw-r--r--src/mscorlib/shared/System/StringComparer.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs263
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj52
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj52
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.20.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.11.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.6.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.3.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.20.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.11.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.6.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.1.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.3.cs309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.20.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.11.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.6.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.3.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.20.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.11.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.6.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.1.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.3.cs321
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128.Avx.cs38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128_r.csproj (renamed from tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_ro.csproj)37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128_ro.csproj (renamed from tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_ro.csproj)39
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.cs346
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs52
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj32
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj32
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.Store.cs297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.cs313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.Load.cs339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.cs338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs32
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractStoreTest.template297
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractVector128Test.template313
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx423
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertLoadTest.template339
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertVector128Test.template338
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest.template253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest_DataTable.cs59
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.cs127
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.cs56
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.cs69
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average_r.csproj41
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.cs56
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.cs56
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.cs56
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.cs55
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs25
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Byte.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Double.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int16.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int32.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int64.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.SByte.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt16.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt32.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt64.cs253
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs301
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs81
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj27
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj27
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.cs127
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_ro.csproj37
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs330
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.cs56
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_r.csproj38
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_ro.csproj37
-rw-r--r--tests/src/performance/Scenario/JitBench/Benchmarks/WebAppBenchmarks.cs (renamed from tests/src/performance/Scenario/JitBench/Benchmarks/MusicStoreBenchmark.cs)103
-rw-r--r--tests/src/performance/Scenario/JitBench/Runner/Benchmark.cs3
197 files changed, 43991 insertions, 2197 deletions
diff --git a/ILAsmVersion.txt b/ILAsmVersion.txt
index 6b4c2cd6b4..8d80ec5b70 100644
--- a/ILAsmVersion.txt
+++ b/ILAsmVersion.txt
@@ -1 +1 @@
-2.1.0-preview2-26315-02
+2.1.0-preview2-26316-03
diff --git a/buildpipeline/pipelines.json b/buildpipeline/pipelines.json
index e48305dcd4..b38243fdcc 100644
--- a/buildpipeline/pipelines.json
+++ b/buildpipeline/pipelines.json
@@ -141,6 +141,21 @@
"Architecture": "arm",
"PB_BuildType": null
}
+ },
+ {
+ "Name": "DotNet-CoreClr-Trusted-Linux-Crossbuild",
+ "Parameters": {
+ "DockerTag": "ubuntu-16.04-cross-arm64-a3ae44b-20180315221921",
+ "Architecture": "arm64",
+ "Rid": "linux"
+ },
+ "ReportingParameters": {
+ "OperatingSystem": "Linux",
+ "SubType": "PortableCrossBuild",
+ "Type": "build/product/",
+ "Architecture": "arm64",
+ "PB_BuildType": null
+ }
}
]
}
@@ -352,195 +367,6 @@
"Trusted-All-Checked",
"Trusted-Crossbuild-Checked"
]
- },
- {
- "Name": "Build And Run Tests - Release",
- "Parameters": {
- "TreatWarningsAsErrors": "false"
- },
- "BuildParameters": {
- "PB_BuildType": "Release"
- },
- "Definitions": [
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/cli/",
- "TargetsWindows": "true",
- "Rid": "win-x64",
- "TargetQueues": "Windows.10.Amd64,Windows.10.Nano.Amd64,Windows.10.Amd64.Core,Windows.7.Amd64,Windows.81.Amd64",
- "TestContainerSuffix": "windows",
- },
- "ReportingParameters": {
- "OperatingSystem": "Windows",
- "SubType": "Build-Tests",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/r2r/cli/",
- "TargetsWindows": "true",
- "Rid": "win-x64",
- "TargetQueues": "Windows.10.Amd64,Windows.10.Nano.Amd64,Windows.10.Amd64.Core,Windows.7.Amd64,Windows.81.Amd64",
- "TestContainerSuffix": "windows-r2r",
- "CrossgenArg": "Crossgen "
- },
- "ReportingParameters": {
- "OperatingSystem": "Windows",
- "SubType": "Build-Tests-R2R",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "Architecture": "arm",
- "HelixJobType": "test/functional/cli/",
- "TargetsWindows": "true",
- "Rid": "win-arm",
- "TargetQueues": "windows.10.arm64",
- "TestContainerSuffix": "windows",
- },
- "ReportingParameters": {
- "OperatingSystem": "Windows",
- "Architecture": "arm64",
- "SubType": "Build-Tests",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "Architecture": "arm",
- "HelixJobType": "test/functional/r2r/cli/",
- "TargetsWindows": "true",
- "Rid": "win-arm",
- "TargetQueues": "windows.10.arm64",
- "TestContainerSuffix": "windows-r2r",
- "CrossgenArg": "Crossgen "
- },
- "ReportingParameters": {
- "OperatingSystem": "Windows",
- "Architecture": "arm64",
- "SubType": "Build-Tests-R2R",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/cli/",
- "TargetsWindows": "false",
- "Rid": "osx-x64",
- "TargetQueues": "osx.1012.amd64,osx.1013.amd64",
- "TestContainerSuffix": "osx",
- "TargetsNonWindowsArg": "TargetsNonWindows "
- },
- "ReportingParameters": {
- "OperatingSystem": "OSX",
- "SubType": "Build-Tests",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/r2r/cli/",
- "TargetsWindows": "false",
- "Rid": "osx-x64",
- "TargetQueues": "osx.1012.amd64,osx.1013.amd64",
- "TestContainerSuffix": "osx-r2r",
- "CrossgenArg": "Crossgen ",
- "TargetsNonWindowsArg": "TargetsNonWindows "
- },
- "ReportingParameters": {
- "OperatingSystem": "OSX",
- "SubType": "Build-Tests-R2R",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/cli/",
- "TargetsWindows": "false",
- "Rid": "linux-x64",
- "TargetQueues": "debian.82.amd64,fedora.26.amd64,fedora.27.amd64,redhat.73.amd64,ubuntu.1404.amd64,ubuntu.1604.amd64,ubuntu.1710.amd64,ubuntu.1804.amd64,opensuse.423.amd64,sles.12.amd64",
- "TestContainerSuffix": "linux",
- "TargetsNonWindowsArg": "TargetsNonWindows "
- },
- "ReportingParameters": {
- "OperatingSystem": "RedHat 7",
- "SubType": "Build-Tests",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/r2r/cli/",
- "TargetsWindows": "false",
- "Rid": "linux-x64",
- "TargetQueues": "debian.82.amd64,fedora.26.amd64,fedora.27.amd64,redhat.73.amd64,ubuntu.1404.amd64,ubuntu.1604.amd64,ubuntu.1710.amd64,ubuntu.1804.amd64,opensuse.423.amd64,sles.12.amd64",
- "TestContainerSuffix": "linux-r2r",
- "CrossgenArg": "Crossgen ",
- "TargetsNonWindowsArg": "TargetsNonWindows "
- },
- "ReportingParameters": {
- "OperatingSystem": "RedHat 7",
- "SubType": "Build-Tests-R2R",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/cli/",
- "TargetsWindows": "false",
- "Rid": "rhel.6-x64",
- "TargetQueues": "redhat.69.amd64",
- "TestContainerSuffix": "rhel6",
- "TargetsNonWindowsArg": "TargetsNonWindows "
- },
- "ReportingParameters": {
- "OperatingSystem": "RedHat6",
- "SubType": "Build-Tests",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- },
- {
- "Name": "Dotnet-CoreClr-Trusted-BuildTests",
- "Parameters": {
- "HelixJobType": "test/functional/r2r/cli/",
- "TargetsWindows": "false",
- "Rid": "rhel.6-x64",
- "TargetQueues": "redhat.69.amd64",
- "TestContainerSuffix": "rhel6-r2r",
- "CrossgenArg": "Crossgen ",
- "TargetsNonWindowsArg": "TargetsNonWindows "
- },
- "ReportingParameters": {
- "OperatingSystem": "RedHat6",
- "SubType": "Build-Tests-R2R",
- "Type": "build/product/",
- "PB_BuildType": "Release"
- }
- }
- ],
- "DependsOn": [
- "Trusted-All-Release"
- ]
}
]
}
diff --git a/buildpipeline/tests/test_pipelines.json b/buildpipeline/tests/test_pipelines.json
index b4f1ed905b..cd93561a92 100644
--- a/buildpipeline/tests/test_pipelines.json
+++ b/buildpipeline/tests/test_pipelines.json
@@ -92,7 +92,7 @@
"HelixJobType": "test/functional/cli/",
"TargetsWindows": "false",
"Rid": "osx-x64",
- "TargetQueues": "osx.1012.amd64",
+ "TargetQueues": "osx.1012.amd64,osx.1013.amd64",
"TestContainerSuffix": "osx",
"TargetsNonWindowsArg": "TargetsNonWindows "
},
@@ -109,7 +109,7 @@
"HelixJobType": "test/functional/r2r/cli/",
"TargetsWindows": "false",
"Rid": "osx-x64",
- "TargetQueues": "osx.1012.amd64",
+ "TargetQueues": "osx.1012.amd64,osx.1013.amd64",
"TestContainerSuffix": "osx-r2r",
"CrossgenArg": "Crossgen ",
"TargetsNonWindowsArg": "TargetsNonWindows "
@@ -127,7 +127,7 @@
"HelixJobType": "test/functional/cli/",
"TargetsWindows": "false",
"Rid": "linux-x64",
- "TargetQueues": "debian.82.amd64,fedora.25.amd64,redhat.72.amd64,ubuntu.1404.amd64,ubuntu.1604.amd64,ubuntu.1710.amd64",
+ "TargetQueues": "debian.82.amd64,fedora.26.amd64,fedora.27.amd64,redhat.73.amd64,ubuntu.1404.amd64,ubuntu.1604.amd64,ubuntu.1710.amd64,ubuntu.1804.amd64,opensuse.423.amd64,sles.12.amd64",
"TestContainerSuffix": "linux",
"TargetsNonWindowsArg": "TargetsNonWindows "
},
@@ -144,7 +144,7 @@
"HelixJobType": "test/functional/r2r/cli/",
"TargetsWindows": "false",
"Rid": "linux-x64",
- "TargetQueues": "debian.82.amd64,fedora.25.amd64,redhat.72.amd64,ubuntu.1404.amd64,ubuntu.1604.amd64,ubuntu.1710.amd64",
+ "TargetQueues": "debian.82.amd64,fedora.26.amd64,fedora.27.amd64,redhat.73.amd64,ubuntu.1404.amd64,ubuntu.1604.amd64,ubuntu.1710.amd64,ubuntu.1804.amd64,opensuse.423.amd64,sles.12.amd64",
"TestContainerSuffix": "linux-r2r",
"CrossgenArg": "Crossgen ",
"TargetsNonWindowsArg": "TargetsNonWindows "
diff --git a/dependencies.props b/dependencies.props
index b0df0dd1c3..43c4f57f8d 100644
--- a/dependencies.props
+++ b/dependencies.props
@@ -23,18 +23,18 @@
<!-- Source of truth for dependency tooling: the commit hash of the dotnet/versions master branch as of the last auto-upgrade. -->
<PropertyGroup>
- <CoreFxCurrentRef>a51129608e40c42e24fc100cd93d763516bc4c47</CoreFxCurrentRef>
- <CoreClrCurrentRef>a51129608e40c42e24fc100cd93d763516bc4c47</CoreClrCurrentRef>
+ <CoreFxCurrentRef>fc1fbe0b638a97baf2aa3bf403a7db7dbfc0b8b5</CoreFxCurrentRef>
+ <CoreClrCurrentRef>fc1fbe0b638a97baf2aa3bf403a7db7dbfc0b8b5</CoreClrCurrentRef>
<BuildToolsCurrentRef>0e6f6fa6b335fa1e0c26c6f24031003cb2d48b81</BuildToolsCurrentRef>
<PgoDataCurrentRef>553f30357d08df4ed6d32f70f3478a76f5db79c2</PgoDataCurrentRef>
</PropertyGroup>
<!-- Tests/infrastructure dependency versions. -->
<PropertyGroup>
- <MicrosoftPrivateCoreFxNETCoreAppPackageVersion>4.5.0-preview2-26315-01</MicrosoftPrivateCoreFxNETCoreAppPackageVersion>
- <MicrosoftNETCorePlatformsPackageVersion>2.1.0-preview2-26315-01</MicrosoftNETCorePlatformsPackageVersion>
+ <MicrosoftPrivateCoreFxNETCoreAppPackageVersion>4.5.0-preview2-26316-03</MicrosoftPrivateCoreFxNETCoreAppPackageVersion>
+ <MicrosoftNETCorePlatformsPackageVersion>2.1.0-preview2-26316-03</MicrosoftNETCorePlatformsPackageVersion>
<PgoDataPackageVersion>99.99.99-master-20180228-0037</PgoDataPackageVersion>
- <MicrosoftNETCoreRuntimeCoreCLRPackageVersion>2.1.0-preview2-26315-02</MicrosoftNETCoreRuntimeCoreCLRPackageVersion>
+ <MicrosoftNETCoreRuntimeCoreCLRPackageVersion>2.1.0-preview2-26316-03</MicrosoftNETCoreRuntimeCoreCLRPackageVersion>
<XunitPackageVersion>2.2.0-beta2-build3300</XunitPackageVersion>
<XunitConsoleNetcorePackageVersion>1.0.2-prerelease-00177</XunitConsoleNetcorePackageVersion>
<XunitPerformanceApiPackageVersion>1.0.0-beta-build0015</XunitPerformanceApiPackageVersion>
diff --git a/src/jit/codegenlinear.h b/src/jit/codegenlinear.h
index c36e4230c8..7ef7e95d10 100644
--- a/src/jit/codegenlinear.h
+++ b/src/jit/codegenlinear.h
@@ -123,8 +123,7 @@ void genSSEIntrinsic(GenTreeHWIntrinsic* node);
void genSSE2Intrinsic(GenTreeHWIntrinsic* node);
void genSSE41Intrinsic(GenTreeHWIntrinsic* node);
void genSSE42Intrinsic(GenTreeHWIntrinsic* node);
-void genAVXIntrinsic(GenTreeHWIntrinsic* node);
-void genAVX2Intrinsic(GenTreeHWIntrinsic* node);
+void genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node);
void genAESIntrinsic(GenTreeHWIntrinsic* node);
void genBMI1Intrinsic(GenTreeHWIntrinsic* node);
void genBMI2Intrinsic(GenTreeHWIntrinsic* node);
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 1eb0fe5916..f1c9529205 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -3063,14 +3063,10 @@ protected:
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
bool mustExpand);
- GenTree* impAVXIntrinsic(NamedIntrinsic intrinsic,
- CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
- bool mustExpand);
- GenTree* impAVX2Intrinsic(NamedIntrinsic intrinsic,
- CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
- bool mustExpand);
+ GenTree* impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic,
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_SIG_INFO* sig,
+ bool mustExpand);
GenTree* impAESIntrinsic(NamedIntrinsic intrinsic,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
diff --git a/src/jit/hwintrinsiccodegenxarch.cpp b/src/jit/hwintrinsiccodegenxarch.cpp
index 873f1c6dec..d19fe8000c 100644
--- a/src/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/jit/hwintrinsiccodegenxarch.cpp
@@ -252,10 +252,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
genSSE42Intrinsic(node);
break;
case InstructionSet_AVX:
- genAVXIntrinsic(node);
- break;
case InstructionSet_AVX2:
- genAVX2Intrinsic(node);
+ genAvxOrAvx2Intrinsic(node);
break;
case InstructionSet_AES:
genAESIntrinsic(node);
@@ -1269,24 +1267,30 @@ void CodeGen::genSSE42Intrinsic(GenTreeHWIntrinsic* node)
}
//------------------------------------------------------------------------
-// genAVXIntrinsic: Generates the code for an AVX hardware intrinsic node
+// genAvxOrAvx2Intrinsic: Generates the code for an AVX/AVX2 hardware intrinsic node
//
// Arguments:
// node - The hardware intrinsic node
//
-void CodeGen::genAVXIntrinsic(GenTreeHWIntrinsic* node)
+void CodeGen::genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node)
{
NamedIntrinsic intrinsicID = node->gtHWIntrinsicId;
var_types baseType = node->gtSIMDBaseType;
emitAttr attr = EA_ATTR(node->gtSIMDSize);
var_types targetType = node->TypeGet();
instruction ins = Compiler::insOfHWIntrinsic(intrinsicID, baseType);
+ int numArgs = Compiler::numArgsOfHWIntrinsic(node);
GenTree* op1 = node->gtGetOp1();
GenTree* op2 = node->gtGetOp2();
+ regNumber op1Reg = REG_NA;
+ regNumber op2Reg = REG_NA;
regNumber targetReg = node->gtRegNum;
emitter* emit = getEmitter();
- genConsumeOperands(node);
+ if ((op1 != nullptr) && !op1->OperIsList())
+ {
+ genConsumeOperands(node);
+ }
switch (intrinsicID)
{
@@ -1357,30 +1361,88 @@ void CodeGen::genAVXIntrinsic(GenTreeHWIntrinsic* node)
break;
}
- default:
- unreached();
- break;
- }
+ case NI_AVX_ExtractVector128:
+ case NI_AVX_InsertVector128:
+ case NI_AVX2_ExtractVector128:
+ case NI_AVX2_InsertVector128:
+ {
+ GenTree* lastOp = nullptr;
+ if (numArgs == 2)
+ {
+ assert(intrinsicID == NI_AVX_ExtractVector128 || NI_AVX_ExtractVector128);
+ op1Reg = op1->gtRegNum;
+ op2Reg = op2->gtRegNum;
+ lastOp = op2;
+ }
+ else
+ {
+ assert(numArgs == 3);
+ assert(op1->OperIsList());
+ assert(op1->gtGetOp2()->OperIsList());
+ assert(op1->gtGetOp2()->gtGetOp2()->OperIsList());
- genProduceReg(node);
-}
+ GenTreeArgList* argList = op1->AsArgList();
+ op1 = argList->Current();
+ genConsumeRegs(op1);
+ op1Reg = op1->gtRegNum;
-//------------------------------------------------------------------------
-// genAVX2Intrinsic: Generates the code for an AVX2 hardware intrinsic node
-//
-// Arguments:
-// node - The hardware intrinsic node
-//
-void CodeGen::genAVX2Intrinsic(GenTreeHWIntrinsic* node)
-{
- NamedIntrinsic intrinsicID = node->gtHWIntrinsicId;
- var_types baseType = node->gtSIMDBaseType;
- instruction ins = INS_invalid;
+ argList = argList->Rest();
+ op2 = argList->Current();
+ genConsumeRegs(op2);
+ op2Reg = op2->gtRegNum;
- genConsumeOperands(node);
+ argList = argList->Rest();
+ lastOp = argList->Current();
+ genConsumeRegs(lastOp);
+ }
+
+ regNumber op3Reg = lastOp->gtRegNum;
+
+ auto emitSwCase = [&](unsigned i) {
+ // TODO-XARCH-Bug the emitter cannot work with imm8 >= 128,
+ // so clear the 8th bit that is not used by the instructions
+ i &= 0x7FU;
+ if (numArgs == 3)
+ {
+ if (intrinsicID == NI_AVX_ExtractVector128 || intrinsicID == NI_AVX2_ExtractVector128)
+ {
+ emit->emitIns_R_AR_I(ins, attr, op2Reg, op1Reg, 0, (int)i);
+ }
+ else if (op2->TypeGet() == TYP_I_IMPL)
+ {
+ emit->emitIns_SIMD_R_R_AR_I(ins, attr, targetReg, op1Reg, op2Reg, (int)i);
+ }
+ else
+ {
+ assert(op2->TypeGet() == TYP_SIMD16);
+ emit->emitIns_SIMD_R_R_R_I(ins, attr, targetReg, op1Reg, op2Reg, (int)i);
+ }
+ }
+ else
+ {
+ assert(numArgs == 2);
+ assert(intrinsicID == NI_AVX_ExtractVector128 || intrinsicID == NI_AVX2_ExtractVector128);
+ emit->emitIns_SIMD_R_R_I(ins, attr, targetReg, op1Reg, (int)i);
+ }
+ };
+
+ if (lastOp->IsCnsIntOrI())
+ {
+ ssize_t ival = lastOp->AsIntCon()->IconValue();
+ emitSwCase((unsigned)ival);
+ }
+ else
+ {
+ // We emit a fallback case for the scenario when the imm-op is not a constant. This should
+ // normally happen when the intrinsic is called indirectly, such as via Reflection. However, it
+ // can also occur if the consumer calls it directly and just doesn't pass a constant value.
+ regNumber baseReg = node->ExtractTempReg();
+ regNumber offsReg = node->GetSingleTempReg();
+ genHWIntrinsicJumpTableFallback(intrinsicID, op3Reg, baseReg, offsReg, emitSwCase);
+ }
+ break;
+ }
- switch (intrinsicID)
- {
default:
unreached();
break;
diff --git a/src/jit/hwintrinsiclistxarch.h b/src/jit/hwintrinsiclistxarch.h
index c8c611f56d..7435c286fa 100644
--- a/src/jit/hwintrinsiclistxarch.h
+++ b/src/jit/hwintrinsiclistxarch.h
@@ -348,10 +348,12 @@ HARDWARE_INTRINSIC(AVX_DotProduct, "DotProduct
HARDWARE_INTRINSIC(AVX_DuplicateEvenIndexed, "DuplicateEvenIndexed", AVX, -1, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movsldup, INS_movddup}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX_DuplicateOddIndexed, "DuplicateOddIndexed", AVX, -1, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movshdup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX_ExtendToVector256, "ExtendToVector256", AVX, -1, 32, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movaps, INS_movapd}, HW_Category_Helper, HW_Flag_OneTypeGeneric|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(AVX_ExtractVector128, "ExtractVector128", AVX, -1, 32, -1, {INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128, INS_vextractf128},HW_Category_IMM, HW_Flag_OneTypeGeneric|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_FullRangeIMM)
HARDWARE_INTRINSIC(AVX_Floor, "Floor", AVX, 9, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX_GetLowerHalf, "GetLowerHalf", AVX, -1, 32, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movaps, INS_movapd}, HW_Category_Helper, HW_Flag_OneTypeGeneric|HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX_HorizontalAdd, "HorizontalAdd", AVX, -1, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_haddps, INS_haddpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AVX_HorizontalSubtract, "HorizontalSubtract", AVX, -1, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_hsubps, INS_hsubpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AVX_InsertVector128, "InsertVector128", AVX, -1, 32, 3, {INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128, INS_vinsertf128},HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_OneTypeGeneric|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(AVX_LoadAlignedVector256, "LoadAlignedVector256", AVX, -1, 32, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movaps, INS_movapd}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX_LoadDquVector256, "LoadDquVector256", AVX, -1, 32, 1, {INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX_LoadVector256, "LoadVector256", AVX, -1, 32, 1, {INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movdqu, INS_movups, INS_movupd}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics)
@@ -395,10 +397,12 @@ HARDWARE_INTRINSIC(AVX2_BroadcastScalarToVector128, "BroadcastS
HARDWARE_INTRINSIC(AVX2_BroadcastScalarToVector256, "BroadcastScalarToVector256", AVX2, -1, 32, 1, {INS_vpbroadcastb,INS_vpbroadcastb,INS_vpbroadcastw,INS_vpbroadcastw,INS_vpbroadcastd,INS_vpbroadcastd,INS_vpbroadcastq,INS_vpbroadcastq,INS_vbroadcastss,INS_vbroadcastsd}, HW_Category_SimpleSIMD, HW_Flag_OneTypeGeneric)
HARDWARE_INTRINSIC(AVX2_CompareEqual, "CompareEqual", AVX2, -1, 32, 2, {INS_pcmpeqb, INS_pcmpeqb, INS_pcmpeqw, INS_pcmpeqw, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqq, INS_pcmpeqq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(AVX2_CompareGreaterThan, "CompareGreaterThan", AVX2, -1, 32, 2, {INS_pcmpgtb, INS_invalid, INS_pcmpgtw, INS_invalid, INS_pcmpgtd, INS_invalid, INS_pcmpgtq, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AVX2_ExtractVector128, "ExtractVector128", AVX2, -1, 32, -1, {INS_vextracti128,INS_vextracti128,INS_vextracti128,INS_vextracti128,INS_vextracti128,INS_vextracti128,INS_vextracti128,INS_vextracti128,INS_invalid, INS_invalid},HW_Category_IMM, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_FullRangeIMM)
HARDWARE_INTRINSIC(AVX2_HorizontalAdd, "HorizontalAdd", AVX2, -1, 32, 2, {INS_invalid, INS_invalid, INS_phaddw, INS_invalid, INS_phaddd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AVX2_HorizontalAddSaturate, "HorizontalAddSaturate", AVX2, -1, 32, 2, {INS_invalid, INS_invalid, INS_phaddsw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AVX2_HorizontalSubtract, "HorizontalSubtract", AVX2, -1, 32, 2, {INS_invalid, INS_invalid, INS_phsubw, INS_invalid, INS_phsubd, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AVX2_HorizontalSubtractSaturate, "HorizontalSubtractSaturate", AVX2, -1, 32, 2, {INS_invalid, INS_invalid, INS_phsubsw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AVX2_InsertVector128, "InsertVector128", AVX2, -1, 32, 3, {INS_vinserti128,INS_vinserti128,INS_vinserti128,INS_vinserti128,INS_vinserti128,INS_vinserti128,INS_vinserti128,INS_vinserti128,INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_SpecialCodeGen)
HARDWARE_INTRINSIC(AVX2_LoadAlignedVector256NonTemporal, "LoadAlignedVector256NonTemporal", AVX2, -1, 32, 1, {INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_movntdqa, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics)
HARDWARE_INTRINSIC(AVX2_Multiply, "Multiply", AVX2, -1, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmuldq, INS_pmuludq, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(AVX2_Or, "Or", AVX2, -1, 32, 2, {INS_por, INS_por, INS_por, INS_por, INS_por, INS_por, INS_por, INS_por, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp
index 56c7e99669..c52958a170 100644
--- a/src/jit/hwintrinsicxarch.cpp
+++ b/src/jit/hwintrinsicxarch.cpp
@@ -660,7 +660,8 @@ bool Compiler::hwIntrinsicSignatureTypeSupported(var_types retType, CORINFO_SIG_
static bool impIsTableDrivenHWIntrinsic(HWIntrinsicCategory category, HWIntrinsicFlag flags)
{
// HW_Flag_NoCodeGen implies this intrinsic should be manually morphed in the importer.
- return category != HW_Category_Special && category != HW_Category_Scalar && (flags & HW_Flag_NoCodeGen) == 0;
+ return category != HW_Category_Special && category != HW_Category_Scalar &&
+ ((flags & (HW_Flag_NoCodeGen | HW_Flag_SpecialImport)) == 0);
}
//------------------------------------------------------------------------
@@ -769,7 +770,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
assert(baseType != TYP_UNKNOWN);
}
- if ((flags & (HW_Flag_OneTypeGeneric | HW_Flag_TwoTypeGeneric)) != 0)
+ if (((flags & (HW_Flag_OneTypeGeneric | HW_Flag_TwoTypeGeneric)) != 0) && ((flags & HW_Flag_SpecialImport) == 0))
{
if (!varTypeIsArithmetic(baseType))
{
@@ -869,9 +870,8 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
case InstructionSet_SSE42:
return impSSE42Intrinsic(intrinsic, method, sig, mustExpand);
case InstructionSet_AVX:
- return impAVXIntrinsic(intrinsic, method, sig, mustExpand);
case InstructionSet_AVX2:
- return impAVX2Intrinsic(intrinsic, method, sig, mustExpand);
+ return impAvxOrAvx2Intrinsic(intrinsic, method, sig, mustExpand);
case InstructionSet_AES:
return impAESIntrinsic(intrinsic, method, sig, mustExpand);
@@ -1058,35 +1058,48 @@ GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic,
return retNode;
}
-GenTree* Compiler::impAVXIntrinsic(NamedIntrinsic intrinsic,
- CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
- bool mustExpand)
+GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic,
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_SIG_INFO* sig,
+ bool mustExpand)
{
GenTree* retNode = nullptr;
GenTree* op1 = nullptr;
GenTree* op2 = nullptr;
var_types baseType = TYP_UNKNOWN;
- switch (intrinsic)
- {
- default:
- JITDUMP("Not implemented hardware intrinsic");
- break;
- }
- return retNode;
-}
+ int simdSize = simdSizeOfHWIntrinsic(intrinsic, sig);
-GenTree* Compiler::impAVX2Intrinsic(NamedIntrinsic intrinsic,
- CORINFO_METHOD_HANDLE method,
- CORINFO_SIG_INFO* sig,
- bool mustExpand)
-{
- GenTree* retNode = nullptr;
- GenTree* op1 = nullptr;
- GenTree* op2 = nullptr;
- var_types baseType = TYP_UNKNOWN;
switch (intrinsic)
{
+ case NI_AVX_ExtractVector128:
+ case NI_AVX2_ExtractVector128:
+ {
+ GenTree* lastOp = impPopStack().val;
+ assert(lastOp->IsCnsIntOrI() || mustExpand);
+ GenTree* vectorOp = impSIMDPopStack(TYP_SIMD32);
+ if (sig->numArgs == 2)
+ {
+ baseType = getBaseTypeOfSIMDType(sig->retTypeSigClass);
+ if (!varTypeIsArithmetic(baseType))
+ {
+ retNode = impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, method, sig, mustExpand);
+ }
+ else
+ {
+ retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD16, vectorOp, lastOp, intrinsic, baseType, 32);
+ }
+ }
+ else
+ {
+ assert(sig->numArgs == 3);
+ op1 = impPopStack().val;
+ CORINFO_ARG_LIST_HANDLE secondArg = info.compCompHnd->getArgNext(sig->args);
+ CORINFO_CLASS_HANDLE secondArgClass = info.compCompHnd->getArgClass(sig, secondArg);
+ baseType = getBaseTypeOfSIMDType(secondArgClass);
+ retNode = gtNewSimdHWIntrinsicNode(TYP_VOID, op1, vectorOp, lastOp, intrinsic, baseType, 32);
+ }
+ break;
+ }
default:
JITDUMP("Not implemented hardware intrinsic");
break;
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 787d758158..30faec23b8 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -15819,6 +15819,8 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
if (returnType != originalCallType)
{
+ JITDUMP("Return type mismatch, have %s, needed %s\n", varTypeName(returnType),
+ varTypeName(originalCallType));
compInlineResult->NoteFatal(InlineObservation::CALLSITE_RETURN_TYPE_MISMATCH);
return false;
}
@@ -18670,6 +18672,17 @@ GenTree* Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, In
op1 = gtCloneExpr(argInfo.argNode);
PREFIX_ASSUME(op1 != nullptr);
argInfo.argTmpNum = BAD_VAR_NUM;
+
+ // We may need to retype to ensure we match the callee's view of the type.
+ // Otherwise callee-pass throughs of arguments can create return type
+ // mismatches that block inlining.
+ //
+ // Note argument type mismatches that prevent inlining should
+ // have been caught in impInlineInitVars.
+ if (op1->TypeGet() != lclTyp)
+ {
+ op1->gtType = genActualType(lclTyp);
+ }
}
else if (argInfo.argIsLclVar && !argCanBeModified && !argInfo.argHasCallerLocalRef)
{
diff --git a/src/jit/instrsxarch.h b/src/jit/instrsxarch.h
index c0cd91d6a2..3be838b274 100644
--- a/src/jit/instrsxarch.h
+++ b/src/jit/instrsxarch.h
@@ -473,8 +473,8 @@ INST3( vpbroadcastb, "pbroadcastb" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SS
INST3( vpbroadcastw, "pbroadcastw" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x79)) // Broadcast int16 value from reg/memory to entire ymm register
INST3( vpbroadcastd, "pbroadcastd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x58)) // Broadcast int32 value from reg/memory to entire ymm register
INST3( vpbroadcastq, "pbroadcastq" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x59)) // Broadcast int64 value from reg/memory to entire ymm register
-INST3( vextractf128, "extractf128" , 0, IUM_WR, 0, 0, SSE3A(0x19), BAD_CODE, BAD_CODE) // Extract 128-bit packed floating point values
-INST3( vextracti128, "extracti128" , 0, IUM_WR, 0, 0, SSE3A(0x39), BAD_CODE, BAD_CODE) // Extract 128-bit packed integer values
+INST3( vextractf128, "extractf128" , 0, IUM_WR, 0, 0, SSE3A(0x19), BAD_CODE, SSE3A(0x19)) // Extract 128-bit packed floating point values
+INST3( vextracti128, "extracti128" , 0, IUM_WR, 0, 0, SSE3A(0x39), BAD_CODE, SSE3A(0x39)) // Extract 128-bit packed integer values
INST3( vinsertf128, "insertf128" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE3A(0x18)) // Insert 128-bit packed floating point values
INST3( vinserti128, "inserti128" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE3A(0x38)) // Insert 128-bit packed integer values
INST3( vzeroupper, "zeroupper" , 0, IUM_WR, 0, 0, 0xC577F8, BAD_CODE, BAD_CODE) // Zero upper 128-bits of all YMM regs (includes 2-byte fixed VEX prefix)
diff --git a/src/jit/namedintrinsiclist.h b/src/jit/namedintrinsiclist.h
index f4d7cb2a88..dd98821c66 100644
--- a/src/jit/namedintrinsiclist.h
+++ b/src/jit/namedintrinsiclist.h
@@ -97,14 +97,19 @@ enum HWIntrinsicFlag : unsigned int
// Select base type using the second argument type
HW_Flag_BaseTypeFromSecondArg = 0x10000,
- // Specail codegen
+ // Special codegen
// the intrinsics need special rules in CodeGen,
- // but can be table-driven in the front-end
+ // but may be table-driven in the front-end
HW_Flag_SpecialCodeGen = 0x20000,
// No Read/Modify/Write Semantics
// the intrinsic doesn't have read/modify/write semantics in two/three-operand form.
HW_Flag_NoRMWSemantics = 0x40000,
+
+ // Special import
+ // the intrinsics need special rules in importer,
+ // but may be table-driven in the back-end
+ HW_Flag_SpecialImport = 0x80000,
};
inline HWIntrinsicFlag operator|(HWIntrinsicFlag c1, HWIntrinsicFlag c2)
diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
index a5b49c8cff..f14199e96c 100644
--- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
@@ -235,6 +235,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Int64.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IntPtr.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Lazy.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Marvin.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Math.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\MathF.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\MarshalByRefObject.cs" />
diff --git a/src/mscorlib/shared/System/Globalization/CompareInfo.cs b/src/mscorlib/shared/System/Globalization/CompareInfo.cs
index ef76c7c75c..f54ecd9144 100644
--- a/src/mscorlib/shared/System/Globalization/CompareInfo.cs
+++ b/src/mscorlib/shared/System/Globalization/CompareInfo.cs
@@ -16,6 +16,8 @@ using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
+using System.Buffers;
+using System.Text;
namespace System.Globalization
{
@@ -1217,6 +1219,34 @@ namespace System.Globalization
return (this.Name.GetHashCode());
}
+ internal static unsafe int GetIgnoreCaseHash(string source)
+ {
+ Debug.Assert(source != null, "source must not be null");
+
+ // Do not allocate on the stack if string is empty
+ if (source.Length == 0)
+ {
+ return source.GetHashCode();
+ }
+
+ char[] borrowedArr = null;
+ Span<char> span = source.Length <= 255 ?
+ stackalloc char[255] :
+ (borrowedArr = ArrayPool<char>.Shared.Rent(source.Length));
+
+ int charsWritten = source.AsSpan().ToUpperInvariant(span);
+
+ // Slice the array to the size returned by ToUpperInvariant.
+ int hash = Marvin.ComputeHash32(span.Slice(0, charsWritten).AsBytes(), Marvin.DefaultSeed);
+
+ // Return the borrowed array if necessary.
+ if (borrowedArr != null)
+ {
+ ArrayPool<char>.Shared.Return(borrowedArr);
+ }
+
+ return hash;
+ }
////////////////////////////////////////////////////////////////////////
//
@@ -1259,7 +1289,7 @@ namespace System.Globalization
if (_invariantMode)
{
- return ((options & CompareOptions.IgnoreCase) != 0) ? TextInfo.GetHashCodeOrdinalIgnoreCase(source) : source.GetHashCode();
+ return ((options & CompareOptions.IgnoreCase) != 0) ? GetIgnoreCaseHash(source) : source.GetHashCode();
}
return GetHashCodeOfStringCore(source, options);
@@ -1279,7 +1309,7 @@ namespace System.Globalization
if (options == CompareOptions.OrdinalIgnoreCase)
{
- return TextInfo.GetHashCodeOrdinalIgnoreCase(source);
+ return GetIgnoreCaseHash(source);
}
//
diff --git a/src/mscorlib/shared/System/Globalization/TextInfo.cs b/src/mscorlib/shared/System/Globalization/TextInfo.cs
index 631c8c0f19..431458bc7a 100644
--- a/src/mscorlib/shared/System/Globalization/TextInfo.cs
+++ b/src/mscorlib/shared/System/Globalization/TextInfo.cs
@@ -80,17 +80,6 @@ namespace System.Globalization
throw new PlatformNotSupportedException();
}
- //
- // Internal ordinal comparison functions
- //
-
- internal static int GetHashCodeOrdinalIgnoreCase(string s)
- {
- // This is the same as an case insensitive hash for Invariant
- // (not necessarily true for sorting, but OK for casing & then we apply normal hash code rules)
- return Invariant.GetCaseInsensitiveHashCode(s);
- }
-
public virtual int ANSICodePage => _cultureData.IDEFAULTANSICODEPAGE;
public virtual int OEMCodePage => _cultureData.IDEFAULTOEMCODEPAGE;
@@ -693,64 +682,5 @@ namespace System.Globalization
|| uc == UnicodeCategory.ModifierLetter
|| uc == UnicodeCategory.OtherLetter);
}
-
- //
- // Get case-insensitive hash code for the specified string.
- //
- internal unsafe int GetCaseInsensitiveHashCode(string str)
- {
- // Validate inputs
- if (str == null)
- {
- throw new ArgumentNullException(nameof(str));
- }
-
- // This code assumes that ASCII casing is safe for whatever context is passed in.
- // this is true today, because we only ever call these methods on Invariant. It would be ideal to refactor
- // these methods so they were correct by construction and we could only ever use Invariant.
-
- uint hash = 5381;
- uint c;
-
- // Note: We assume that str contains only ASCII characters until
- // we hit a non-ASCII character to optimize the common case.
- for (int i = 0; i < str.Length; i++)
- {
- c = str[i];
- if (c >= 0x80)
- {
- return GetCaseInsensitiveHashCodeSlow(str);
- }
-
- // If we have a lowercase character, ANDing off 0x20
- // will make it an uppercase character.
- if ((c - 'a') <= ('z' - 'a'))
- {
- c = (uint)((int)c & ~0x20);
- }
-
- hash = ((hash << 5) + hash) ^ c;
- }
-
- return (int)hash;
- }
-
- private unsafe int GetCaseInsensitiveHashCodeSlow(string str)
- {
- Debug.Assert(str != null);
-
- string upper = ToUpper(str);
-
- uint hash = 5381;
- uint c;
-
- for (int i = 0; i < upper.Length; i++)
- {
- c = upper[i];
- hash = ((hash << 5) + hash) ^ c;
- }
-
- return (int)hash;
- }
}
}
diff --git a/src/mscorlib/shared/System/Marvin.cs b/src/mscorlib/shared/System/Marvin.cs
new file mode 100644
index 0000000000..ca4e7cb1a4
--- /dev/null
+++ b/src/mscorlib/shared/System/Marvin.cs
@@ -0,0 +1,115 @@
+// 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.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ internal static class Marvin
+ {
+ /// <summary>
+ /// Convenience method to compute a Marvin hash and collapse it into a 32-bit hash.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int ComputeHash32(ReadOnlySpan<byte> data, ulong seed)
+ {
+ long hash64 = ComputeHash(data, seed);
+ return ((int)(hash64 >> 32)) ^ (int)hash64;
+ }
+
+ /// <summary>
+ /// Computes a 64-hash using the Marvin algorithm.
+ /// </summary>
+ public static long ComputeHash(ReadOnlySpan<byte> data, ulong seed)
+ {
+ uint p0 = (uint)seed;
+ uint p1 = (uint)(seed >> 32);
+
+ if (data.Length >= sizeof(uint))
+ {
+ ReadOnlySpan<uint> uData = MemoryMarshal.Cast<byte, uint>(data);
+
+ for (int i = 0; i < uData.Length; i++)
+ {
+ p0 += uData[i];
+ Block(ref p0, ref p1);
+ }
+
+ // byteOffset = data.Length - data.Length % 4
+ // is equivalent to clearing last 2 bits of length
+ // Using it directly gives a perf hit for short strings making it at least 5% or more slower.
+ int byteOffset = data.Length & (~3);
+ data = data.Slice(byteOffset);
+ }
+
+ switch (data.Length)
+ {
+ case 0:
+ p0 += 0x80u;
+ break;
+
+ case 1:
+ p0 += 0x8000u | data[0];
+ break;
+
+ case 2:
+ p0 += 0x800000u | MemoryMarshal.Cast<byte, ushort>(data)[0];
+ break;
+
+ case 3:
+ p0 += 0x80000000u | (((uint)data[2]) << 16) | (uint)(MemoryMarshal.Cast<byte, ushort>(data)[0]);
+ break;
+
+ default:
+ Debug.Fail("Should not get here.");
+ break;
+ }
+
+ Block(ref p0, ref p1);
+ Block(ref p0, ref p1);
+
+ return (((long)p1) << 32) | p0;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void Block(ref uint rp0, ref uint rp1)
+ {
+ uint p0 = rp0;
+ uint p1 = rp1;
+
+ p1 ^= p0;
+ p0 = _rotl(p0, 20);
+
+ p0 += p1;
+ p1 = _rotl(p1, 9);
+
+ p1 ^= p0;
+ p0 = _rotl(p0, 27);
+
+ p0 += p1;
+ p1 = _rotl(p1, 19);
+
+ rp0 = p0;
+ rp1 = p1;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static uint _rotl(uint value, int shift)
+ {
+ // This is expected to be optimized into a single rol (or ror with negated shift value) instruction
+ return (value << shift) | (value >> (32 - shift));
+ }
+
+ public static ulong DefaultSeed { get; } = GenerateSeed();
+
+ private static unsafe ulong GenerateSeed()
+ {
+ ulong result;
+ Interop.GetRandomBytes((byte*)&result, sizeof(ulong));
+ return result;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/StringComparer.cs b/src/mscorlib/shared/System/StringComparer.cs
index de311e91d1..cb2d32fccb 100644
--- a/src/mscorlib/shared/System/StringComparer.cs
+++ b/src/mscorlib/shared/System/StringComparer.cs
@@ -307,7 +307,7 @@ namespace System
if (_ignoreCase)
{
- return TextInfo.GetHashCodeOrdinalIgnoreCase(obj);
+ return CompareInfo.GetIgnoreCaseHash(obj);
}
return obj.GetHashCode();
@@ -375,7 +375,7 @@ namespace System
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj);
}
- return TextInfo.GetHashCodeOrdinalIgnoreCase(obj);
+ return CompareInfo.GetIgnoreCaseHash(obj);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs
index 7fa6926ee7..23f4127691 100644
--- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs
+++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs
@@ -4,6 +4,7 @@
using System;
using System.Runtime.Intrinsics;
+using System.Runtime.CompilerServices;
namespace System.Runtime.Intrinsics.X86
{
@@ -238,42 +239,145 @@ namespace System.Runtime.Intrinsics.X86
/// __int8 _mm256_extract_epi8 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static sbyte Extract(Vector256<sbyte> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static sbyte Extract(Vector256<sbyte> value, byte index)
+ {
+ index &= 0x1F; // the instructions only need the lowest 5 bits.
+ if (index > 15)
+ {
+ return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 16));
+ }
+ else
+ {
+ return Sse41.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int8 _mm256_extract_epi8 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static byte Extract(Vector256<byte> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte Extract(Vector256<byte> value, byte index)
+ {
+ index &= 0x1F; // the instructions only need the lowest 5 bits.
+ if (index > 15)
+ {
+ return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 16));
+ }
+ else
+ {
+ return Sse41.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int16 _mm256_extract_epi16 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static short Extract(Vector256<short> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static short Extract(Vector256<short> value, byte index)
+ {
+ index &= 0xF; // the instructions only need the lowest 4 bits.
+ if (index > 7)
+ {
+ return Sse2.Extract(ExtractVector128(value, 1), (byte)(index - 8));
+ }
+ else
+ {
+ return Sse2.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int16 _mm256_extract_epi16 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static ushort Extract(Vector256<ushort> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ushort Extract(Vector256<ushort> value, byte index)
+ {
+ index &= 0xF; // the instructions only need the lowest 4 bits.
+ if (index > 7)
+ {
+ return Sse2.Extract(ExtractVector128(value, 1), (byte)(index - 8));
+ }
+ else
+ {
+ return Sse2.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int32 _mm256_extract_epi32 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static int Extract(Vector256<int> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Extract(Vector256<int> value, byte index)
+ {
+ index &= 0x7; // the instructions only need the lowest 3 bits.
+ if (index > 3)
+ {
+ return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 4));
+ }
+ else
+ {
+ return Sse41.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int32 _mm256_extract_epi32 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static uint Extract(Vector256<uint> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint Extract(Vector256<uint> value, byte index)
+ {
+ index &= 0x7; // the instructions only need the lowest 3 bits.
+ if (index > 3)
+ {
+ return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 4));
+ }
+ else
+ {
+ return Sse41.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int64 _mm256_extract_epi64 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static long Extract(Vector256<long> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long Extract(Vector256<long> value, byte index)
+ {
+ index &= 0x3; // the instructions only need the lowest 2 bits.
+ if (index > 1)
+ {
+ return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 2));
+ }
+ else
+ {
+ return Sse41.Extract(GetLowerHalf(value), index);
+ }
+ }
+
/// <summary>
/// __int64 _mm256_extract_epi64 (__m256i a, const int index)
/// HELPER
/// </summary>
- public static ulong Extract(Vector256<ulong> value, byte index) => Extract(value, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong Extract(Vector256<ulong> value, byte index)
+ {
+ index &= 0x3; // the instructions only need the lowest 2 bits.
+ if (index > 1)
+ {
+ return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 2));
+ }
+ else
+ {
+ return Sse41.Extract(GetLowerHalf(value), index);
+ }
+ }
/// <summary>
/// __m128 _mm256_extractf128_ps (__m256 a, const int imm8)
@@ -402,42 +506,169 @@ namespace System.Runtime.Intrinsics.X86
/// __m256i _mm256_insert_epi8 (__m256i a, __int8 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<sbyte> Insert(Vector256<sbyte> value, sbyte data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<sbyte> Insert(Vector256<sbyte> value, sbyte data, byte index)
+ {
+ index &= 0x1F; // the instructions only need the lowest 5 bits.
+ if (index > 15)
+ {
+ Vector128<sbyte> half = ExtractVector128(value, 1);
+ half = Sse41.Insert(half, data, (byte)(index - 16));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<sbyte> half = Sse41.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, sbyte>(Blend(StaticCast<sbyte, float>(value), StaticCast<sbyte, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi8 (__m256i a, __int8 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<byte> Insert(Vector256<byte> value, byte data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<byte> Insert(Vector256<byte> value, byte data, byte index)
+ {
+ index &= 0x1F; // the instructions only need the lowest 5 bits.
+ if (index > 15)
+ {
+ Vector128<byte> half = ExtractVector128(value, 1);
+ half = Sse41.Insert(half, data, (byte)(index - 16));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<byte> half = Sse41.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, byte>(Blend(StaticCast<byte, float>(value), StaticCast<byte, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi16 (__m256i a, __int16 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<short> Insert(Vector256<short> value, short data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<short> Insert(Vector256<short> value, short data, byte index)
+ {
+ index &= 0xF; // the instructions only need the lowest 4 bits.
+ if (index > 7)
+ {
+ Vector128<short> half = ExtractVector128(value, 1);
+ half = Sse2.Insert(half, data, (byte)(index - 8));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<short> half = Sse2.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, short>(Blend(StaticCast<short, float>(value), StaticCast<short, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi16 (__m256i a, __int16 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<ushort> Insert(Vector256<ushort> value, ushort data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<ushort> Insert(Vector256<ushort> value, ushort data, byte index)
+ {
+ index &= 0xF; // the instructions only need the lowest 4 bits.
+ if (index > 7)
+ {
+ Vector128<ushort> half = ExtractVector128(value, 1);
+ half = Sse2.Insert(half, data, (byte)(index - 8));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<ushort> half = Sse2.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, ushort>(Blend(StaticCast<ushort, float>(value), StaticCast<ushort, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi32 (__m256i a, __int32 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<int> Insert(Vector256<int> value, int data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<int> Insert(Vector256<int> value, int data, byte index)
+ {
+ index &= 0x7; // the instructions only need the lowest 3 bits.
+ if (index > 3)
+ {
+ Vector128<int> half = ExtractVector128(value, 1);
+ half = Sse41.Insert(half, data, (byte)(index - 4));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<int> half = Sse41.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, int>(Blend(StaticCast<int, float>(value), StaticCast<int, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi32 (__m256i a, __int32 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<uint> Insert(Vector256<uint> value, uint data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<uint> Insert(Vector256<uint> value, uint data, byte index)
+ {
+ index &= 0x7; // the instructions only need the lowest 3 bits.
+ if (index > 3)
+ {
+ Vector128<uint> half = ExtractVector128(value, 1);
+ half = Sse41.Insert(half, data, (byte)(index - 4));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<uint> half = Sse41.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, uint>(Blend(StaticCast<uint, float>(value), StaticCast<uint, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi64 (__m256i a, __int64 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<long> Insert(Vector256<long> value, long data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<long> Insert(Vector256<long> value, long data, byte index)
+ {
+ index &= 0x3; // the instructions only need the lowest 2 bits.
+ if (index > 1)
+ {
+ Vector128<long> half = ExtractVector128(value, 1);
+ half = Sse41.Insert(half, data, (byte)(index - 2));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<long> half = Sse41.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, long>(Blend(StaticCast<long, float>(value), StaticCast<long, float>(ExtendToVector256(half)), 15));
+ }
+ }
+
/// <summary>
/// __m256i _mm256_insert_epi64 (__m256i a, __int64 i, const int index)
/// HELPER
/// </summary>
- public static Vector256<ulong> Insert(Vector256<ulong> value, ulong data, byte index) => Insert(value, data, index);
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256<ulong> Insert(Vector256<ulong> value, ulong data, byte index)
+ {
+ index &= 0x3; // the instructions only need the lowest 2 bits.
+ if (index > 1)
+ {
+ Vector128<ulong> half = ExtractVector128(value, 1);
+ half = Sse41.Insert(half, data, (byte)(index - 2));
+ return InsertVector128(value, half, 1);
+ }
+ else
+ {
+ Vector128<ulong> half = Sse41.Insert(GetLowerHalf(value), data, index);
+ return StaticCast<float, ulong>(Blend(StaticCast<ulong, float>(value), StaticCast<ulong, float>(ExtendToVector256(half)), 15));
+ }
+ }
/// <summary>
/// __m256 _mm256_insertf128_ps (__m256 a, __m128 b, int imm8)
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj
index e1d1a8d9e3..98abca2e19 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj
@@ -44,6 +44,22 @@
<Compile Include="DuplicateEvenIndexed.Double.cs" />
<Compile Include="DuplicateEvenIndexed.Single.cs" />
<Compile Include="DuplicateOddIndexed.Single.cs" />
+ <Compile Include="Extract.Byte.1.cs" />
+ <Compile Include="Extract.SByte.1.cs" />
+ <Compile Include="Extract.Byte.20.cs" />
+ <Compile Include="Extract.SByte.20.cs" />
+ <Compile Include="Extract.Int16.1.cs" />
+ <Compile Include="Extract.UInt16.1.cs" />
+ <Compile Include="Extract.Int16.11.cs" />
+ <Compile Include="Extract.UInt16.11.cs" />
+ <Compile Include="Extract.Int32.1.cs" />
+ <Compile Include="Extract.UInt32.1.cs" />
+ <Compile Include="Extract.Int32.6.cs" />
+ <Compile Include="Extract.UInt32.6.cs" />
+ <Compile Include="Extract.Int64.1.cs" />
+ <Compile Include="Extract.UInt64.1.cs" />
+ <Compile Include="Extract.Int64.3.cs" />
+ <Compile Include="Extract.UInt64.3.cs" />
<Compile Include="ExtendToVector256.Byte.cs" />
<Compile Include="ExtendToVector256.Double.cs" />
<Compile Include="ExtendToVector256.Int16.cs" />
@@ -54,6 +70,42 @@
<Compile Include="ExtendToVector256.UInt16.cs" />
<Compile Include="ExtendToVector256.UInt32.cs" />
<Compile Include="ExtendToVector256.UInt64.cs" />
+ <Compile Include="ExtractVector128.Byte.1.Store.cs" />
+ <Compile Include="ExtractVector128.SByte.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int16.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int32.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int64.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.Store.cs" />
+ <Compile Include="ExtractVector128.Single.1.Store.cs" />
+ <Compile Include="ExtractVector128.Double.1.Store.cs" />
+ <Compile Include="Insert.Byte.1.cs" />
+ <Compile Include="Insert.SByte.1.cs" />
+ <Compile Include="Insert.Byte.20.cs" />
+ <Compile Include="Insert.SByte.20.cs" />
+ <Compile Include="Insert.Int16.1.cs" />
+ <Compile Include="Insert.UInt16.1.cs" />
+ <Compile Include="Insert.Int16.11.cs" />
+ <Compile Include="Insert.UInt16.11.cs" />
+ <Compile Include="Insert.Int32.1.cs" />
+ <Compile Include="Insert.UInt32.1.cs" />
+ <Compile Include="Insert.Int32.6.cs" />
+ <Compile Include="Insert.UInt32.6.cs" />
+ <Compile Include="Insert.Int64.1.cs" />
+ <Compile Include="Insert.UInt64.1.cs" />
+ <Compile Include="Insert.Int64.3.cs" />
+ <Compile Include="Insert.UInt64.3.cs" />
+ <Compile Include="InsertVector128.Byte.1.Load.cs" />
+ <Compile Include="InsertVector128.SByte.1.Load.cs" />
+ <Compile Include="InsertVector128.Int16.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt16.1.Load.cs" />
+ <Compile Include="InsertVector128.Int32.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt32.1.Load.cs" />
+ <Compile Include="InsertVector128.Int64.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt64.1.Load.cs" />
+ <Compile Include="InsertVector128.Single.1.Load.cs" />
+ <Compile Include="InsertVector128.Double.1.Load.cs" />
<Compile Include="Floor.Double.cs" />
<Compile Include="Floor.Single.cs" />
<Compile Include="GetLowerHalf.Byte.cs" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj
index 4dd281b38b..7b45811695 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj
@@ -44,6 +44,22 @@
<Compile Include="DuplicateEvenIndexed.Double.cs" />
<Compile Include="DuplicateEvenIndexed.Single.cs" />
<Compile Include="DuplicateOddIndexed.Single.cs" />
+ <Compile Include="Extract.Byte.1.cs" />
+ <Compile Include="Extract.SByte.1.cs" />
+ <Compile Include="Extract.Byte.20.cs" />
+ <Compile Include="Extract.SByte.20.cs" />
+ <Compile Include="Extract.Int16.1.cs" />
+ <Compile Include="Extract.UInt16.1.cs" />
+ <Compile Include="Extract.Int16.11.cs" />
+ <Compile Include="Extract.UInt16.11.cs" />
+ <Compile Include="Extract.Int32.1.cs" />
+ <Compile Include="Extract.UInt32.1.cs" />
+ <Compile Include="Extract.Int32.6.cs" />
+ <Compile Include="Extract.UInt32.6.cs" />
+ <Compile Include="Extract.Int64.1.cs" />
+ <Compile Include="Extract.UInt64.1.cs" />
+ <Compile Include="Extract.Int64.3.cs" />
+ <Compile Include="Extract.UInt64.3.cs" />
<Compile Include="ExtendToVector256.Byte.cs" />
<Compile Include="ExtendToVector256.Double.cs" />
<Compile Include="ExtendToVector256.Int16.cs" />
@@ -54,6 +70,42 @@
<Compile Include="ExtendToVector256.UInt16.cs" />
<Compile Include="ExtendToVector256.UInt32.cs" />
<Compile Include="ExtendToVector256.UInt64.cs" />
+ <Compile Include="ExtractVector128.Byte.1.Store.cs" />
+ <Compile Include="ExtractVector128.SByte.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int16.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int32.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int64.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.Store.cs" />
+ <Compile Include="ExtractVector128.Single.1.Store.cs" />
+ <Compile Include="ExtractVector128.Double.1.Store.cs" />
+ <Compile Include="Insert.Byte.1.cs" />
+ <Compile Include="Insert.SByte.1.cs" />
+ <Compile Include="Insert.Byte.20.cs" />
+ <Compile Include="Insert.SByte.20.cs" />
+ <Compile Include="Insert.Int16.1.cs" />
+ <Compile Include="Insert.UInt16.1.cs" />
+ <Compile Include="Insert.Int16.11.cs" />
+ <Compile Include="Insert.UInt16.11.cs" />
+ <Compile Include="Insert.Int32.1.cs" />
+ <Compile Include="Insert.UInt32.1.cs" />
+ <Compile Include="Insert.Int32.6.cs" />
+ <Compile Include="Insert.UInt32.6.cs" />
+ <Compile Include="Insert.Int64.1.cs" />
+ <Compile Include="Insert.UInt64.1.cs" />
+ <Compile Include="Insert.Int64.3.cs" />
+ <Compile Include="Insert.UInt64.3.cs" />
+ <Compile Include="InsertVector128.Byte.1.Load.cs" />
+ <Compile Include="InsertVector128.SByte.1.Load.cs" />
+ <Compile Include="InsertVector128.Int16.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt16.1.Load.cs" />
+ <Compile Include="InsertVector128.Int32.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt32.1.Load.cs" />
+ <Compile Include="InsertVector128.Int64.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt64.1.Load.cs" />
+ <Compile Include="InsertVector128.Single.1.Load.cs" />
+ <Compile Include="InsertVector128.Double.1.Load.cs" />
<Compile Include="Floor.Double.cs" />
<Compile Include="Floor.Single.cs" />
<Compile Include="GetLowerHalf.Byte.cs" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.1.cs
new file mode 100644
index 0000000000..4f64c65045
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractByte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractByte1();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractByte1();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.20.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.20.cs
new file mode 100644
index 0000000000..bbe912f98d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.20.cs
@@ -0,0 +1,309 @@
+// 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 ExtractByte20()
+ {
+ var test = new SimpleUnaryOpTest__ExtractByte20();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractByte20
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractByte20()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractByte20()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractByte20();
+ var result = Avx.Extract(test._fld, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[20]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.1.cs
new file mode 100644
index 0000000000..183888c5fc
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractInt161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt161();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt161();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.11.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.11.cs
new file mode 100644
index 0000000000..e240fe4e62
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.11.cs
@@ -0,0 +1,309 @@
+// 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 ExtractInt1611()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt1611();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractInt1611
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractInt1611()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractInt1611()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt1611();
+ var result = Avx.Extract(test._fld, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[11]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.1.cs
new file mode 100644
index 0000000000..ef7ee434c1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractInt321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt321();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt321();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.6.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.6.cs
new file mode 100644
index 0000000000..c7d935cba1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.6.cs
@@ -0,0 +1,309 @@
+// 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 ExtractInt326()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt326();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractInt326
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractInt326()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractInt326()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt326();
+ var result = Avx.Extract(test._fld, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[6]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.1.cs
new file mode 100644
index 0000000000..269128a314
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractInt641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt641();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt641();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.3.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.3.cs
new file mode 100644
index 0000000000..70835b59b4
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.3.cs
@@ -0,0 +1,309 @@
+// 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 ExtractInt643()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt643();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractInt643
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractInt643()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractInt643()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractInt643();
+ var result = Avx.Extract(test._fld, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[3]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.1.cs
new file mode 100644
index 0000000000..e50c608442
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractSByte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractSByte1();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractSByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractSByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractSByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractSByte1();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.20.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.20.cs
new file mode 100644
index 0000000000..5cdc42c2ea
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.20.cs
@@ -0,0 +1,309 @@
+// 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 ExtractSByte20()
+ {
+ var test = new SimpleUnaryOpTest__ExtractSByte20();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractSByte20
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractSByte20()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractSByte20()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractSByte20();
+ var result = Avx.Extract(test._fld, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[20]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.1.cs
new file mode 100644
index 0000000000..67a8d3ed48
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractUInt161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt161();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractUInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractUInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractUInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt161();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.11.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.11.cs
new file mode 100644
index 0000000000..4cfdc671e9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.11.cs
@@ -0,0 +1,309 @@
+// 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 ExtractUInt1611()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt1611();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractUInt1611
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractUInt1611()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractUInt1611()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt1611();
+ var result = Avx.Extract(test._fld, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[11]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.1.cs
new file mode 100644
index 0000000000..1d43daa75d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractUInt321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt321();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractUInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractUInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractUInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt321();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.6.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.6.cs
new file mode 100644
index 0000000000..de8837caf1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.6.cs
@@ -0,0 +1,309 @@
+// 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 ExtractUInt326()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt326();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractUInt326
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractUInt326()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractUInt326()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt326();
+ var result = Avx.Extract(test._fld, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[6]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.1.cs
new file mode 100644
index 0000000000..a7ed898a86
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.1.cs
@@ -0,0 +1,309 @@
+// 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 ExtractUInt641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt641();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractUInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractUInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractUInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt641();
+ var result = Avx.Extract(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[1]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.3.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.3.cs
new file mode 100644
index 0000000000..67154d41af
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.3.cs
@@ -0,0 +1,309 @@
+// 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 ExtractUInt643()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt643();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractUInt643
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractUInt643()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractUInt643()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Extract(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Extract(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Extract(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Extract(
+ _clsVar,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx.Extract(firstOp, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Extract(firstOp, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractUInt643();
+ var result = Avx.Extract(test._fld, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Extract(_fld, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if ((result[0] != firstOp[3]))
+ {
+ Succeeded = false;
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.Store.cs
new file mode 100644
index 0000000000..b43bb977bc
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Byte1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Byte1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = 16 / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Byte1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Byte1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1Store();
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Byte*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.cs
new file mode 100644
index 0000000000..4a8d646024
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Byte.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128Byte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Byte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = 16 / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Byte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Byte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.Store.cs
new file mode 100644
index 0000000000..4c80be7fe8
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Double1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Double1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = 16 / sizeof(Double);
+
+ private static Double[] _data = new Double[Op1ElementCount];
+
+ private static Vector256<Double> _clsVar;
+
+ private Vector256<Double> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Double1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Double1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Double*), typeof(Vector256<Double>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Double*)),
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Double*), typeof(Vector256<Double>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Double*)),
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Double*), typeof(Vector256<Double>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Double*)),
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Double*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1Store();
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Double*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(firstOp[2]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(firstOp[i + 2])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Double>(Vector256<Double><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.cs
new file mode 100644
index 0000000000..a048510694
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Double.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128Double1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Double1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = 16 / sizeof(Double);
+
+ private static Double[] _data = new Double[Op1ElementCount];
+
+ private static Vector256<Double> _clsVar;
+
+ private Vector256<Double> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Double1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Double1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Double1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Double>(Vector256<Double><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.Store.cs
new file mode 100644
index 0000000000..8732da30ea
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Int161Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int161Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = 16 / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int161Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int161Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161Store();
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Int16*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.cs
new file mode 100644
index 0000000000..8ef99ca072
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int16.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128Int161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = 16 / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.Store.cs
new file mode 100644
index 0000000000..886c0bddca
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Int321Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int321Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = 16 / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int321Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int321Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321Store();
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Int32*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.cs
new file mode 100644
index 0000000000..11b97be6eb
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int32.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128Int321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = 16 / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.Store.cs
new file mode 100644
index 0000000000..005fc82b49
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Int641Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int641Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = 16 / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int641Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int641Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641Store();
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Int64*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.cs
new file mode 100644
index 0000000000..f6f8c1b63f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Int64.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128Int641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = 16 / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.Store.cs
new file mode 100644
index 0000000000..fa745d2716
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128SByte1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128SByte1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = 16 / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128SByte1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128SByte1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1Store();
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((SByte*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.cs
new file mode 100644
index 0000000000..2dddbe5259
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.SByte.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128SByte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128SByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = 16 / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128SByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128SByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.Store.cs
new file mode 100644
index 0000000000..3fe06f5bd0
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Single1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Single1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int RetElementCount = 16 / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector256<Single> _clsVar;
+
+ private Vector256<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Single1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Single1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Single*), typeof(Vector256<Single>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Single*)),
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Single*), typeof(Vector256<Single>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Single*)),
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(Single*), typeof(Vector256<Single>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Single*)),
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (Single*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1Store();
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((Single*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(firstOp[4]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i + 4])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Single>(Vector256<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.cs
new file mode 100644
index 0000000000..7b72949740
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.Single.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128Single1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Single1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int RetElementCount = 16 / sizeof(Single);
+
+ private static Single[] _data = new Single[Op1ElementCount];
+
+ private static Vector256<Single> _clsVar;
+
+ private Vector256<Single> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Single1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Single1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Single1();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray = new Single[Op1ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<Single>(Vector256<Single><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.Store.cs
new file mode 100644
index 0000000000..4f3d5a18fe
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128UInt161Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt161Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = 16 / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt161Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt161Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161Store();
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((UInt16*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.cs
new file mode 100644
index 0000000000..855580c58c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt16.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128UInt161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = 16 / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.Store.cs
new file mode 100644
index 0000000000..14202204fd
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128UInt321Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt321Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = 16 / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt321Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt321Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321Store();
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((UInt32*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.cs
new file mode 100644
index 0000000000..25fd0644c0
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt32.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128UInt321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = 16 / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.Store.cs
new file mode 100644
index 0000000000..fc22be9aef
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128UInt641Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt641Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = 16 / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt641Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt641Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx).GetMethod(nameof(Avx.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641Store();
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx.ExtractVector128((UInt64*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.cs
new file mode 100644
index 0000000000..d43f65136a
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/ExtractVector128.UInt64.1.cs
@@ -0,0 +1,321 @@
+// 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.Reflection;
+using System.Linq;
+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 ExtractVector128UInt641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = 16 / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.ExtractVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.ExtractVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641();
+ var result = Avx.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.ExtractVector128)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.1.cs
new file mode 100644
index 0000000000..cd89f1fec6
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertByte1()
+ {
+ var test = new SimpleUnaryOpTest__InsertByte1();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__InsertByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Byte>), typeof(Byte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Byte>), typeof(Byte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Byte>), typeof(Byte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (byte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (byte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (byte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (byte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertByte1();
+ var result = Avx.Insert(test._fld, (byte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (byte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.20.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.20.cs
new file mode 100644
index 0000000000..6ae3d08357
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.20.cs
@@ -0,0 +1,321 @@
+// 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 InsertByte20()
+ {
+ var test = new SimpleUnaryOpTest__InsertByte20();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertByte20
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__InsertByte20()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertByte20()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Byte>), typeof(Byte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)2,
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Byte>), typeof(Byte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Byte>), typeof(Byte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)2,
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (byte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (byte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (byte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (byte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertByte20();
+ var result = Avx.Insert(test._fld, (byte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (byte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 20 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.1.cs
new file mode 100644
index 0000000000..b2039f4a2e
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertInt161()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt161();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__InsertInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (short)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int16>), typeof(Int16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (short)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int16>), typeof(Int16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int16>), typeof(Int16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (short)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (short)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (short)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (short)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt161();
+ var result = Avx.Insert(test._fld, (short)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (short)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.11.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.11.cs
new file mode 100644
index 0000000000..311762cd92
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.11.cs
@@ -0,0 +1,321 @@
+// 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 InsertInt1611()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt1611();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertInt1611
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__InsertInt1611()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertInt1611()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (short)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int16>), typeof(Int16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (short)2,
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int16>), typeof(Int16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int16>), typeof(Int16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (short)2,
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (short)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (short)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (short)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (short)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt1611();
+ var result = Avx.Insert(test._fld, (short)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (short)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 11 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.1.cs
new file mode 100644
index 0000000000..84fa978194
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertInt321()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt321();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__InsertInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (int)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int32>), typeof(Int32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (int)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int32>), typeof(Int32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int32>), typeof(Int32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (int)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (int)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (int)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (int)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt321();
+ var result = Avx.Insert(test._fld, (int)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (int)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.6.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.6.cs
new file mode 100644
index 0000000000..a9a7a6ce9d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.6.cs
@@ -0,0 +1,321 @@
+// 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 InsertInt326()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt326();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertInt326
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__InsertInt326()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertInt326()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (int)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int32>), typeof(Int32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (int)2,
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int32>), typeof(Int32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int32>), typeof(Int32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (int)2,
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (int)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (int)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (int)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (int)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt326();
+ var result = Avx.Insert(test._fld, (int)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (int)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 6 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.1.cs
new file mode 100644
index 0000000000..ea68e0a1d9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertInt641()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt641();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__InsertInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (long)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int64>), typeof(Int64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (long)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int64>), typeof(Int64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int64>), typeof(Int64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (long)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (long)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (long)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (long)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt641();
+ var result = Avx.Insert(test._fld, (long)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (long)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.3.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.3.cs
new file mode 100644
index 0000000000..618532fe99
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.3.cs
@@ -0,0 +1,321 @@
+// 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 InsertInt643()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt643();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertInt643
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__InsertInt643()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertInt643()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (long)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int64>), typeof(Int64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (long)2,
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int64>), typeof(Int64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<Int64>), typeof(Int64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (long)2,
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (long)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (long)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (long)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (long)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertInt643();
+ var result = Avx.Insert(test._fld, (long)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (long)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 3 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.1.cs
new file mode 100644
index 0000000000..69557b48e9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertSByte1()
+ {
+ var test = new SimpleUnaryOpTest__InsertSByte1();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertSByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (sbyte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<SByte>), typeof(SByte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (sbyte)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<SByte>), typeof(SByte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<SByte>), typeof(SByte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (sbyte)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (sbyte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (sbyte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (sbyte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSByte1();
+ var result = Avx.Insert(test._fld, (sbyte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (sbyte)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.20.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.20.cs
new file mode 100644
index 0000000000..91b233d31f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.20.cs
@@ -0,0 +1,321 @@
+// 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 InsertSByte20()
+ {
+ var test = new SimpleUnaryOpTest__InsertSByte20();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertSByte20
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__InsertSByte20()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertSByte20()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (sbyte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<SByte>), typeof(SByte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (sbyte)2,
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<SByte>), typeof(SByte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<SByte>), typeof(SByte), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (sbyte)2,
+ (byte)20
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (sbyte)2,
+ 20
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (sbyte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (sbyte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (sbyte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertSByte20();
+ var result = Avx.Insert(test._fld, (sbyte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (sbyte)2, 20);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 20 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.1.cs
new file mode 100644
index 0000000000..c67ca950e3
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertUInt161()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt161();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertUInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__InsertUInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertUInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (ushort)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (ushort)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (ushort)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (ushort)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ushort)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ushort)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt161();
+ var result = Avx.Insert(test._fld, (ushort)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (ushort)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.11.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.11.cs
new file mode 100644
index 0000000000..327b65bfea
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.11.cs
@@ -0,0 +1,321 @@
+// 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 InsertUInt1611()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt1611();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertUInt1611
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__InsertUInt1611()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertUInt1611()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (ushort)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (ushort)2,
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (ushort)2,
+ (byte)11
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (ushort)2,
+ 11
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (ushort)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ushort)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ushort)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt1611();
+ var result = Avx.Insert(test._fld, (ushort)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (ushort)2, 11);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 11 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.1.cs
new file mode 100644
index 0000000000..7a742fbf37
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertUInt321()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt321();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertUInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__InsertUInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertUInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (uint)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (uint)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (uint)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (uint)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (uint)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (uint)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt321();
+ var result = Avx.Insert(test._fld, (uint)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (uint)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.6.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.6.cs
new file mode 100644
index 0000000000..0800058258
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.6.cs
@@ -0,0 +1,321 @@
+// 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 InsertUInt326()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt326();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertUInt326
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__InsertUInt326()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertUInt326()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (uint)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (uint)2,
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (uint)2,
+ (byte)6
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (uint)2,
+ 6
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (uint)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (uint)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (uint)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt326();
+ var result = Avx.Insert(test._fld, (uint)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (uint)2, 6);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 6 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.1.cs
new file mode 100644
index 0000000000..9b6b4e3a20
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.1.cs
@@ -0,0 +1,321 @@
+// 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 InsertUInt641()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt641();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertUInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__InsertUInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertUInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (ulong)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (ulong)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (ulong)2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (ulong)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ulong)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ulong)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt641();
+ var result = Avx.Insert(test._fld, (ulong)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (ulong)2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 1 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.3.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.3.cs
new file mode 100644
index 0000000000..9839d7ab0e
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.3.cs
@@ -0,0 +1,321 @@
+// 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 InsertUInt643()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt643();
+
+ try
+ {
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+ }
+ catch (PlatformNotSupportedException)
+ {
+ test.Succeeded = true;
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__InsertUInt643
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__InsertUInt643()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__InsertUInt643()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.Insert(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (ulong)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.Insert(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.Insert(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (ulong)2,
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (ulong)2,
+ (byte)3
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.Insert(
+ _clsVar,
+ (ulong)2,
+ 3
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx.Insert(firstOp, (ulong)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ulong)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx.Insert(firstOp, (ulong)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__InsertUInt643();
+ var result = Avx.Insert(test._fld, (ulong)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.Insert(_fld, (ulong)2, 3);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+
+ for (var i = 0; i < RetElementCount; i++)
+ {
+ if ((i == 3 ? result[i] != 2 : result[i] != 0))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128.Avx.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128.Avx.cs
new file mode 100644
index 0000000000..63f9233ef1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128.Avx.cs
@@ -0,0 +1,38 @@
+// 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.Collections.Generic;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ static Program()
+ {
+ TestList = new Dictionary<string, Action>() {
+ ["ExtractVector128.Byte.1"] = ExtractVector128Byte1,
+ ["ExtractVector128.SByte.1"] = ExtractVector128SByte1,
+ ["ExtractVector128.Int16.1"] = ExtractVector128Int161,
+ ["ExtractVector128.UInt16.1"] = ExtractVector128UInt161,
+ ["ExtractVector128.Int32.1"] = ExtractVector128Int321,
+ ["ExtractVector128.UInt32.1"] = ExtractVector128UInt321,
+ ["ExtractVector128.Int64.1"] = ExtractVector128Int641,
+ ["ExtractVector128.UInt64.1"] = ExtractVector128UInt641,
+ ["ExtractVector128.Single.1"] = ExtractVector128Single1,
+ ["ExtractVector128.Double.1"] = ExtractVector128Double1,
+ ["InsertVector128.Byte.1"] = InsertVector128Byte1,
+ ["InsertVector128.SByte.1"] = InsertVector128SByte1,
+ ["InsertVector128.Int16.1"] = InsertVector128Int161,
+ ["InsertVector128.UInt16.1"] = InsertVector128UInt161,
+ ["InsertVector128.Int32.1"] = InsertVector128Int321,
+ ["InsertVector128.UInt32.1"] = InsertVector128UInt321,
+ ["InsertVector128.Int64.1"] = InsertVector128Int641,
+ ["InsertVector128.UInt64.1"] = InsertVector128UInt641,
+ ["InsertVector128.Single.1"] = InsertVector128Single1,
+ ["InsertVector128.Double.1"] = InsertVector128Double1,
+ };
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128_r.csproj
index 746b725470..68189b400a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128_r.csproj
@@ -5,15 +5,14 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{8AABA105-3887-4CA6-83F9-3CD59DAAC7E8}</ProjectGuid>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
<OutputType>Exe</OutputType>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
@@ -28,10 +27,34 @@
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
- <Compile Include="DivideScalar.cs" />
- <Compile Include="TestTableSse2.cs" />
+ <Compile Include="ExtractVector128.Byte.1.cs" />
+ <Compile Include="ExtractVector128.SByte.1.cs" />
+ <Compile Include="ExtractVector128.Int16.1.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.cs" />
+ <Compile Include="ExtractVector128.Int32.1.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.cs" />
+ <Compile Include="ExtractVector128.Int64.1.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.cs" />
+ <Compile Include="ExtractVector128.Single.1.cs" />
+ <Compile Include="ExtractVector128.Double.1.cs" />
+ <Compile Include="InsertVector128.Byte.1.cs" />
+ <Compile Include="InsertVector128.SByte.1.cs" />
+ <Compile Include="InsertVector128.Int16.1.cs" />
+ <Compile Include="InsertVector128.UInt16.1.cs" />
+ <Compile Include="InsertVector128.Int32.1.cs" />
+ <Compile Include="InsertVector128.UInt32.1.cs" />
+ <Compile Include="InsertVector128.Int64.1.cs" />
+ <Compile Include="InsertVector128.UInt64.1.cs" />
+ <Compile Include="InsertVector128.Single.1.cs" />
+ <Compile Include="InsertVector128.Double.1.cs" />
+ <Compile Include="InsertExtractVector128.Avx.cs" />
+ <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
</Project>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128_ro.csproj
index fd0ec48868..68189b400a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertExtractVector128_ro.csproj
@@ -5,15 +5,14 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{75455928-80BB-4905-956F-0D53BFC4D804}</ProjectGuid>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
<OutputType>Exe</OutputType>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<ItemGroup>
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
@@ -28,10 +27,34 @@
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
- <Compile Include="MaxScalar.cs" />
- <Compile Include="TestTableSse2.cs" />
+ <Compile Include="ExtractVector128.Byte.1.cs" />
+ <Compile Include="ExtractVector128.SByte.1.cs" />
+ <Compile Include="ExtractVector128.Int16.1.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.cs" />
+ <Compile Include="ExtractVector128.Int32.1.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.cs" />
+ <Compile Include="ExtractVector128.Int64.1.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.cs" />
+ <Compile Include="ExtractVector128.Single.1.cs" />
+ <Compile Include="ExtractVector128.Double.1.cs" />
+ <Compile Include="InsertVector128.Byte.1.cs" />
+ <Compile Include="InsertVector128.SByte.1.cs" />
+ <Compile Include="InsertVector128.Int16.1.cs" />
+ <Compile Include="InsertVector128.UInt16.1.cs" />
+ <Compile Include="InsertVector128.Int32.1.cs" />
+ <Compile Include="InsertVector128.UInt32.1.cs" />
+ <Compile Include="InsertVector128.Int64.1.cs" />
+ <Compile Include="InsertVector128.UInt64.1.cs" />
+ <Compile Include="InsertVector128.Single.1.cs" />
+ <Compile Include="InsertVector128.Double.1.cs" />
+ <Compile Include="InsertExtractVector128.Avx.cs" />
+ <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.Load.cs
new file mode 100644
index 0000000000..0d7c5786de
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Byte1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Byte1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = 16 / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
+ private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Byte1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Byte1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ (Byte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ (Byte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ (Byte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Byte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Byte*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = (Byte*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = (Byte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = (Byte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1Load();
+ var result = Avx.InsertVector128(test._fld1, (Byte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Byte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Byte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Byte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.cs
new file mode 100644
index 0000000000..ffcce7b13d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Byte.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Byte1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Byte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = 16 / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
+ private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Byte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Byte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.Load.cs
new file mode 100644
index 0000000000..db00d65ecd
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Double1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Double1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = 16 / sizeof(Double);
+ private const int RetElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[Op1ElementCount];
+ private static Double[] _data2 = new Double[Op2ElementCount];
+
+ private static Vector256<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector256<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Double1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Double1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ (Double*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ (Double*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ (Double*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Double>), typeof(Double*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Double*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Double>), typeof(Double*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Double*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Double>), typeof(Double*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Double*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Double*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Double*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var right = (Double*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = (Double*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = (Double*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1Load();
+ var result = Avx.InsertVector128(test._fld1, (Double*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Double*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Double*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Double*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Double> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[i - 2]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Double>(Vector256<Double>, Vector128<Double>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.cs
new file mode 100644
index 0000000000..188c9ef831
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Double.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Double1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Double1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = 16 / sizeof(Double);
+ private const int RetElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data1 = new Double[Op1ElementCount];
+ private static Double[] _data2 = new Double[Op2ElementCount];
+
+ private static Vector256<Double> _clsVar1;
+ private static Vector128<Double> _clsVar2;
+
+ private Vector256<Double> _fld1;
+ private Vector128<Double> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Double1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Double1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Double*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Double*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Double) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Double1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Double>(Vector256<Double>, Vector128<Double>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.Load.cs
new file mode 100644
index 0000000000..0f032f8d2a
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int161Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int161Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = 16 / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
+ private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int161Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int161Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ (Int16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ (Int16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ (Int16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Int16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int16*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = (Int16*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = (Int16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = (Int16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161Load();
+ var result = Avx.InsertVector128(test._fld1, (Int16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Int16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int16>(Vector256<Int16>, Vector128<Int16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.cs
new file mode 100644
index 0000000000..592d79556f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int16.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int161()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = 16 / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
+ private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int16>(Vector256<Int16>, Vector128<Int16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.Load.cs
new file mode 100644
index 0000000000..50e36a3971
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int321Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int321Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int Op2ElementCount = 16 / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
+ private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int321Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int321Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ (Int32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ (Int32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ (Int32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Int32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int32*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = (Int32*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = (Int32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = (Int32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321Load();
+ var result = Avx.InsertVector128(test._fld1, (Int32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Int32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[Op1ElementCount];
+ Int32[] inArray2 = new Int32[Op2ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.cs
new file mode 100644
index 0000000000..fcc13d2bcb
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int32.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int321()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int Op2ElementCount = 16 / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
+ private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.Load.cs
new file mode 100644
index 0000000000..1aaa274971
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int641Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int641Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int Op2ElementCount = 16 / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
+ private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int641Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int641Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ (Int64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ (Int64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ (Int64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Int64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int64*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = (Int64*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = (Int64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = (Int64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641Load();
+ var result = Avx.InsertVector128(test._fld1, (Int64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Int64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[Op1ElementCount];
+ Int64[] inArray2 = new Int64[Op2ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int64>(Vector256<Int64>, Vector128<Int64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.cs
new file mode 100644
index 0000000000..0d353aea1d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Int64.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int641()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int Op2ElementCount = 16 / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
+ private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Int64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Int64>(Vector256<Int64>, Vector128<Int64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.Load.cs
new file mode 100644
index 0000000000..4b584fbaef
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128SByte1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128SByte1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = 16 / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
+ private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128SByte1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128SByte1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ (SByte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ (SByte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ (SByte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (SByte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (SByte*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = (SByte*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = (SByte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = (SByte*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1Load();
+ var result = Avx.InsertVector128(test._fld1, (SByte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (SByte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (SByte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (SByte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<SByte>(Vector256<SByte>, Vector128<SByte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.cs
new file mode 100644
index 0000000000..7dcd2f0ac1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.SByte.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128SByte1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128SByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = 16 / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
+ private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128SByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128SByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(SByte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<SByte>(Vector256<SByte>, Vector128<SByte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.Load.cs
new file mode 100644
index 0000000000..a41d40d3af
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Single1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Single1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int Op2ElementCount = 16 / sizeof(Single);
+ private const int RetElementCount = VectorSize / sizeof(Single);
+
+ private static Single[] _data1 = new Single[Op1ElementCount];
+ private static Single[] _data2 = new Single[Op2ElementCount];
+
+ private static Vector256<Single> _clsVar1;
+ private static Vector128<Single> _clsVar2;
+
+ private Vector256<Single> _fld1;
+ private Vector128<Single> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Single1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Single1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ (Single*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ (Single*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ (Single*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Single>), typeof(Single*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Single*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Single>), typeof(Single*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Single*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<Single>), typeof(Single*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Single*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (Single*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Single*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var right = (Single*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = (Single*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = (Single*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1Load();
+ var result = Avx.InsertVector128(test._fld1, (Single*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Single*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (Single*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Single*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(left[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(right[i - 4]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i])))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Single>(Vector256<Single>, Vector128<Single>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.cs
new file mode 100644
index 0000000000..6b12b571e1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.Single.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Single1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Single1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Single);
+ private const int Op2ElementCount = 16 / sizeof(Single);
+ private const int RetElementCount = VectorSize / sizeof(Single);
+
+ private static Single[] _data1 = new Single[Op1ElementCount];
+ private static Single[] _data2 = new Single[Op2ElementCount];
+
+ private static Vector256<Single> _clsVar1;
+ private static Vector128<Single> _clsVar2;
+
+ private Vector256<Single> _fld1;
+ private Vector128<Single> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Single1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Single1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (float)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (float)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Single*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Single*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(Single) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Single1();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Single[] inArray1 = new Single[Op1ElementCount];
+ Single[] inArray2 = new Single[Op2ElementCount];
+ Single[] outArray = new Single[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Single[] left, Single[] right, Single[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<Single>(Vector256<Single>, Vector128<Single>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.Load.cs
new file mode 100644
index 0000000000..47fc2ca379
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt161Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt161Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = 16 / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+ private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt161Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt161Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ (UInt16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ (UInt16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ (UInt16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (UInt16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt16*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = (UInt16*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = (UInt16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = (UInt16*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161Load();
+ var result = Avx.InsertVector128(test._fld1, (UInt16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (UInt16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt16>(Vector256<UInt16>, Vector128<UInt16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.cs
new file mode 100644
index 0000000000..6eff087993
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt16.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt161()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = 16 / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+ private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt16) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt16>(Vector256<UInt16>, Vector128<UInt16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.Load.cs
new file mode 100644
index 0000000000..da9e5bfd1b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt321Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt321Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int Op2ElementCount = 16 / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+ private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt321Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt321Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ (UInt32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ (UInt32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ (UInt32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (UInt32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt32*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = (UInt32*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = (UInt32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = (UInt32*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321Load();
+ var result = Avx.InsertVector128(test._fld1, (UInt32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (UInt32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
+ UInt32[] inArray2 = new UInt32[Op2ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt32>(Vector256<UInt32>, Vector128<UInt32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.cs
new file mode 100644
index 0000000000..4a11f6f989
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt32.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt321()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int Op2ElementCount = 16 / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+ private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt32) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt32>(Vector256<UInt32>, Vector128<UInt32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.Load.cs
new file mode 100644
index 0000000000..8fb7b27950
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt641Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt641Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int Op2ElementCount = 16 / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+ private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt641Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt641Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ (UInt64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ (UInt64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ (UInt64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethod(nameof(Avx.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ (UInt64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt64*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = (UInt64*)_dataTable.inArray2Ptr;
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = (UInt64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = (UInt64*)(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641Load();
+ var result = Avx.InsertVector128(test._fld1, (UInt64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, (UInt64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
+ UInt64[] inArray2 = new UInt64[Op2ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt64>(Vector256<UInt64>, Vector128<UInt64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.cs
new file mode 100644
index 0000000000..50742653ed
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/InsertVector128.UInt64.1.cs
@@ -0,0 +1,346 @@
+// 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.Reflection;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt641()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int Op2ElementCount = 16 / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+ private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx.InsertVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx.InsertVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx).GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .FirstOrDefault( mi => mi.Name == nameof(Avx.InsertVector128) && mi.IsGenericMethod)
+ .MakeGenericMethod(new[] { typeof(UInt64) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641();
+ var result = Avx.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.InsertVector128)}<UInt64>(Vector256<UInt64>, Vector128<UInt64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs
index d74b22f5e5..1bf4389d94 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs
@@ -29,6 +29,22 @@ namespace JIT.HardwareIntrinsics.X86
["DuplicateEvenIndexed.Double"] = DuplicateEvenIndexedDouble,
["DuplicateEvenIndexed.Single"] = DuplicateEvenIndexedSingle,
["DuplicateOddIndexed.Single"] = DuplicateOddIndexedSingle,
+ ["Extract.Byte.1"] = ExtractByte1,
+ ["Extract.SByte.1"] = ExtractSByte1,
+ ["Extract.Byte.20"] = ExtractByte20,
+ ["Extract.SByte.20"] = ExtractSByte20,
+ ["Extract.Int16.1"] = ExtractInt161,
+ ["Extract.UInt16.1"] = ExtractUInt161,
+ ["Extract.Int16.11"] = ExtractInt1611,
+ ["Extract.UInt16.11"] = ExtractUInt1611,
+ ["Extract.Int32.1"] = ExtractInt321,
+ ["Extract.UInt32.1"] = ExtractUInt321,
+ ["Extract.Int32.6"] = ExtractInt326,
+ ["Extract.UInt32.6"] = ExtractUInt326,
+ ["Extract.Int64.1"] = ExtractInt641,
+ ["Extract.UInt64.1"] = ExtractUInt641,
+ ["Extract.Int64.3"] = ExtractInt643,
+ ["Extract.UInt64.3"] = ExtractUInt643,
["ExtendToVector256.Byte"] = ExtendToVector256Byte,
["ExtendToVector256.Double"] = ExtendToVector256Double,
["ExtendToVector256.Int16"] = ExtendToVector256Int16,
@@ -39,6 +55,42 @@ namespace JIT.HardwareIntrinsics.X86
["ExtendToVector256.UInt16"] = ExtendToVector256UInt16,
["ExtendToVector256.UInt32"] = ExtendToVector256UInt32,
["ExtendToVector256.UInt64"] = ExtendToVector256UInt64,
+ ["ExtractVector128.Byte.1.Store"] = ExtractVector128Byte1Store,
+ ["ExtractVector128.SByte.1.Store"] = ExtractVector128SByte1Store,
+ ["ExtractVector128.Int16.1.Store"] = ExtractVector128Int161Store,
+ ["ExtractVector128.UInt16.1.Store"] = ExtractVector128UInt161Store,
+ ["ExtractVector128.Int32.1.Store"] = ExtractVector128Int321Store,
+ ["ExtractVector128.UInt32.1.Store"] = ExtractVector128UInt321Store,
+ ["ExtractVector128.Int64.1.Store"] = ExtractVector128Int641Store,
+ ["ExtractVector128.UInt64.1.Store"] = ExtractVector128UInt641Store,
+ ["ExtractVector128.Single.1.Store"] = ExtractVector128Single1Store,
+ ["ExtractVector128.Double.1.Store"] = ExtractVector128Double1Store,
+ ["Insert.Byte.1"] = InsertByte1,
+ ["Insert.Byte.20"] = InsertByte20,
+ ["Insert.SByte.1"] = InsertSByte1,
+ ["Insert.SByte.20"] = InsertSByte20,
+ ["Insert.Int16.1"] = InsertInt161,
+ ["Insert.Int16.11"] = InsertInt1611,
+ ["Insert.UInt16.1"] = InsertUInt161,
+ ["Insert.UInt16.11"] = InsertUInt1611,
+ ["Insert.Int32.1"] = InsertInt321,
+ ["Insert.Int32.6"] = InsertInt326,
+ ["Insert.UInt32.1"] = InsertUInt321,
+ ["Insert.UInt32.6"] = InsertUInt326,
+ ["Insert.Int64.1"] = InsertInt641,
+ ["Insert.Int64.3"] = InsertInt643,
+ ["Insert.UInt64.1"] = InsertUInt641,
+ ["Insert.UInt64.3"] = InsertUInt643,
+ ["InsertVector128.Byte.1.Load"] = InsertVector128Byte1Load,
+ ["InsertVector128.SByte.1.Load"] = InsertVector128SByte1Load,
+ ["InsertVector128.Int16.1.Load"] = InsertVector128Int161Load,
+ ["InsertVector128.UInt16.1.Load"] = InsertVector128UInt161Load,
+ ["InsertVector128.Int32.1.Load"] = InsertVector128Int321Load,
+ ["InsertVector128.UInt32.1.Load"] = InsertVector128UInt321Load,
+ ["InsertVector128.Int64.1.Load"] = InsertVector128Int641Load,
+ ["InsertVector128.UInt64.1.Load"] = InsertVector128UInt641Load,
+ ["InsertVector128.Single.1.Load"] = InsertVector128Single1Load,
+ ["InsertVector128.Double.1.Load"] = InsertVector128Double1Load,
["Floor.Double"] = FloorDouble,
["Floor.Single"] = FloorSingle,
["GetLowerHalf.Byte"] = GetLowerHalfByte,
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj
index 3555431351..027236a269 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj
@@ -87,6 +87,38 @@
<Compile Include="CompareGreaterThan.Int32.cs" />
<Compile Include="CompareGreaterThan.Int64.cs" />
<Compile Include="CompareGreaterThan.SByte.cs" />
+ <Compile Include="ExtractVector128.Byte.1.cs" />
+ <Compile Include="ExtractVector128.SByte.1.cs" />
+ <Compile Include="ExtractVector128.Int16.1.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.cs" />
+ <Compile Include="ExtractVector128.Int32.1.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.cs" />
+ <Compile Include="ExtractVector128.Int64.1.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.cs" />
+ <Compile Include="ExtractVector128.Byte.1.Store.cs" />
+ <Compile Include="ExtractVector128.SByte.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int16.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int32.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int64.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.Store.cs" />
+ <Compile Include="InsertVector128.Byte.1.cs" />
+ <Compile Include="InsertVector128.SByte.1.cs" />
+ <Compile Include="InsertVector128.Int16.1.cs" />
+ <Compile Include="InsertVector128.UInt16.1.cs" />
+ <Compile Include="InsertVector128.Int32.1.cs" />
+ <Compile Include="InsertVector128.UInt32.1.cs" />
+ <Compile Include="InsertVector128.Int64.1.cs" />
+ <Compile Include="InsertVector128.UInt64.1.cs" />
+ <Compile Include="InsertVector128.Byte.1.Load.cs" />
+ <Compile Include="InsertVector128.SByte.1.Load.cs" />
+ <Compile Include="InsertVector128.Int16.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt16.1.Load.cs" />
+ <Compile Include="InsertVector128.Int32.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt32.1.Load.cs" />
+ <Compile Include="InsertVector128.Int64.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt64.1.Load.cs" />
<Compile Include="Or.Byte.cs" />
<Compile Include="Or.Int16.cs" />
<Compile Include="Or.Int32.cs" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj
index 5570c82acc..7eb8667ead 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj
@@ -87,6 +87,38 @@
<Compile Include="CompareGreaterThan.Int32.cs" />
<Compile Include="CompareGreaterThan.Int64.cs" />
<Compile Include="CompareGreaterThan.SByte.cs" />
+ <Compile Include="ExtractVector128.Byte.1.cs" />
+ <Compile Include="ExtractVector128.SByte.1.cs" />
+ <Compile Include="ExtractVector128.Int16.1.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.cs" />
+ <Compile Include="ExtractVector128.Int32.1.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.cs" />
+ <Compile Include="ExtractVector128.Int64.1.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.cs" />
+ <Compile Include="ExtractVector128.Byte.1.Store.cs" />
+ <Compile Include="ExtractVector128.SByte.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int16.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt16.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int32.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt32.1.Store.cs" />
+ <Compile Include="ExtractVector128.Int64.1.Store.cs" />
+ <Compile Include="ExtractVector128.UInt64.1.Store.cs" />
+ <Compile Include="InsertVector128.Byte.1.cs" />
+ <Compile Include="InsertVector128.SByte.1.cs" />
+ <Compile Include="InsertVector128.Int16.1.cs" />
+ <Compile Include="InsertVector128.UInt16.1.cs" />
+ <Compile Include="InsertVector128.Int32.1.cs" />
+ <Compile Include="InsertVector128.UInt32.1.cs" />
+ <Compile Include="InsertVector128.Int64.1.cs" />
+ <Compile Include="InsertVector128.UInt64.1.cs" />
+ <Compile Include="InsertVector128.Byte.1.Load.cs" />
+ <Compile Include="InsertVector128.SByte.1.Load.cs" />
+ <Compile Include="InsertVector128.Int16.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt16.1.Load.cs" />
+ <Compile Include="InsertVector128.Int32.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt32.1.Load.cs" />
+ <Compile Include="InsertVector128.Int64.1.Load.cs" />
+ <Compile Include="InsertVector128.UInt64.1.Load.cs" />
<Compile Include="Or.Byte.cs" />
<Compile Include="Or.Int16.cs" />
<Compile Include="Or.Int32.cs" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.Store.cs
new file mode 100644
index 0000000000..0ec5ded3b9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Byte1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Byte1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = 16 / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Byte1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Byte1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Byte*), typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Byte*)),
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (Byte*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Byte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1Store();
+ Avx2.ExtractVector128((Byte*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((Byte*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.cs
new file mode 100644
index 0000000000..2cc202e806
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Byte.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128Byte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Byte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = 16 / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Vector256<Byte> _clsVar;
+
+ private Vector256<Byte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Byte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Byte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Byte1();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Byte>(Vector256<Byte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.Store.cs
new file mode 100644
index 0000000000..2554632bee
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Int161Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int161Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = 16 / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int161Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int161Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int16*), typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int16*)),
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (Int16*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Int16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161Store();
+ Avx2.ExtractVector128((Int16*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((Int16*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.cs
new file mode 100644
index 0000000000..38e04fac97
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int16.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128Int161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = 16 / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Vector256<Int16> _clsVar;
+
+ private Vector256<Int16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int161();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Int16>(Vector256<Int16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.Store.cs
new file mode 100644
index 0000000000..d6ff51f478
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Int321Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int321Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = 16 / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int321Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int321Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int32*), typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int32*)),
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (Int32*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Int32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321Store();
+ Avx2.ExtractVector128((Int32*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((Int32*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.cs
new file mode 100644
index 0000000000..fc93d547e8
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int32.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128Int321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int RetElementCount = 16 / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Vector256<Int32> _clsVar;
+
+ private Vector256<Int32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int321();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Int32>(Vector256<Int32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.Store.cs
new file mode 100644
index 0000000000..ad8d67478c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128Int641Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int641Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = 16 / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int641Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int641Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Int64*), typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(Int64*)),
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (Int64*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((Int64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641Store();
+ Avx2.ExtractVector128((Int64*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((Int64*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.cs
new file mode 100644
index 0000000000..c9d36d21b7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.Int64.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128Int641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128Int641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int RetElementCount = 16 / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Vector256<Int64> _clsVar;
+
+ private Vector256<Int64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128Int641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128Int641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128Int641();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<Int64>(Vector256<Int64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.Store.cs
new file mode 100644
index 0000000000..4a3b8ccf5d
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128SByte1Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128SByte1Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = 16 / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128SByte1Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128SByte1Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(SByte*), typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(SByte*)),
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (SByte*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((SByte*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1Store();
+ Avx2.ExtractVector128((SByte*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((SByte*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.cs
new file mode 100644
index 0000000000..d581fe0e56
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.SByte.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128SByte1()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128SByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = 16 / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static Vector256<SByte> _clsVar;
+
+ private Vector256<SByte> _fld;
+
+ private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128SByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128SByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128SByte1();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[16])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 16]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<SByte>(Vector256<SByte><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.Store.cs
new file mode 100644
index 0000000000..56e756ca6c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128UInt161Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt161Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = 16 / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt161Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt161Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt16*), typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt16*)),
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (UInt16*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((UInt16*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161Store();
+ Avx2.ExtractVector128((UInt16*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((UInt16*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.cs
new file mode 100644
index 0000000000..72a583e4c7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt16.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128UInt161()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = 16 / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static Vector256<UInt16> _clsVar;
+
+ private Vector256<UInt16> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt161();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[8])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 8]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<UInt16>(Vector256<UInt16><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.Store.cs
new file mode 100644
index 0000000000..353e23a7b9
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128UInt321Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt321Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = 16 / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt321Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt321Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt32*), typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt32*)),
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (UInt32*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((UInt32*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321Store();
+ Avx2.ExtractVector128((UInt32*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((UInt32*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.cs
new file mode 100644
index 0000000000..374751b4f2
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt32.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128UInt321()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int RetElementCount = 16 / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static Vector256<UInt32> _clsVar;
+
+ private Vector256<UInt32> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt321();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[4])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 4]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<UInt32>(Vector256<UInt32><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.Store.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.Store.cs
new file mode 100644
index 0000000000..60b9e27e34
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.Store.cs
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 ExtractVector128UInt641Store()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt641Store
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = 16 / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt641Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt641Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ Avx2.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ Avx2.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ Avx2.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(UInt64*), typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof(UInt64*)),
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ Avx2.ExtractVector128(
+ (UInt64*)_dataTable.outArrayPtr,
+ _clsVar,
+ 1
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ Avx2.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ Avx2.ExtractVector128((UInt64*)_dataTable.outArrayPtr, firstOp, 1);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641Store();
+ Avx2.ExtractVector128((UInt64*)_dataTable.outArrayPtr, test._fld, 1);
+ }
+
+ public void RunFldScenario()
+ {
+ Avx2.ExtractVector128((UInt64*)_dataTable.outArrayPtr, _fld, 1);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.cs
new file mode 100644
index 0000000000..f1fcefa48c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ExtractVector128.UInt64.1.cs
@@ -0,0 +1,313 @@
+// 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 ExtractVector128UInt641()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__ExtractVector128UInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int RetElementCount = 16 / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static Vector256<UInt64> _clsVar;
+
+ private Vector256<UInt64> _fld;
+
+ private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleUnaryOpTest__ExtractVector128UInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__ExtractVector128UInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.ExtractVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.ExtractVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.ExtractVector128), new Type[] { typeof(Vector256<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.ExtractVector128(
+ _clsVar,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArrayPtr);
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr));
+ var result = Avx2.ExtractVector128(firstOp, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__ExtractVector128UInt641();
+ var result = Avx2.ExtractVector128(test._fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.ExtractVector128(_fld, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[2])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((result[i] != firstOp[i + 2]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.ExtractVector128)}<UInt64>(Vector256<UInt64><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.Load.cs
new file mode 100644
index 0000000000..6c2de2f66b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Byte1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Byte1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = 16 / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
+ private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Byte1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Byte1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ (Byte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ (Byte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ (Byte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Byte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Byte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (Byte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Byte*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = (Byte*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = (Byte*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = (Byte*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1Load();
+ var result = Avx2.InsertVector128(test._fld1, (Byte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Byte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (Byte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Byte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Byte> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.cs
new file mode 100644
index 0000000000..5c7c198199
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Byte.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Byte1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Byte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = 16 / sizeof(Byte);
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
+ private static Byte[] _data2 = new Byte[Op2ElementCount];
+
+ private static Vector256<Byte> _clsVar1;
+ private static Vector128<Byte> _clsVar2;
+
+ private Vector256<Byte> _fld1;
+ private Vector128<Byte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Byte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Byte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Vector128<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Vector128<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Byte>), typeof(Vector128<Byte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Byte1();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Byte>(Vector256<Byte>, Vector128<Byte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.Load.cs
new file mode 100644
index 0000000000..56fc66cb53
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int161Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int161Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = 16 / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
+ private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int161Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int161Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0,short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ (Int16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ (Int16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ (Int16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Int16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (Int16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int16*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = (Int16*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = (Int16*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = (Int16*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161Load();
+ var result = Avx2.InsertVector128(test._fld1, (Int16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (Int16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int16> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int16>(Vector256<Int16>, Vector128<Int16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.cs
new file mode 100644
index 0000000000..dce21e86d4
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int16.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int161()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = 16 / sizeof(Int16);
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
+ private static Int16[] _data2 = new Int16[Op2ElementCount];
+
+ private static Vector256<Int16> _clsVar1;
+ private static Vector128<Int16> _clsVar2;
+
+ private Vector256<Int16> _fld1;
+ private Vector128<Int16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(0, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(0, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Vector128<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Vector128<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int16>), typeof(Vector128<Int16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int161();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int16>(Vector256<Int16>, Vector128<Int16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.Load.cs
new file mode 100644
index 0000000000..f0c27ff6d1
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int321Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int321Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int Op2ElementCount = 16 / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
+ private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int321Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int321Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ (Int32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ (Int32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ (Int32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Int32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (Int32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int32*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = (Int32*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = (Int32*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = (Int32*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321Load();
+ var result = Avx2.InsertVector128(test._fld1, (Int32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (Int32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int32> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[Op1ElementCount];
+ Int32[] inArray2 = new Int32[Op2ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.cs
new file mode 100644
index 0000000000..3850505248
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int32.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int321()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int32);
+ private const int Op2ElementCount = 16 / sizeof(Int32);
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
+ private static Int32[] _data2 = new Int32[Op2ElementCount];
+
+ private static Vector256<Int32> _clsVar1;
+ private static Vector128<Int32> _clsVar2;
+
+ private Vector256<Int32> _fld1;
+ private Vector128<Int32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (int)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (int)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Vector128<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Vector128<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int32>), typeof(Vector128<Int32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int321();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray1 = new Int32[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] left, Int32[] right, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int32>(Vector256<Int32>, Vector128<Int32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.Load.cs
new file mode 100644
index 0000000000..da0f4f13f7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int641Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int641Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int Op2ElementCount = 16 / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
+ private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int641Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int641Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ (Int64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ (Int64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ (Int64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Int64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(Int64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (Int64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (Int64*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = (Int64*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = (Int64*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = (Int64*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641Load();
+ var result = Avx2.InsertVector128(test._fld1, (Int64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (Int64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (Int64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (Int64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<Int64> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[Op1ElementCount];
+ Int64[] inArray2 = new Int64[Op2ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int64>(Vector256<Int64>, Vector128<Int64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.cs
new file mode 100644
index 0000000000..1ceadc38f2
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.Int64.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128Int641()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128Int641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int64);
+ private const int Op2ElementCount = 16 / sizeof(Int64);
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
+ private static Int64[] _data2 = new Int64[Op2ElementCount];
+
+ private static Vector256<Int64> _clsVar1;
+ private static Vector128<Int64> _clsVar2;
+
+ private Vector256<Int64> _fld1;
+ private Vector128<Int64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128Int641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128Int641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (long)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((Int64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<Int64>), typeof(Vector128<Int64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128Int641();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray1 = new Int64[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] left, Int64[] right, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<Int64>(Vector256<Int64>, Vector128<Int64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.Load.cs
new file mode 100644
index 0000000000..d3abe77188
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128SByte1Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128SByte1Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = 16 / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
+ private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128SByte1Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128SByte1Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0,sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ (SByte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ (SByte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ (SByte*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(SByte*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(SByte*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (SByte*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (SByte*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = (SByte*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = (SByte*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = (SByte*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1Load();
+ var result = Avx2.InsertVector128(test._fld1, (SByte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (SByte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (SByte*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (SByte*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<SByte> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<SByte>(Vector256<SByte>, Vector128<SByte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.cs
new file mode 100644
index 0000000000..388796251f
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.SByte.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128SByte1()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128SByte1
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = 16 / sizeof(SByte);
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
+ private static SByte[] _data2 = new SByte[Op2ElementCount];
+
+ private static Vector256<SByte> _clsVar1;
+ private static Vector128<SByte> _clsVar2;
+
+ private Vector256<SByte> _fld1;
+ private Vector128<SByte> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128SByte1()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128SByte1()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(Vector128<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(Vector128<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<SByte>), typeof(Vector128<SByte>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128SByte1();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 15 ? result[i] != right[i - 16] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<SByte>(Vector256<SByte>, Vector128<SByte>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.Load.cs
new file mode 100644
index 0000000000..6d0c365fb4
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt161Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt161Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = 16 / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+ private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt161Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt161Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0,ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ (UInt16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ (UInt16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ (UInt16*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(UInt16*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt16*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (UInt16*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt16*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = (UInt16*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = (UInt16*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = (UInt16*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161Load();
+ var result = Avx2.InsertVector128(test._fld1, (UInt16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (UInt16*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt16*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt16> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<UInt16>(Vector256<UInt16>, Vector128<UInt16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.cs
new file mode 100644
index 0000000000..67decefd50
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt16.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt161()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt161
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = 16 / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
+ private static UInt16[] _data2 = new UInt16[Op2ElementCount];
+
+ private static Vector256<UInt16> _clsVar1;
+ private static Vector128<UInt16> _clsVar2;
+
+ private Vector256<UInt16> _fld1;
+ private Vector128<UInt16> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt161()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt161()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(0, ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(Vector128<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(Vector128<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt16>), typeof(Vector128<UInt16>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt161();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 7 ? result[i] != right[i - 8] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<UInt16>(Vector256<UInt16>, Vector128<UInt16>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.Load.cs
new file mode 100644
index 0000000000..0ab344b409
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt321Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt321Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int Op2ElementCount = 16 / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+ private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt321Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt321Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ (UInt32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ (UInt32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ (UInt32*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(UInt32*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt32*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (UInt32*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt32*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = (UInt32*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = (UInt32*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = (UInt32*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321Load();
+ var result = Avx2.InsertVector128(test._fld1, (UInt32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (UInt32*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt32*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt32> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
+ UInt32[] inArray2 = new UInt32[Op2ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<UInt32>(Vector256<UInt32>, Vector128<UInt32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.cs
new file mode 100644
index 0000000000..c6b4daf6ee
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt32.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt321()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt321
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt32);
+ private const int Op2ElementCount = 16 / sizeof(UInt32);
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
+ private static UInt32[] _data2 = new UInt32[Op2ElementCount];
+
+ private static Vector256<UInt32> _clsVar1;
+ private static Vector128<UInt32> _clsVar2;
+
+ private Vector256<UInt32> _fld1;
+ private Vector128<UInt32> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt321()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt321()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (uint)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (uint)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(Vector128<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(Vector128<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt32>), typeof(Vector128<UInt32>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt321();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray1 = new UInt32[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] left, UInt32[] right, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 3 ? result[i] != right[i - 4] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<UInt32>(Vector256<UInt32>, Vector128<UInt32>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.Load.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.Load.cs
new file mode 100644
index 0000000000..69db416db5
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.Load.cs
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt641Load()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt641Load
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int Op2ElementCount = 16 / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+ private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt641Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt641Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0,int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ (UInt64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ (UInt64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ (UInt64*)(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(UInt64*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof(UInt64*)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ (UInt64*)_dataTable.inArray2Ptr,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, (UInt64*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = (UInt64*)_dataTable.inArray2Ptr;
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = (UInt64*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = (UInt64*)(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641Load();
+ var result = Avx2.InsertVector128(test._fld1, (UInt64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, (UInt64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, (UInt64*)(_dataTable.inArray2Ptr), 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, (UInt64*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<UInt64> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
+ UInt64[] inArray2 = new UInt64[Op2ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<UInt64>(Vector256<UInt64>, Vector128<UInt64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.cs
new file mode 100644
index 0000000000..9fee258ffa
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/InsertVector128.UInt64.1.cs
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void InsertVector128UInt641()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if (Avx.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 (Avx.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 (Avx.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__InsertVector128UInt641
+ {
+ private const int VectorSize = 32;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt64);
+ private const int Op2ElementCount = 16 / sizeof(UInt64);
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
+ private static UInt64[] _data2 = new UInt64[Op2ElementCount];
+
+ private static Vector256<UInt64> _clsVar1;
+ private static Vector128<UInt64> _clsVar2;
+
+ private Vector256<UInt64> _fld1;
+ private Vector128<UInt64> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+
+ static SimpleBinaryOpTest__InsertVector128UInt641()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__InsertVector128UInt641()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ulong)(random.Next(0, int.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Avx2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Avx2.InsertVector128(
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Avx2.InsertVector128(
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Avx2).GetMethod(nameof(Avx2.InsertVector128), new Type[] { typeof(Vector256<UInt64>), typeof(Vector128<UInt64>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
+ LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr)),
+ (byte)1
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Avx2.InsertVector128(
+ _clsVar1,
+ _clsVar2,
+ 1
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var right = LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.InsertVector128(left, right, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__InsertVector128UInt641();
+ var result = Avx2.InsertVector128(test._fld1, test._fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Avx2.InsertVector128(_fld1, _fld2, 1);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector256<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.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray1 = new UInt64[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] left, UInt64[] right, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != left[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((i > 1 ? result[i] != right[i - 2] : result[i] != left[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Avx2)}.{nameof(Avx2.InsertVector128)}<UInt64>(Vector256<UInt64>, Vector128<UInt64>.1): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs
index 4d15e34f42..65d93f357d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Program.Avx2.cs
@@ -72,6 +72,38 @@ namespace JIT.HardwareIntrinsics.X86
["CompareGreaterThan.Int32"] = CompareGreaterThanInt32,
["CompareGreaterThan.Int64"] = CompareGreaterThanInt64,
["CompareGreaterThan.SByte"] = CompareGreaterThanSByte,
+ ["ExtractVector128.Byte.1"] = ExtractVector128Byte1,
+ ["ExtractVector128.SByte.1"] = ExtractVector128SByte1,
+ ["ExtractVector128.Int16.1"] = ExtractVector128Int161,
+ ["ExtractVector128.UInt16.1"] = ExtractVector128UInt161,
+ ["ExtractVector128.Int32.1"] = ExtractVector128Int321,
+ ["ExtractVector128.UInt32.1"] = ExtractVector128UInt321,
+ ["ExtractVector128.Int64.1"] = ExtractVector128Int641,
+ ["ExtractVector128.UInt64.1"] = ExtractVector128UInt641,
+ ["ExtractVector128.Byte.1.Store"] = ExtractVector128Byte1Store,
+ ["ExtractVector128.SByte.1.Store"] = ExtractVector128SByte1Store,
+ ["ExtractVector128.Int16.1.Store"] = ExtractVector128Int161Store,
+ ["ExtractVector128.UInt16.1.Store"] = ExtractVector128UInt161Store,
+ ["ExtractVector128.Int32.1.Store"] = ExtractVector128Int321Store,
+ ["ExtractVector128.UInt32.1.Store"] = ExtractVector128UInt321Store,
+ ["ExtractVector128.Int64.1.Store"] = ExtractVector128Int641Store,
+ ["ExtractVector128.UInt64.1.Store"] = ExtractVector128UInt641Store,
+ ["InsertVector128.Byte.1"] = InsertVector128Byte1,
+ ["InsertVector128.SByte.1"] = InsertVector128SByte1,
+ ["InsertVector128.Int16.1"] = InsertVector128Int161,
+ ["InsertVector128.UInt16.1"] = InsertVector128UInt161,
+ ["InsertVector128.Int32.1"] = InsertVector128Int321,
+ ["InsertVector128.UInt32.1"] = InsertVector128UInt321,
+ ["InsertVector128.Int64.1"] = InsertVector128Int641,
+ ["InsertVector128.UInt64.1"] = InsertVector128UInt641,
+ ["InsertVector128.Byte.1.Load"] = InsertVector128Byte1Load,
+ ["InsertVector128.SByte.1.Load"] = InsertVector128SByte1Load,
+ ["InsertVector128.Int16.1.Load"] = InsertVector128Int161Load,
+ ["InsertVector128.UInt16.1.Load"] = InsertVector128UInt161Load,
+ ["InsertVector128.Int32.1.Load"] = InsertVector128Int321Load,
+ ["InsertVector128.UInt32.1.Load"] = InsertVector128UInt321Load,
+ ["InsertVector128.Int64.1.Load"] = InsertVector128Int641Load,
+ ["InsertVector128.UInt64.1.Load"] = InsertVector128UInt641Load,
["Or.Byte"] = OrByte,
["Or.Int16"] = OrInt16,
["Or.Int32"] = OrInt32,
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractStoreTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractStoreTest.template
new file mode 100644
index 0000000000..e686366914
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractStoreTest.template
@@ -0,0 +1,297 @@
+// 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.Reflection;
+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 {Method}{RetBaseType}{Imm}Store()
+ {
+ var test = new SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}Store();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if ({LoadIsa}.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 ({LoadIsa}.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 ({LoadIsa}.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}Store
+ {
+ private const int VectorSize = {VectorSize};
+
+ private const int Op1ElementCount = VectorSize / sizeof({Op1BaseType});
+ private const int RetElementCount = 16 / sizeof({RetBaseType});
+
+ private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount];
+
+ private static {Op1VectorType}<{Op1BaseType}> _clsVar;
+
+ private {Op1VectorType}<{Op1BaseType}> _fld;
+
+ private SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable;
+
+ static SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}Store()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}Store()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data, new {RetBaseType}[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => {Isa}.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ {Isa}.{Method}(
+ ({Op1BaseType}*)_dataTable.outArrayPtr,
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr),
+ {Imm}
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ {Isa}.{Method}(
+ ({Op1BaseType}*)_dataTable.outArrayPtr,
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ {Imm}
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ {Isa}.{Method}(
+ ({Op1BaseType}*)_dataTable.outArrayPtr,
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ {Imm}
+ );
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)),
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr),
+ (byte){Imm}
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)),
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ (byte){Imm}
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}*), typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Pointer.Box(_dataTable.outArrayPtr, typeof({Op1BaseType}*)),
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ (byte){Imm}
+ });
+
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ {Isa}.{Method}(
+ ({Op1BaseType}*)_dataTable.outArrayPtr,
+ _clsVar,
+ {Imm}
+ );
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr);
+ {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, firstOp, {Imm});
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
+ {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, firstOp, {Imm});
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
+ {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, firstOp, {Imm});
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}Store();
+ {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, test._fld, {Imm});
+ }
+
+ public void RunFldScenario()
+ {
+ {Isa}.{Method}(({Op1BaseType}*)_dataTable.outArrayPtr, _fld, {Imm});
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "")
+ {
+ if ({ValidateFirstResult})
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ({ValidateRemainingResults})
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractVector128Test.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractVector128Test.template
new file mode 100644
index 0000000000..7765e86fe6
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ExtractVector128Test.template
@@ -0,0 +1,313 @@
+// 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 {Method}{RetBaseType}{Imm}()
+ {
+ var test = new SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if ({LoadIsa}.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 ({LoadIsa}.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 ({LoadIsa}.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}
+ {
+ private const int VectorSize = {VectorSize};
+
+ private const int Op1ElementCount = VectorSize / sizeof({Op1BaseType});
+ private const int RetElementCount = 16 / sizeof({RetBaseType});
+
+ private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount];
+
+ private static {Op1VectorType}<{Op1BaseType}> _clsVar;
+
+ private {Op1VectorType}<{Op1BaseType}> _fld;
+
+ private SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable;
+
+ static SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), VectorSize);
+ }
+
+ public SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
+ _dataTable = new SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data, new {RetBaseType}[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => {Isa}.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = {Isa}.{Method}(
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = {Isa}.{Method}(
+ _clsVar,
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr);
+ var result = {Isa}.{Method}(firstOp, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
+ var result = {Isa}.{Method}(firstOp, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
+ var result = {Isa}.{Method}(firstOp, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleUnaryOpTest__{Method}{RetBaseType}{Imm}();
+ var result = {Isa}.{Method}(test._fld, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = {Isa}.{Method}(_fld, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "")
+ {
+ if ({ValidateFirstResult})
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ({ValidateRemainingResults})
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}><9>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
index bd64a8e9c2..07f6be07da 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
@@ -77,144 +77,169 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
private static readonly (string templateFileName, Dictionary<string, string> templateData)[] Sse2Inputs = new []
{
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] + right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(~left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(~left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(~left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(~left[i] & right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] == right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((byte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((byte)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((short)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((int)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((ushort)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((ushort)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((uint)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((uint)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] > right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((short)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((int)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] >= right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] < right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] < right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] < right[i]) ? unchecked((short)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] < right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] < right[i]) ? unchecked((int)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] < right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] < right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] <= right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] != right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] > right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] >= right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] < right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] <= right[i]) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareOrdered", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((!double.IsNaN(left[0]) && !double.IsNaN(right[0])) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((!double.IsNaN(left[i]) && !double.IsNaN(right[i])) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareUnordered", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((double.IsNaN(left[0]) || double.IsNaN(right[0])) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((double.IsNaN(left[i]) || double.IsNaN(right[i])) ? -1 : 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] / right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
- ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
- ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
- ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Math.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(Math.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "Math.Max(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Max(left[i], right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "Math.Max(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Max(left[i], right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Math.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(Math.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MinValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MinValue))", ["ValidateFirstResult"] = "Math.Min(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Min(left[i], right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MinValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MinValue))", ["ValidateFirstResult"] = "Math.Min(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Min(left[i], right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] * right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] | right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] | right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] | right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] | right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(ulong)(left[i] | right[i]) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] << 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(ushort)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(ushort)(firstOp[i] << 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] << 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(uint)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(uint)(firstOp[i] << 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(long)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(long)(firstOp[i] << 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(ulong)(firstOp[i] << 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0!= result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)8", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 8"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)8", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 8"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] >> 15) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] >> 15) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] >> 31) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] >> 31) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(ushort)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(ushort)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(uint)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(uint)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(long)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(long)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(ulong)(firstOp[i] >> 1) != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0!= result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)8", ["ValidateFirstResult"] = "result[0] != 8", ["ValidateRemainingResults"] = "(i == 15 ? result[i] != 0 : result[i] != 8)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)8", ["ValidateFirstResult"] = "result[0] != 8", ["ValidateRemainingResults"] = "(i == 15 ? result[i] != 0 : result[i] != 8)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "(i == 7 ? result[i] != 0 : result[i] != 2048)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "(i == 7 ? result[i] != 0 : result[i] != 2048)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)8", ["ValidateFirstResult"] = "result[0] != 134217728", ["ValidateRemainingResults"] = "(i == 3 ? result[i] != 0 : result[i] != 134217728)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)8", ["ValidateFirstResult"] = "result[0] != 134217728", ["ValidateRemainingResults"] = "(i == 3 ? result[i] != 0 : result[i] != 134217728)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)8", ["ValidateFirstResult"] = "result[0] != 576460752303423488L", ["ValidateRemainingResults"] = "(result[i] != 0)"}),
- ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)8", ["ValidateFirstResult"] = "result[0] != 576460752303423488UL", ["ValidateRemainingResults"] = "(result[i] != 0)"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] - right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] - right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] - right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] - right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] - right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] ^ right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] ^ right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] ^ right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] ^ right[i]) != result[i]"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] + right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] + right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "Sse2Verify.AddSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "Sse2Verify.AddSaturate(left[i], right[i], result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "Sse2Verify.AddSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "Sse2Verify.AddSaturate(left[i], right[i], result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "Sse2Verify.AddSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "Sse2Verify.AddSaturate(left[i], right[i], result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(ushort.MinValue,ushort.MaxValue))",["NextValueOp2"] = "(ushort)(random.Next(ushort.MinValue,ushort.MaxValue))", ["ValidateFirstResult"] = "Sse2Verify.AddSaturate(left[0], right[0], result[0])", ["ValidateRemainingResults"] = "Sse2Verify.AddSaturate(left[i], right[i], result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AddScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "And", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(~left[0] & right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(~left[i] & right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "AndNot", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "Average", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(byte)((left[0] + right[0] + 1) >> 1) != result[0]", ["ValidateRemainingResults"] = "(byte)((left[i] + right[i] + 1) >> 1) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Average", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(ushort.MinValue,ushort.MaxValue))",["NextValueOp2"] = "(ushort)(random.Next(ushort.MinValue,ushort.MaxValue))", ["ValidateFirstResult"] = "(ushort)((left[0] + right[0] + 1) >> 1) != result[0]", ["ValidateRemainingResults"] = "(ushort)((left[i] + right[i] + 1) >> 1) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] == right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] == right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((byte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((byte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((short)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((int)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((ushort)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((ushort)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((uint)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((uint)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] > right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] > right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((short)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((int)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] >= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] >= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] < right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] < right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] < right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] < right[i]) ? unchecked((short)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] < right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] < right[i]) ? unchecked((int)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] < right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] < right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] <= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] <= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((left[0] != right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((left[i] != right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotGreaterThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] > right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] > right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotGreaterThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] >= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] >= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotLessThan", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] < right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] < right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareNotLessThanOrEqual", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != (!(left[0] <= right[0]) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != (!(left[i] <= right[i]) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareOrdered", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((!double.IsNaN(left[0]) && !double.IsNaN(right[0])) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((!double.IsNaN(left[i]) && !double.IsNaN(right[i])) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "CompareUnordered", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != ((double.IsNaN(left[0]) || double.IsNaN(right[0])) ? -1 : 0)", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != ((double.IsNaN(left[i]) || double.IsNaN(right[i])) ? -1 : 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Divide", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] / right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "DivideScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Extract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Insert", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2", ["Imm"] = "129", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Math.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(Math.Max(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "Math.Max(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Max(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Max", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "Math.Max(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Max(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "MaxScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Math.Max(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"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Math.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(Math.Min(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MinValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MinValue))", ["ValidateFirstResult"] = "Math.Min(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Min(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Min", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MinValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MinValue))", ["ValidateFirstResult"] = "Math.Min(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "Math.Min(left[i], right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "MinScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(Math.Min(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"] = "Multiply", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] * right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "MultiplyScalar", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] | right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Or", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(ulong)(left[i] | right[i]) != result[i]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(byte.MinValue, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(ushort.MinValue, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ScalarUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "SetAllVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "random.NextDouble()", ["ValidateFirstResult"] = "result[0] != firstOp[0]", ["ValidateRemainingResults"] = "result[i] != firstOp[0]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] << 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(ushort)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(ushort)(firstOp[i] << 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] << 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(uint)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(uint)(firstOp[i] << 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(long)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(long)(firstOp[i] << 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(firstOp[0] << 1) != result[0]", ["ValidateRemainingResults"] = "(ulong)(firstOp[i] << 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0!= result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)8", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 8"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)8", ["ValidateFirstResult"] = "result[0] != 0", ["ValidateRemainingResults"] = "result[i] != 8"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftLeftLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "result[i] != 2048"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] >> 15) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] >> 15) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightArithmetic", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] >> 31) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] >> 31) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(short)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(short)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(ushort)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(ushort)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(int)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(int)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(uint)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(uint)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(long)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(long)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(firstOp[0] >> 1) != result[0]", ["ValidateRemainingResults"] = "(ulong)(firstOp[i] >> 1) != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0!= result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "0 != result[0]", ["ValidateRemainingResults"] = "0 != result[i]"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)8", ["ValidateFirstResult"] = "result[0] != 8", ["ValidateRemainingResults"] = "(i == 15 ? result[i] != 0 : result[i] != 8)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)8", ["ValidateFirstResult"] = "result[0] != 8", ["ValidateRemainingResults"] = "(i == 15 ? result[i] != 0 : result[i] != 8)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "(i == 7 ? result[i] != 0 : result[i] != 2048)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)8", ["ValidateFirstResult"] = "result[0] != 2048", ["ValidateRemainingResults"] = "(i == 7 ? result[i] != 0 : result[i] != 2048)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)8", ["ValidateFirstResult"] = "result[0] != 134217728", ["ValidateRemainingResults"] = "(i == 3 ? result[i] != 0 : result[i] != 134217728)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)8", ["ValidateFirstResult"] = "result[0] != 134217728", ["ValidateRemainingResults"] = "(i == 3 ? result[i] != 0 : result[i] != 134217728)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)8", ["ValidateFirstResult"] = "result[0] != 576460752303423488L", ["ValidateRemainingResults"] = "(result[i] != 0)"}),
+ ("ImmUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "ShiftRightLogical128BitLane", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)8", ["ValidateFirstResult"] = "result[0] != 576460752303423488UL", ["ValidateRemainingResults"] = "(result[i] != 0)"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] - right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] - right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] - right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "Subtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["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"] = "SubtractSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["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"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(ushort.MinValue,ushort.MaxValue))",["NextValueOp2"] = "(ushort)(random.Next(ushort.MinValue,ushort.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["VectorSize"] = "16", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["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", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["VectorSize"] = "16", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(long)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(long)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["VectorSize"] = "16", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "(sbyte)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(sbyte)(left[i] ^ right[i]) != result[i]"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse2", ["LoadIsa"] = "Sse2", ["Method"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["VectorSize"] = "16", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["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"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["VectorSize"] = "16", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["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"] = "Xor", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["VectorSize"] = "16", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(ulong)(left[0] ^ right[0]) != result[0]", ["ValidateRemainingResults"] = "(ulong)(left[i] ^ right[i]) != result[i]"}),
};
private static readonly (string templateFileName, Dictionary<string, string> templateData)[] Sse3Inputs = new []
@@ -233,7 +258,7 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue + 1, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != Math.Abs(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != Math.Abs(firstOp[i])"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "Abs", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue + 1, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != Math.Abs(firstOp[0])", ["ValidateRemainingResults"] = "result[i] != Math.Abs(firstOp[i])"}),
("HorizontalBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[i1] != (short)(left[i3] + left[i3 + 1])", ["ValidateRemainingResults"] = "result[i2] != (short)(right[i3] + right[i3 + 1])"}),
- ("HorizontalBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[i1] != (int)(left[i3] + left[i3 + 1])", ["ValidateRemainingResults"] = "result[i2] != (int)(right[i3] + right[i3 + 1])"}),
+ ("HorizontalBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalAdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[i1] != (int)(left[i3] + left[i3 + 1])", ["ValidateRemainingResults"] = "result[i2] != (int)(right[i3] + right[i3 + 1])"}),
("HorizontalBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalAddSaturate", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[i1] != Math.Clamp((left[i3] + left[i3 + 1]), short.MinValue, short.MaxValue)", ["ValidateRemainingResults"] = "result[i2] != Math.Clamp((right[i3] + right[i3 + 1]), short.MinValue, short.MaxValue)"}),
("HorizontalBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["VectorSize"] = "16", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[i1] != (short)(left[i3] - left[i3 + 1])", ["ValidateRemainingResults"] = "result[i2] != (short)(right[i3] - right[i3 + 1])"}),
("HorizontalBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Ssse3", ["LoadIsa"] = "Sse2", ["Method"] = "HorizontalSubtract", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["VectorSize"] = "16", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[i1] != (int)(left[i3] - left[i3 + 1])", ["ValidateRemainingResults"] = "result[i2] != (int)(right[i3] - right[i3 + 1])"}),
@@ -376,11 +401,11 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
};
private static readonly (string templateFileName, Dictionary<string, string> templateData)[] AvxInputs = new []
-{
+{
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Add", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "AddSubtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "((i % 2 != 0) && (BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i]))) || ((i % 2 == 0) && (BitConverter.DoubleToInt64Bits(left[i] - right[i]) != BitConverter.DoubleToInt64Bits(result[i])))"}),
- ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "AddSubtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "((i % 2 != 0) && (BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i]))) || ((i % 2 == 0) && (BitConverter.SingleToInt32Bits(left[i] - right[i]) != BitConverter.SingleToInt32Bits(result[i])))"}),
+ ("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "AddSubtract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] - right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "((i % 2 != 0) && (BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i]))) || ((i % 2 == 0) && (BitConverter.SingleToInt32Bits(left[i] - right[i]) != BitConverter.SingleToInt32Bits(result[i])))"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "And", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "And", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "(BitConverter.SingleToInt32Bits(left[0]) & BitConverter.SingleToInt32Bits(right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "(BitConverter.SingleToInt32Bits(left[i]) & BitConverter.SingleToInt32Bits(right[i])) != BitConverter.SingleToInt32Bits(result[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "AndNot", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["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])"}),
@@ -394,6 +419,22 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "DuplicateEvenIndexed", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(firstOp[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "(i % 2 == 0) ? (BitConverter.DoubleToInt64Bits(firstOp[i]) != BitConverter.DoubleToInt64Bits(result[i])) : (BitConverter.DoubleToInt64Bits(firstOp[i - 1]) != BitConverter.DoubleToInt64Bits(result[i]))"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "DuplicateEvenIndexed", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "(i % 2 == 0) ? (BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i])) : (BitConverter.SingleToInt32Bits(firstOp[i - 1]) != BitConverter.SingleToInt32Bits(result[i]))"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "DuplicateOddIndexed", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(firstOp[1]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "(i % 2 == 0) ? (BitConverter.SingleToInt32Bits(firstOp[i + 1]) != BitConverter.SingleToInt32Bits(result[i])) : (BitConverter.SingleToInt32Bits(firstOp[i]) != BitConverter.SingleToInt32Bits(result[i]))"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "20", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[20])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "20", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[20])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "11", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[11])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "11", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[11])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "6", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[6])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "6", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[6])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "3", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[3])"}),
+ ("ExtractScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "3", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[3])"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
@@ -404,6 +445,42 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(firstOp[4])", ["ValidateRemainingResults"] = "(BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(firstOp[i + 4]))"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(firstOp[2])", ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(firstOp[i + 2]))"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "20", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)0", ["ValidateFirstResult"] = "(i == 20 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "20", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 20 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "11", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 11 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2",["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2",["Imm"] = "11", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 11 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "6", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "6", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "3", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 3 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertScalarTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "3", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 3 ? result[i] != 2 : result[i] != 0)"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(0,sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(0,short.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0,ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["NextValueOp2"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(left[0])", ["ValidateRemainingResults"] = "(i > 3 ? BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(right[i - 4]) : BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(left[i]))"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Double", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["NextValueOp2"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(left[0])", ["ValidateRemainingResults"] = "(i > 1 ? BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(right[i - 2]) : BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(left[i]))"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Floor", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Floor(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Floor(firstOp[i]))"}),
("SimpleUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Floor", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(MathF.Floor(firstOp[0]))", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != BitConverter.SingleToInt32Bits(MathF.Floor(firstOp[i]))"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "GetLowerHalf", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (Op1ElementCount / 2)) ? firstOp[i] : 0)"}),
@@ -513,12 +590,12 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
- ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
+ ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int32", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
- ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
+ ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int64", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
- ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
- ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "(BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[i]))"}),
+ ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "(firstOp[0] != result[i])"}),
+ ("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["VectorSize"] = "32", ["NextValueOp1"] = "(float)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "(BitConverter.SingleToInt32Bits(firstOp[0]) != BitConverter.SingleToInt32Bits(result[i]))"}),
("GenericUnOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Sse2", ["Method"] = "BroadcastScalarToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["VectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "BitConverter.DoubleToInt64Bits(firstOp[0]) != BitConverter.DoubleToInt64Bits(result[0])", ["ValidateRemainingResults"] = "(BitConverter.DoubleToInt64Bits(firstOp[0]) != BitConverter.DoubleToInt64Bits(result[i]))"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((byte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((byte)(-1)) : 0)"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "CompareEqual", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int16", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] == right[0]) ? unchecked((short)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] == right[i]) ? unchecked((short)(-1)) : 0)"}),
@@ -532,6 +609,38 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((int)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((int)(-1)) : 0)"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int64", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((long)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((long)(-1)) : 0)"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "CompareGreaterThan", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "SByte", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != ((left[0] > right[0]) ? unchecked((sbyte)(-1)) : 0)", ["ValidateRemainingResults"] = "result[i] != ((left[i] > right[i]) ? unchecked((sbyte)(-1)) : 0)"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[16]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 16])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[8]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 8])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[4]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 4])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("ExtractStoreTest.template", new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "ExtractVector128", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != firstOp[2]", ["ValidateRemainingResults"] = "(result[i] != firstOp[i + 2])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertVector128Test.template",new Dictionary<string, string>{["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(0,sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(0,short.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["NextValueOp2"] = "(ushort)(random.Next(0,ushort.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(uint)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 3 ? result[i] != right[i - 4] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(long)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
+ ("InsertLoadTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["Imm"] = "1", ["VectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["NextValueOp2"] = "(ulong)(random.Next(0,int.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 1 ? result[i] != right[i - 2] : result[i] != left[i])"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "Or", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Byte", ["VectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(byte)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(byte)(left[i] | right[i]) != result[i]"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "Or", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int16", ["VectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "(short)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(short)(left[i] | right[i]) != result[i]"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Avx2", ["LoadIsa"] = "Avx", ["Method"] = "Or", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector256", ["Op2BaseType"] = "Int32", ["VectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["NextValueOp2"] = "(int)(random.Next(int.MinValue, int.MaxValue))", ["ValidateFirstResult"] = "(int)(left[0] | right[0]) != result[0]", ["ValidateRemainingResults"] = "(int)(left[i] | right[i]) != result[i]"}),
@@ -637,21 +746,39 @@ namespace JIT.HardwareIntrinsics.X86
private static bool isImmTemplate(string name)
{
- return name == "ImmUnOpTest.template" || name == "InsertScalarTest.template" ||
- name == "ExtractScalarTest.template" || name == "ImmBinOpTest.template";
+ return name == "ImmUnOpTest.template" || name == "InsertScalarTest.template" ||
+ name == "ExtractScalarTest.template" || name == "InsertVector128Test.template" ||
+ name == "ExtractVector128Test.template" || name == "InsertLoadTest.template" ||
+ name == "ExtractStoreTest.template" || name == "ImmBinOpTest.template";
}
private static void ProcessInput(StreamWriter testListFile, (string templateFileName, Dictionary<string, string> templateData) input)
+
{
var testName = $"{input.templateData["Method"]}.{input.templateData["RetBaseType"]}";
+ var suffix = "";
+
if (isImmTemplate(input.templateFileName))
{
testName += $".{input.templateData["Imm"]}";
+ suffix += $"{input.templateData["Imm"]}";
+ }
+
+ if (input.templateFileName == "InsertLoadTest.template")
+ {
+ testName += ".Load";
+ suffix += "Load";
+ }
+ else if (input.templateFileName == "ExtractStoreTest.template")
+ {
+ testName += ".Store";
+ suffix += "Store";
}
// Ex: ["Add.Single"] = AddSingle
- testListFile.WriteLine($@" [""{testName}""] = {input.templateData["Method"]}{input.templateData["RetBaseType"]}{(isImmTemplate(input.templateFileName) ? input.templateData["Imm"] : "")},");
+ testListFile.WriteLine($@" [""{testName}""] = {input.templateData["Method"]}{input.templateData["RetBaseType"]}{suffix},");
+
var testFileName = Path.Combine("..", input.templateData["Isa"], $"{testName}.cs");
var template = File.ReadAllText(input.templateFileName);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertLoadTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertLoadTest.template
new file mode 100644
index 0000000000..7759c8645b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertLoadTest.template
@@ -0,0 +1,339 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void {Method}{RetBaseType}{Imm}Load()
+ {
+ var test = new SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}Load();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if ({LoadIsa}.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 ({LoadIsa}.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 ({LoadIsa}.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}Load
+ {
+ private const int VectorSize = {VectorSize};
+
+ private const int Op1ElementCount = VectorSize / sizeof({Op1BaseType});
+ private const int Op2ElementCount = 16 / sizeof({Op2BaseType});
+ private const int RetElementCount = VectorSize / sizeof({RetBaseType});
+
+ private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
+ private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
+
+ private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
+ private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
+
+ private {Op1VectorType}<{Op1BaseType}> _fld1;
+ private {Op2VectorType}<{Op2BaseType}> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable;
+
+ static SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}Load()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}Load()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
+ _dataTable = new SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => {Isa}.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = {Isa}.{Method}(
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
+ ({Op2BaseType}*)_dataTable.inArray2Ptr,
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ ({Op2BaseType}*)(_dataTable.inArray2Ptr),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ ({Op2BaseType}*)(_dataTable.inArray2Ptr),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2BaseType}*), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof({Op2BaseType}*)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2BaseType}*), typeof(byte) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof({Op2BaseType}*)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2BaseType}*), typeof(byte) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ Pointer.Box(_dataTable.inArray2Ptr, typeof({Op2BaseType}*)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = {Isa}.{Method}(
+ _clsVar1,
+ ({Op2BaseType}*)_dataTable.inArray2Ptr,
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, ({Op2BaseType}*)_dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var right = ({Op2BaseType}*)_dataTable.inArray2Ptr;
+ var result = {Isa}.{Method}(left, right, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var right = ({Op2BaseType}*)(_dataTable.inArray2Ptr);
+ var result = {Isa}.{Method}(left, right, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var right = ({Op2BaseType}*)(_dataTable.inArray2Ptr);
+ var result = {Isa}.{Method}(left, right, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}Load();
+ var result = {Isa}.{Method}(test._fld1, ({Op2BaseType}*)(_dataTable.inArray2Ptr), {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, ({Op2BaseType}*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = {Isa}.{Method}(_fld1, ({Op2BaseType}*)(_dataTable.inArray2Ptr), {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, ({Op2BaseType}*)(_dataTable.inArray2Ptr), _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
+ {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
+ {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "")
+ {
+ if ({ValidateFirstResult})
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ({ValidateRemainingResults})
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>.{Imm}): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertVector128Test.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertVector128Test.template
new file mode 100644
index 0000000000..535ab774e6
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/InsertVector128Test.template
@@ -0,0 +1,338 @@
+// 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;
+using static System.Runtime.Intrinsics.X86.Sse2;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public static partial class Program
+ {
+ private static void {Method}{RetBaseType}{Imm}()
+ {
+ var test = new SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ if ({LoadIsa}.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 ({LoadIsa}.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 ({LoadIsa}.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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}
+ {
+ private const int VectorSize = {VectorSize};
+
+ private const int Op1ElementCount = VectorSize / sizeof({Op1BaseType});
+ private const int Op2ElementCount = 16 / sizeof({Op2BaseType});
+ private const int RetElementCount = VectorSize / sizeof({RetBaseType});
+
+ private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
+ private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
+
+ private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
+ private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
+
+ private {Op1VectorType}<{Op1BaseType}> _fld1;
+ private {Op2VectorType}<{Op2BaseType}> _fld2;
+
+ private SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable;
+
+ static SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
+ _dataTable = new SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => {Isa}.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = {Isa}.{Method}(
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof(byte) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
+ LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
+ (byte){Imm}
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = {Isa}.{Method}(
+ _clsVar1,
+ _clsVar2,
+ {Imm}
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
+ var result = {Isa}.{Method}(left, right, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var right = Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var result = {Isa}.{Method}(left, right, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var right = LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var result = {Isa}.{Method}(left, right, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__{Method}{RetBaseType}{Imm}();
+ var result = {Isa}.{Method}(test._fld1, test._fld2, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = {Isa}.{Method}(_fld1, _fld2, {Imm});
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
+ {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
+ {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "")
+ {
+ if ({ValidateFirstResult})
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ({ValidateRemainingResults})
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>.{Imm}): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest.template
new file mode 100644
index 0000000000..cb0b807147
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest.template
@@ -0,0 +1,253 @@
+// 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 {Method}{RetBaseType}()
+ {
+ bool skipIf32Bit = typeof({Op1BaseType}) == typeof(Int64) ? true :
+ typeof({Op1BaseType}) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__{Method}{RetBaseType}();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__{Method}{RetBaseType}
+ {
+ private const int VectorSize = {VectorSize};
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof({RetBaseType});
+
+ private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount];
+
+ private static {Op1BaseType} _clsVar;
+
+ private {Op1BaseType} _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable;
+
+ static SimpleScalarUnaryOpTest__{Method}{RetBaseType}()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = {NextValueOp1};
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Marshal.SizeOf<{Op1BaseType}>());
+ }
+
+ public SimpleScalarUnaryOpTest__{Method}{RetBaseType}()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = {NextValueOp1};
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Marshal.SizeOf<{Op1BaseType}>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = {NextValueOp1};
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data, new {RetBaseType}[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => {Isa}.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = {Isa}.{Method}(
+ Unsafe.Read<{Op1BaseType}>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<{Op1BaseType}>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1BaseType}) });
+ {Op1BaseType} parameter = ({Op1BaseType}) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = {Isa}.{Method}(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<{Op1BaseType}>(_dataTable.inArrayPtr);
+ var result = {Isa}.{Method}(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__{Method}{RetBaseType}();
+ var result = {Isa}.{Method}(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = {Isa}.{Method}(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult({Op1BaseType} firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
+ {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "")
+ {
+ if ({ValidateFirstResult})
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ({ValidateRemainingResults})
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest_DataTable.cs
new file mode 100644
index 0000000000..8c3b9a0699
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/ScalarUnOpTest_DataTable.cs
@@ -0,0 +1,59 @@
+// 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.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+ public unsafe struct SimpleScalarUnaryOpTest__DataTable<TResult, TOp1> : IDisposable
+ where TResult : struct
+ where TOp1 : struct
+ {
+ private static byte inArrayElementSize;
+ public byte[] inArray;
+ public byte[] outArray;
+
+ private GCHandle inHandle;
+ private GCHandle outHandle;
+
+ private byte simdSize;
+
+ public SimpleScalarUnaryOpTest__DataTable(TOp1[] inArray, TResult[] outArray, int simdSize)
+ {
+ inArrayElementSize = (byte) Marshal.SizeOf<TOp1>();
+ this.inArray = new byte[inArrayElementSize * 2];
+ this.outArray = new byte[simdSize * 2];
+
+ this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.simdSize = unchecked((byte)(simdSize));
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArrayPtr), ref Unsafe.As<TOp1, byte>(ref inArray[0]), (uint)(2 * inArrayElementSize));
+ }
+
+ public void* inArrayPtr => inHandle.AddrOfPinnedObject().ToPointer();
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), simdSize);
+
+ public void Dispose()
+ {
+ inHandle.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, byte expectedAlignment)
+ {
+ // Compute how bad the misalignment is, which is at most (expectedAlignment - 1).
+ // Then subtract that from the expectedAlignment and add it to the original address
+ // to compute the aligned address.
+
+ var misalignment = expectedAlignment - ((ulong)(buffer) % expectedAlignment);
+ return (void*)(buffer + misalignment);
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs
new file mode 100644
index 0000000000..4a22bcfac3
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs
@@ -0,0 +1,330 @@
+// 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 AddSaturateByte()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateByte();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddSaturateByte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / 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__AddSaturateByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddSaturateByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AddSaturate(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AddSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateByte();
+ var result = Sse2.AddSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AddSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.AddSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.AddSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AddSaturate)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs
new file mode 100644
index 0000000000..7a463912c0
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs
@@ -0,0 +1,330 @@
+// 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 AddSaturateInt16()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateInt16();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddSaturateInt16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = VectorSize / 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__AddSaturateInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddSaturateInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AddSaturate(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AddSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateInt16();
+ var result = Sse2.AddSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AddSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.AddSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.AddSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AddSaturate)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs
new file mode 100644
index 0000000000..fc11e93456
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs
@@ -0,0 +1,330 @@
+// 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 AddSaturateSByte()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateSByte();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddSaturateSByte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = VectorSize / 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__AddSaturateSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddSaturateSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AddSaturate(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AddSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateSByte();
+ var result = Sse2.AddSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AddSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.AddSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.AddSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AddSaturate)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs
new file mode 100644
index 0000000000..f3ec17f0dc
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs
@@ -0,0 +1,330 @@
+// 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 AddSaturateUInt16()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateUInt16();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddSaturateUInt16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / 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__AddSaturateUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddSaturateUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AddSaturate(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AddSaturate(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddSaturate), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AddSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddSaturateUInt16();
+ var result = Sse2.AddSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AddSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.AddSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.AddSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AddSaturate)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.cs
deleted file mode 100644
index 3473c82e80..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.cs
+++ /dev/null
@@ -1,127 +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.AddSaturate);
-
- if (Sse2.IsSupported)
- {
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var ushortTable = TestTableSse2<ushort>.Create(testsCount))
- using (var sbyteTable = TestTableSse2<sbyte>.Create(testsCount))
- using (var byteTable = TestTableSse2<byte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.AddSaturate(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.AddSaturate(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.AddSaturate(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.AddSaturate(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) =>
- {
- int value = x + y;
- value = Math.Max(value, short.MinValue);
- value = Math.Min(value, short.MaxValue);
- a = (short) value;
- return a == z;
- };
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x & y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) =>
- {
- int value = x + y;
- value = Math.Max(value, 0);
- value = Math.Min(value, ushort.MaxValue);
- a = (ushort) value;
- return a == z;
- };
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x & y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) =>
- {
- int value = x + y;
- value = Math.Max(value, sbyte.MinValue);
- value = Math.Min(value, sbyte.MaxValue);
- a = (sbyte) value;
- return a == z;
- };
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x & y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) =>
- {
- int value = x + y;
- value = Math.Max(value, 0);
- value = Math.Min(value, byte.MaxValue);
- a = (byte) value;
- return a == z;
- };
-
- if (!byteTable.CheckResult(checkByte))
- {
- PrintError(byteTable, methodUnderTestName, "(byte x, byte y, byte z, ref byte a) => (a = (byte)(x & y)) == z", checkByte);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_r.csproj
deleted file mode 100644
index 8e2410930e..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{B09B2F36-803A-4435-BCFA-0E83F963840F}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AddSaturate.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/AddSaturate_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_ro.csproj
deleted file mode 100644
index 3c1dd7ee81..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{28A6B11C-68B9-45AF-A42C-C5886AAF6748}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AddSaturate.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/AddScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs
new file mode 100644
index 0000000000..67d07d1c1a
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs
@@ -0,0 +1,330 @@
+// 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 AddScalarDouble()
+ {
+ var test = new SimpleBinaryOpTest__AddScalarDouble();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AddScalarDouble
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = VectorSize / 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__AddScalarDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AddScalarDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.AddScalar(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.AddScalar(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.AddScalar(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.AddScalar(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AddScalarDouble();
+ var result = Sse2.AddScalar(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.AddScalar(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.AddScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.cs
deleted file mode 100644
index d6fb163f80..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.AddScalar);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableScalarSse2<double, double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.AddScalar(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- a[0] = x[0] + y[0];
- a[1] = x[1];
- return a[0] == z[0] && a[1] == z[1];
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => AddScalar", checkDouble);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_r.csproj
deleted file mode 100644
index ef63cf3411..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{B09B2F36-803A-4435-BCFA-0E83F963840F}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AddScalar.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/AddScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_ro.csproj
deleted file mode 100644
index e45d56a6a4..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{28A6B11C-68B9-45AF-A42C-C5886AAF6748}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AddScalar.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/Average.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs
new file mode 100644
index 0000000000..11327ef082
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs
@@ -0,0 +1,330 @@
+// 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 AverageByte()
+ {
+ var test = new SimpleBinaryOpTest__AverageByte();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AverageByte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / 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__AverageByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AverageByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Average(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Average(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Average(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Average), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Average), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Average), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Average(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Average(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AverageByte();
+ var result = Sse2.Average(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Average(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if ((byte)((left[0] + right[0] + 1) >> 1) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((byte)((left[i] + right[i] + 1) >> 1) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Average)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs
new file mode 100644
index 0000000000..a6cd504a7b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs
@@ -0,0 +1,330 @@
+// 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 AverageUInt16()
+ {
+ var test = new SimpleBinaryOpTest__AverageUInt16();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__AverageUInt16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / 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__AverageUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__AverageUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.Average(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.Average(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.Average(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Average), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Average), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.Average), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.Average(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Average(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__AverageUInt16();
+ var result = Sse2.Average(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.Average(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if ((ushort)((left[0] + right[0] + 1) >> 1) != result[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ((ushort)((left[i] + right[i] + 1) >> 1) != result[i])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.Average)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.cs
deleted file mode 100644
index 54f0b15f3b..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.cs
+++ /dev/null
@@ -1,69 +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.Average);
-
- if (Sse2.IsSupported)
- {
- using (var ushortTable = TestTableSse2<ushort>.Create(testsCount))
- using (var byteTable = TestTableSse2<byte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- Vector128<ushort> result = Sse2.Average(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- Vector128<byte> result = Sse2.Average(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<ushort> checkUshort = (ushort x, ushort y, ushort z, ref ushort a) =>
- (a = (ushort)((x + y + 1) >> 1)) == z;
-
- if (!ushortTable.CheckResult(checkUshort))
- {
- PrintError(ushortTable, methodUnderTestName, "(x, y, z, ref a) => (a = (x + y + 1) >> 1) == z", checkUshort);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) =>
- (a = (byte)((x + y + 1) >> 1)) == z;
-
- if (!byteTable.CheckResult(checkByte))
- {
- PrintError(byteTable, methodUnderTestName, "(x, y, z, ref a) => (a = (x + y + 1) >> 1) == 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/Average_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average_r.csproj
deleted file mode 100644
index cd2ed88563..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average_r.csproj
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{A1460AF7-173B-46EB-80BC-2CBAB97364AE}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <PropertyGroup>
- <LangVersion>7.1</LangVersion>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Average.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/Average_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average_ro.csproj
deleted file mode 100644
index 875df8d582..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{5D32628E-9C43-4DF7-B5C1-FD596CCCB996}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Average.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/DivideScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs
new file mode 100644
index 0000000000..287b40b627
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs
@@ -0,0 +1,330 @@
+// 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 DivideScalarDouble()
+ {
+ var test = new SimpleBinaryOpTest__DivideScalarDouble();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__DivideScalarDouble
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = VectorSize / 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__DivideScalarDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__DivideScalarDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.DivideScalar(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.DivideScalar(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.DivideScalar(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.DivideScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.DivideScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.DivideScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.DivideScalar(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.DivideScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.DivideScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.DivideScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__DivideScalarDouble();
+ var result = Sse2.DivideScalar(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.DivideScalar(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] / right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.DivideScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.cs
deleted file mode 100644
index b57fd17d51..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- private const int Pass = 100;
- private const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.DivideScalar);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableScalarSse2<double, double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.DivideScalar(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- a[0] = x[0] / y[0];
- a[1] = x[1];
- return a[0] == z[0] && a[1] == z[1];
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x / y) == z", checkDouble);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_r.csproj
deleted file mode 100644
index ef13996c9d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{87A3726E-381D-417E-B498-3C4FFB632544}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="DivideScalar.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/MaxScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs
new file mode 100644
index 0000000000..3030073569
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs
@@ -0,0 +1,330 @@
+// 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 MaxScalarDouble()
+ {
+ var test = new SimpleBinaryOpTest__MaxScalarDouble();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MaxScalarDouble
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = VectorSize / 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__MaxScalarDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MaxScalarDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.MaxScalar(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.MaxScalar(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.MaxScalar(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MaxScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MaxScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MaxScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.MaxScalar(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MaxScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MaxScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MaxScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MaxScalarDouble();
+ var result = Sse2.MaxScalar(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.MaxScalar(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(Math.Max(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.MaxScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.cs
deleted file mode 100644
index 8d11f911e0..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.MaxScalar);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableScalarSse2<double, double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.MaxScalar(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- a[0] = Math.Max(x[0], y[0]);
- a[1] = x[1];
- return a[0] == z[0] && a[1] == z[1];
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x > y ? x : y) == z", checkDouble);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_r.csproj
deleted file mode 100644
index e08d77e813..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{E47ED2C4-6A89-43E3-AD1A-8FEDA7D8FA03}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="MaxScalar.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/MinScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs
new file mode 100644
index 0000000000..f63a9208fa
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs
@@ -0,0 +1,330 @@
+// 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 MinScalarDouble()
+ {
+ var test = new SimpleBinaryOpTest__MinScalarDouble();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MinScalarDouble
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = VectorSize / 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__MinScalarDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MinScalarDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.MinScalar(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.MinScalar(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.MinScalar(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MinScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MinScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MinScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.MinScalar(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MinScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MinScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MinScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MinScalarDouble();
+ var result = Sse2.MinScalar(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.MinScalar(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(Math.Min(left[0], right[0])) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.MinScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.cs
deleted file mode 100644
index 5ae64f3bea..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.MinScalar);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableScalarSse2<double, double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.MinScalar(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- a[0] = Math.Min(x[0], y[0]);
- a[1] = x[1];
- return a[0] == z[0] && a[1] == z[1];
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseOr(x, y)) == z", checkDouble);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_r.csproj
deleted file mode 100644
index 2e1488d8d7..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{78A91B0F-6535-42D7-B64C-948DF295B6BB}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="MinScalar.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/MinScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_ro.csproj
deleted file mode 100644
index 4e8543a8c1..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{C392B2A4-03ED-4A52-8419-C17085646869}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="MinScalar.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/MultiplyScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs
new file mode 100644
index 0000000000..9c8a27c3bd
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs
@@ -0,0 +1,330 @@
+// 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 MultiplyScalarDouble()
+ {
+ var test = new SimpleBinaryOpTest__MultiplyScalarDouble();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__MultiplyScalarDouble
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = VectorSize / 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__MultiplyScalarDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__MultiplyScalarDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.MultiplyScalar(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.MultiplyScalar(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.MultiplyScalar(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.MultiplyScalar(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MultiplyScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__MultiplyScalarDouble();
+ var result = Sse2.MultiplyScalar(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.MultiplyScalar(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] * right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.MultiplyScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.cs
deleted file mode 100644
index e4f2c7b0d2..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- 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.MultiplyScalar);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableScalarSse2<double, double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.MultiplyScalar(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- a[0] = x[0] * y[0];
- a[1] = x[1];
- return a[0] == z[0] && a[1] == z[1];
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = x * y) == z", checkDouble);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_r.csproj
deleted file mode 100644
index affd316bf5..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{750A2506-0993-4BD6-B350-9D1CDF4736A1}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="MultiplyScalar.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/MultiplyScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_ro.csproj
deleted file mode 100644
index 74c040d254..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{9B509A79-A647-4FA8-A057-0D7935EC3A0A}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="MultiplyScalar.cs" />
- <Compile Include="TestTableSse2.cs" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
index cbfd3a9e7d..10782bcced 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Program.Sse2.cs
@@ -21,6 +21,11 @@ namespace JIT.HardwareIntrinsics.X86
["Add.UInt16"] = AddUInt16,
["Add.UInt32"] = AddUInt32,
["Add.UInt64"] = AddUInt64,
+ ["AddSaturate.Byte"] = AddSaturateByte,
+ ["AddSaturate.SByte"] = AddSaturateSByte,
+ ["AddSaturate.Int16"] = AddSaturateInt16,
+ ["AddSaturate.UInt16"] = AddSaturateUInt16,
+ ["AddScalar.Double"] = AddScalarDouble,
["And.Double"] = AndDouble,
["And.Byte"] = AndByte,
["And.Int16"] = AndInt16,
@@ -39,6 +44,8 @@ namespace JIT.HardwareIntrinsics.X86
["AndNot.UInt16"] = AndNotUInt16,
["AndNot.UInt32"] = AndNotUInt32,
["AndNot.UInt64"] = AndNotUInt64,
+ ["Average.Byte"] = AverageByte,
+ ["Average.UInt16"] = AverageUInt16,
["CompareEqual.Double"] = CompareEqualDouble,
["CompareEqual.Byte"] = CompareEqualByte,
["CompareEqual.Int16"] = CompareEqualInt16,
@@ -64,6 +71,7 @@ namespace JIT.HardwareIntrinsics.X86
["CompareOrdered.Double"] = CompareOrderedDouble,
["CompareUnordered.Double"] = CompareUnorderedDouble,
["Divide.Double"] = DivideDouble,
+ ["DivideScalar.Double"] = DivideScalarDouble,
["Extract.Int16.1"] = ExtractInt161,
["Extract.UInt16.1"] = ExtractUInt161,
["Extract.Int16.129"] = ExtractInt16129,
@@ -75,10 +83,13 @@ namespace JIT.HardwareIntrinsics.X86
["Max.Double"] = MaxDouble,
["Max.Byte"] = MaxByte,
["Max.Int16"] = MaxInt16,
+ ["MaxScalar.Double"] = MaxScalarDouble,
["Min.Double"] = MinDouble,
["Min.Byte"] = MinByte,
["Min.Int16"] = MinInt16,
+ ["MinScalar.Double"] = MinScalarDouble,
["Multiply.Double"] = MultiplyDouble,
+ ["MultiplyScalar.Double"] = MultiplyScalarDouble,
["Or.Double"] = OrDouble,
["Or.Byte"] = OrByte,
["Or.Int16"] = OrInt16,
@@ -88,6 +99,15 @@ namespace JIT.HardwareIntrinsics.X86
["Or.UInt16"] = OrUInt16,
["Or.UInt32"] = OrUInt32,
["Or.UInt64"] = OrUInt64,
+ ["SetAllVector128.Byte"] = SetAllVector128Byte,
+ ["SetAllVector128.SByte"] = SetAllVector128SByte,
+ ["SetAllVector128.Int16"] = SetAllVector128Int16,
+ ["SetAllVector128.UInt16"] = SetAllVector128UInt16,
+ ["SetAllVector128.Int32"] = SetAllVector128Int32,
+ ["SetAllVector128.UInt32"] = SetAllVector128UInt32,
+ ["SetAllVector128.Int64"] = SetAllVector128Int64,
+ ["SetAllVector128.UInt64"] = SetAllVector128UInt64,
+ ["SetAllVector128.Double"] = SetAllVector128Double,
["ShiftLeftLogical.Int16.1"] = ShiftLeftLogicalInt161,
["ShiftLeftLogical.UInt16.1"] = ShiftLeftLogicalUInt161,
["ShiftLeftLogical.Int32.1"] = ShiftLeftLogicalInt321,
@@ -141,6 +161,11 @@ namespace JIT.HardwareIntrinsics.X86
["Subtract.UInt16"] = SubtractUInt16,
["Subtract.UInt32"] = SubtractUInt32,
["Subtract.UInt64"] = SubtractUInt64,
+ ["SubtractSaturate.Byte"] = SubtractSaturateByte,
+ ["SubtractSaturate.SByte"] = SubtractSaturateSByte,
+ ["SubtractSaturate.Int16"] = SubtractSaturateInt16,
+ ["SubtractSaturate.UInt16"] = SubtractSaturateUInt16,
+ ["SubtractScalar.Double"] = SubtractScalarDouble,
["Xor.Double"] = XorDouble,
["Xor.Byte"] = XorByte,
["Xor.Int16"] = XorInt16,
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Byte.cs
new file mode 100644
index 0000000000..a5a197e3fa
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Byte.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128Byte()
+ {
+ bool skipIf32Bit = typeof(Byte) == typeof(Int64) ? true :
+ typeof(Byte) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Byte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128Byte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(Byte);
+
+ private static Byte[] _data = new Byte[Op1ElementCount];
+
+ private static Byte _clsVar;
+
+ private Byte _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128Byte()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (byte)(random.Next(byte.MinValue, byte.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Marshal.SizeOf<Byte>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128Byte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (byte)(random.Next(byte.MinValue, byte.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Marshal.SizeOf<Byte>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (byte)(random.Next(byte.MinValue, byte.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<Byte>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Byte) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<Byte>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Byte) });
+ Byte parameter = (Byte) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Byte>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Byte();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Byte firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<Byte>(Vector128<Byte>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Double.cs
new file mode 100644
index 0000000000..323c057290
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Double.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128Double()
+ {
+ bool skipIf32Bit = typeof(Double) == typeof(Int64) ? true :
+ typeof(Double) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Double();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128Double
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(Double);
+
+ private static Double[] _data = new Double[Op1ElementCount];
+
+ private static Double _clsVar;
+
+ private Double _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<Double, Double> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128Double()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = random.NextDouble();
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Marshal.SizeOf<Double>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128Double()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = random.NextDouble();
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Marshal.SizeOf<Double>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = random.NextDouble();
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<Double>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Double) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<Double>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Double) });
+ Double parameter = (Double) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Double>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Double();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Double firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray = new Double[Op1ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<Double>(Vector128<Double>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int16.cs
new file mode 100644
index 0000000000..a8bbab56f8
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int16.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128Int16()
+ {
+ bool skipIf32Bit = typeof(Int16) == typeof(Int64) ? true :
+ typeof(Int16) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Int16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128Int16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(Int16);
+
+ private static Int16[] _data = new Int16[Op1ElementCount];
+
+ private static Int16 _clsVar;
+
+ private Int16 _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128Int16()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (short)(random.Next(short.MinValue, short.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Marshal.SizeOf<Int16>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128Int16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (short)(random.Next(short.MinValue, short.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Marshal.SizeOf<Int16>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (short)(random.Next(short.MinValue, short.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<Int16>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Int16) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<Int16>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Int16) });
+ Int16 parameter = (Int16) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Int16>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Int16();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Int16 firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<Int16>(Vector128<Int16>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int32.cs
new file mode 100644
index 0000000000..033a4498f2
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int32.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128Int32()
+ {
+ bool skipIf32Bit = typeof(Int32) == typeof(Int64) ? true :
+ typeof(Int32) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Int32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128Int32
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(Int32);
+
+ private static Int32[] _data = new Int32[Op1ElementCount];
+
+ private static Int32 _clsVar;
+
+ private Int32 _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128Int32()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (int)(random.Next(int.MinValue, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Marshal.SizeOf<Int32>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128Int32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (int)(random.Next(int.MinValue, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Marshal.SizeOf<Int32>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (int)(random.Next(int.MinValue, int.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<Int32>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Int32) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<Int32>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Int32) });
+ Int32 parameter = (Int32) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Int32>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Int32();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Int32 firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] outArray = new Int32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<Int32>(Vector128<Int32>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int64.cs
new file mode 100644
index 0000000000..297ed3d220
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.Int64.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128Int64()
+ {
+ bool skipIf32Bit = typeof(Int64) == typeof(Int64) ? true :
+ typeof(Int64) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Int64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128Int64
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(Int64);
+
+ private static Int64[] _data = new Int64[Op1ElementCount];
+
+ private static Int64 _clsVar;
+
+ private Int64 _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128Int64()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (long)(random.Next(int.MinValue, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Marshal.SizeOf<Int64>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128Int64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (long)(random.Next(int.MinValue, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Marshal.SizeOf<Int64>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (long)(random.Next(int.MinValue, int.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<Int64>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Int64) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<Int64>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(Int64) });
+ Int64 parameter = (Int64) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<Int64>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128Int64();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Int64 firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] outArray = new Int64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<Int64>(Vector128<Int64>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.SByte.cs
new file mode 100644
index 0000000000..a5a0f5d188
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.SByte.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128SByte()
+ {
+ bool skipIf32Bit = typeof(SByte) == typeof(Int64) ? true :
+ typeof(SByte) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128SByte();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128SByte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(SByte);
+
+ private static SByte[] _data = new SByte[Op1ElementCount];
+
+ private static SByte _clsVar;
+
+ private SByte _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128SByte()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Marshal.SizeOf<SByte>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128SByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Marshal.SizeOf<SByte>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<SByte>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(SByte) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<SByte>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(SByte) });
+ SByte parameter = (SByte) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<SByte>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128SByte();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(SByte firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<SByte>(Vector128<SByte>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt16.cs
new file mode 100644
index 0000000000..7db4dcc036
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt16.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128UInt16()
+ {
+ bool skipIf32Bit = typeof(UInt16) == typeof(Int64) ? true :
+ typeof(UInt16) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128UInt16();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128UInt16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(UInt16);
+
+ private static UInt16[] _data = new UInt16[Op1ElementCount];
+
+ private static UInt16 _clsVar;
+
+ private UInt16 _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128UInt16()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (ushort)(random.Next(ushort.MinValue, ushort.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Marshal.SizeOf<UInt16>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128UInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (ushort)(random.Next(ushort.MinValue, ushort.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Marshal.SizeOf<UInt16>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (ushort)(random.Next(ushort.MinValue, ushort.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<UInt16>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(UInt16) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<UInt16>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(UInt16) });
+ UInt16 parameter = (UInt16) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<UInt16>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128UInt16();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(UInt16 firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<UInt16>(Vector128<UInt16>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt32.cs
new file mode 100644
index 0000000000..4bc9879439
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt32.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128UInt32()
+ {
+ bool skipIf32Bit = typeof(UInt32) == typeof(Int64) ? true :
+ typeof(UInt32) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128UInt32();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128UInt32
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(UInt32);
+
+ private static UInt32[] _data = new UInt32[Op1ElementCount];
+
+ private static UInt32 _clsVar;
+
+ private UInt32 _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128UInt32()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (uint)(random.Next(0, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Marshal.SizeOf<UInt32>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128UInt32()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (uint)(random.Next(0, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Marshal.SizeOf<UInt32>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (uint)(random.Next(0, int.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<UInt32>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(UInt32) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<UInt32>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(UInt32) });
+ UInt32 parameter = (UInt32) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<UInt32>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128UInt32();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(UInt32 firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] outArray = new UInt32[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<UInt32>(Vector128<UInt32>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt64.cs
new file mode 100644
index 0000000000..5a4dbd3b50
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.UInt64.cs
@@ -0,0 +1,253 @@
+// 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 SetAllVector128UInt64()
+ {
+ bool skipIf32Bit = typeof(UInt64) == typeof(Int64) ? true :
+ typeof(UInt64) == typeof(UInt64) ? true : false;
+
+ if (skipIf32Bit && !Environment.Is64BitProcess)
+ {
+ return;
+ }
+
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128UInt64();
+
+ if (test.IsSupported)
+ {
+ // Validates basic functionality works, using Unsafe.Read
+ test.RunBasicScenario_UnsafeRead();
+
+ // Validates calling via reflection works, using Unsafe.Read
+ test.RunReflectionScenario_UnsafeRead();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates calling via reflection works, using Load
+ test.RunReflectionScenario();
+ }
+
+ // Validates passing a static member works
+ test.RunClsVarScenario();
+
+ // Validates passing a local works, using Unsafe.Read
+ test.RunLclVarScenario_UnsafeRead();
+
+ // Validates passing the field of a local works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleScalarUnaryOpTest__SetAllVector128UInt64
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = 2;
+ private const int RetElementCount = VectorSize / sizeof(UInt64);
+
+ private static UInt64[] _data = new UInt64[Op1ElementCount];
+
+ private static UInt64 _clsVar;
+
+ private UInt64 _fld;
+
+ private SimpleScalarUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+
+ static SimpleScalarUnaryOpTest__SetAllVector128UInt64()
+ {
+ var random = new Random();
+
+ for (int i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (ulong)(random.Next(0, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Marshal.SizeOf<UInt64>());
+ }
+
+ public SimpleScalarUnaryOpTest__SetAllVector128UInt64()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (ulong)(random.Next(0, int.MaxValue));
+ }
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Marshal.SizeOf<UInt64>());
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ _data[i] = (ulong)(random.Next(0, int.MaxValue));
+ }
+
+ _dataTable = new SimpleScalarUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SetAllVector128(
+ Unsafe.Read<UInt64>(_dataTable.inArrayPtr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(UInt64) });
+ var result = method.Invoke(null, new object[] { Unsafe.Read<UInt64>(_dataTable.inArrayPtr)});
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario()
+ {
+ var method = typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), new Type[] { typeof(UInt64) });
+ UInt64 parameter = (UInt64) _dataTable.inArray[0];
+ var result = method.Invoke(null, new object[] { parameter });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
+ ValidateResult(parameter, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SetAllVector128(
+ _clsVar
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var firstOp = Unsafe.Read<UInt64>(_dataTable.inArrayPtr);
+ var result = Sse2.SetAllVector128(firstOp);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(firstOp, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleScalarUnaryOpTest__SetAllVector128UInt64();
+ var result = Sse2.SetAllVector128(test._fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SetAllVector128(_fld);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(UInt64 firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray[0]), firstOp);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ {
+ UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] outArray = new UInt64[RetElementCount];
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray, outArray, method);
+ }
+
+ private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
+ {
+ if (result[0] != firstOp[0])
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (result[i] != firstOp[0])
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)}<UInt64>(Vector128<UInt64>): {method} failed:");
+ Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs
deleted file mode 100644
index d379720ddf..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128.cs
+++ /dev/null
@@ -1,301 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- private const int Pass = 100;
- private const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.SetAllVector128);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableSse2<double>.Create(testsCount))
- using (var longTable = TestTableSse2<long>.Create(testsCount))
- using (var ulongTable = TestTableSse2<ulong>.Create(testsCount))
- using (var intTable = TestTableSse2<int>.Create(testsCount))
- using (var uintTable = TestTableSse2<uint>.Create(testsCount))
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var ushortTable = TestTableSse2<ushort>.Create(testsCount))
- using (var sbyteTable = TestTableSse2<sbyte>.Create(testsCount))
- using (var byteTable = TestTableSse2<byte>.Create(testsCount))
- {
- for (double i = 0; i < testsCount; i += 1)
- {
- Vector128<double> result = Sse2.SetAllVector128(i);
- doubleTable.SetOutArray(result, (int)i);
- }
-
- if (Environment.Is64BitProcess)
- {
- for (long i = 0; i < testsCount; i++)
- {
- Vector128<long> result = Sse2.SetAllVector128(i);
- longTable.SetOutArray(result, (int)i);
- }
-
- for (ulong i = 0; i < (ulong)testsCount; i++)
- {
- Vector128<ulong> result = Sse2.SetAllVector128(i);
- ulongTable.SetOutArray(result, (int)i);
- }
- }
- else
- {
- try
- {
- var vd = Sse2.SetAllVector128((long)0xffffl);
- testResult = Fail;
- Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)} failed for long: expected PlatformNotSupportedException exception.");
- }
- catch (PlatformNotSupportedException)
- {
-
- }
-
- try
- {
- var vd = Sse2.SetAllVector128((ulong)0xfffful);
- testResult = Fail;
- Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SetAllVector128)} failed for ulong: expected PlatformNotSupportedException exception.");
- }
- catch (PlatformNotSupportedException)
- {
-
- }
- }
-
-
-
- for (int i = 0; i < testsCount; i++)
- {
- Vector128<int> result = Sse2.SetAllVector128((int)i);
- intTable.SetOutArray(result, i);
- }
-
- for (uint i = 0; i < testsCount; i++)
- {
- Vector128<uint> result = Sse2.SetAllVector128(i);
- uintTable.SetOutArray(result, (int)i);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- Vector128<short> result = Sse2.SetAllVector128((short)i);
- shortTable.SetOutArray(result, i);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- Vector128<ushort> result = Sse2.SetAllVector128((ushort)i);
- ushortTable.SetOutArray(result, i);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- Vector128<sbyte> result = Sse2.SetAllVector128((sbyte)i);
- sbyteTable.SetOutArray(result, i);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- Vector128<byte> result = Sse2.SetAllVector128((byte)i);
- byteTable.SetOutArray(result, i);
- }
-
- double doubleCounter = 0.0;
- CheckMethodSpan<double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != doubleCounter)
- result = false;
- }
- doubleCounter += 1;
- return result;
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(double x, double y, double z, ref double a) => (a = BitwiseXor(x, y)) == z", checkDouble);
- testResult = Fail;
- }
-
- if (Environment.Is64BitProcess)
- {
- long longCounter = 0;
- CheckMethodSpan<long> checkInt64 = (Span<long> x, Span<long> y, Span<long> z, Span<long> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != longCounter)
- result = false;
- }
- longCounter++;
- return result;
- };
-
- if (!longTable.CheckResult(checkInt64))
- {
- PrintError(longTable, methodUnderTestName, "(long x, long y, long z, ref long a) => (a = x ^ y) == z", checkInt64);
- testResult = Fail;
- }
-
- ulong ulongCounter = 0;
- CheckMethodSpan<ulong> checkUInt64 = (Span<ulong> x, Span<ulong> y, Span<ulong> z, Span<ulong> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != ulongCounter)
- result = false;
- }
- ulongCounter++;
- return result;
- };
-
- if (!ulongTable.CheckResult(checkUInt64))
- {
- PrintError(ulongTable, methodUnderTestName, "(Span<ulong> x, Span<ulong> y, Span<ulong> z, Span<ulong> a) => SetAllVector128", checkUInt64);
- testResult = Fail;
- }
- }
-
- int intCounter = 0;
- CheckMethodSpan<int> checkInt32 = (Span<int> x, Span<int> y, Span<int> z, Span<int> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != intCounter)
- result = false;
- }
- intCounter++;
- return result;
- };
-
- if (!intTable.CheckResult(checkInt32))
- {
- PrintError(intTable, methodUnderTestName, "(int x, int y, int z, ref int a) => (a = x ^ y) == z", checkInt32);
- testResult = Fail;
- }
-
- uint uintCounter = 0;
- CheckMethodSpan<uint> checkUInt32 = (Span<uint> x, Span<uint> y, Span<uint> z, Span<uint> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != uintCounter)
- result = false;
- }
- uintCounter++;
- return result;
- };
-
- if (!uintTable.CheckResult(checkUInt32))
- {
- PrintError(uintTable, methodUnderTestName, "(uint x, uint y, uint z, ref uint a) => (a = x ^ y) == z", checkUInt32);
- testResult = Fail;
- }
-
- int shortCounter = 0;
- CheckMethodSpan<short> checkInt16 = (Span<short> x, Span<short> y, Span<short> z, Span<short> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != shortCounter)
- result = false;
- }
- shortCounter++;
- return result;
- };
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x ^ y)) == z", checkInt16);
- testResult = Fail;
- }
-
- int ushortCounter = 0;
- CheckMethodSpan<ushort> checkUInt16 = (Span<ushort> x, Span<ushort> y, Span<ushort> z, Span<ushort> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != ushortCounter)
- result = false;
- }
- ushortCounter++;
- return result;
- };
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x ^ y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- int sbyteCounter = 0;
- CheckMethodSpan<sbyte> checkSByte = (Span<sbyte> x, Span<sbyte> y, Span<sbyte> z, Span<sbyte> a) =>
- {
- bool result = true;
- for (int i = 0; i < z.Length; i++)
- {
- if (z[i] != sbyteCounter)
- result = false;
- }
- sbyteCounter++;
- return result;
- };
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x ^ y)) == z", checkSByte);
- testResult = Fail;
- }
-
- int byteCounter = 0;
- CheckMethodSpan<byte> checkByte = (Span<byte> x, Span<byte> y, Span<byte> z, Span<byte> a) =>
- {
- bool result = true;
- for (int i = 0; i < x.Length; i++)
- {
- if (z[i] != byteCounter)
- result = false;
- }
- byteCounter++;
- return result;
- };
-
- if (!byteTable.CheckResult(checkByte))
- {
- PrintError(byteTable, methodUnderTestName, "(byte x, byte y, byte z, ref byte a) => (a = (byte)(x ^ y)) == z", checkByte);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj
deleted file mode 100644
index 8ff187b439..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{8156C540-D3A7-4B4A-B513-3C638EC9088A}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="SetAllVector128.cs" />
- <Compile Include="TestTableSse2.cs" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj
deleted file mode 100644
index f63ed35b08..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SetAllVector128_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{4A5D16DC-6AFD-4BCC-929F-08EFDF76298E}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="SetAllVector128.cs" />
- <Compile Include="TestTableSse2.cs" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs
new file mode 100644
index 0000000000..45459771f7
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2Verify.cs
@@ -0,0 +1,81 @@
+// 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.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Runtime.Intrinsics;
+
+namespace JIT.HardwareIntrinsics.X86
+{
+
+ public static class Sse2Verify
+ {
+ public static bool AddSaturate(byte x, byte y, byte z)
+ {
+ int value = x + y;
+ value = Math.Max(value, 0);
+ value = Math.Min(value, byte.MaxValue);
+ return value != z;
+ }
+
+ public static bool AddSaturate(sbyte x, sbyte y, sbyte z)
+ {
+ int value = x + y;
+ value = Math.Max(value, sbyte.MinValue);
+ value = Math.Min(value, sbyte.MaxValue);
+ return value != z;
+ }
+
+ public static bool AddSaturate(ushort x, ushort y, ushort z)
+ {
+ int value = x + y;
+ value = Math.Max(value, 0);
+ value = Math.Min(value, ushort.MaxValue);
+ return value != z;
+ }
+
+ public static bool AddSaturate(short x, short y, short z)
+ {
+ int value = x + y;
+ value = Math.Max(value, short.MinValue);
+ value = Math.Min(value, short.MaxValue);
+ return value != z;
+ }
+
+ public static bool SubtractSaturate(byte x, byte y, byte z)
+ {
+ int value = (int)x - y;
+ value = Math.Max(value, 0);
+ value = Math.Min(value, byte.MaxValue);
+ return (byte) value != z;
+ }
+
+ public static bool SubtractSaturate(sbyte x, sbyte y, sbyte z)
+ {
+ int value = (int)x - y;
+ value = Math.Max(value, sbyte.MinValue);
+ value = Math.Min(value, sbyte.MaxValue);
+ return (sbyte) value != z;
+ }
+
+ public static bool SubtractSaturate(ushort x, ushort y, ushort z)
+ {
+ int value = (int)x - y;
+ value = Math.Max(value, 0);
+ value = Math.Min(value, ushort.MaxValue);
+ return (ushort) value != z;
+ }
+
+ public static bool SubtractSaturate(short x, short y, short z)
+ {
+ int value = (int)x - y;
+ value = Math.Max(value, short.MinValue);
+ value = Math.Min(value, short.MaxValue);
+ return (short) value != z;
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
index 22b99ef26f..fec034cb51 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
@@ -36,6 +36,11 @@
<Compile Include="Add.UInt16.cs" />
<Compile Include="Add.UInt32.cs" />
<Compile Include="Add.UInt64.cs" />
+ <Compile Include="AddSaturate.Byte.cs"/>
+ <Compile Include="AddSaturate.SByte.cs"/>
+ <Compile Include="AddSaturate.Int16.cs"/>
+ <Compile Include="AddSaturate.UInt16.cs"/>
+ <Compile Include="AddScalar.Double.cs"/>
<Compile Include="And.Double.cs" />
<Compile Include="And.Byte.cs" />
<Compile Include="And.Int16.cs" />
@@ -54,6 +59,8 @@
<Compile Include="AndNot.UInt16.cs" />
<Compile Include="AndNot.UInt32.cs" />
<Compile Include="AndNot.UInt64.cs" />
+ <Compile Include="Average.Byte.cs"/>
+ <Compile Include="Average.UInt16.cs"/>
<Compile Include="CompareEqual.Double.cs" />
<Compile Include="CompareEqual.Byte.cs" />
<Compile Include="CompareEqual.Int16.cs" />
@@ -79,6 +86,7 @@
<Compile Include="CompareOrdered.Double.cs" />
<Compile Include="CompareUnordered.Double.cs" />
<Compile Include="Divide.Double.cs" />
+ <Compile Include="DivideScalar.Double.cs" />
<Compile Include="Extract.Int16.1.cs" />
<Compile Include="Extract.UInt16.1.cs" />
<Compile Include="Extract.Int16.129.cs" />
@@ -90,10 +98,13 @@
<Compile Include="Max.Double.cs" />
<Compile Include="Max.Byte.cs" />
<Compile Include="Max.Int16.cs" />
+ <Compile Include="MaxScalar.Double.cs" />
<Compile Include="Min.Double.cs" />
<Compile Include="Min.Byte.cs" />
<Compile Include="Min.Int16.cs" />
+ <Compile Include="MinScalar.Double.cs" />
<Compile Include="Multiply.Double.cs" />
+ <Compile Include="MultiplyScalar.Double.cs" />
<Compile Include="Or.Double.cs" />
<Compile Include="Or.Byte.cs" />
<Compile Include="Or.Int16.cs" />
@@ -103,6 +114,15 @@
<Compile Include="Or.UInt16.cs" />
<Compile Include="Or.UInt32.cs" />
<Compile Include="Or.UInt64.cs" />
+ <Compile Include="SetAllVector128.Byte.cs" />
+ <Compile Include="SetAllVector128.SByte.cs" />
+ <Compile Include="SetAllVector128.Int16.cs" />
+ <Compile Include="SetAllVector128.UInt16.cs" />
+ <Compile Include="SetAllVector128.Int32.cs" />
+ <Compile Include="SetAllVector128.UInt32.cs" />
+ <Compile Include="SetAllVector128.Int64.cs" />
+ <Compile Include="SetAllVector128.UInt64.cs" />
+ <Compile Include="SetAllVector128.Double.cs" />
<Compile Include="ShiftLeftLogical.Int16.1.cs" />
<Compile Include="ShiftLeftLogical.UInt16.1.cs" />
<Compile Include="ShiftLeftLogical.Int32.1.cs" />
@@ -156,6 +176,11 @@
<Compile Include="Subtract.UInt16.cs" />
<Compile Include="Subtract.UInt32.cs" />
<Compile Include="Subtract.UInt64.cs" />
+ <Compile Include="SubtractSaturate.Byte.cs"/>
+ <Compile Include="SubtractSaturate.SByte.cs"/>
+ <Compile Include="SubtractSaturate.Int16.cs"/>
+ <Compile Include="SubtractSaturate.UInt16.cs"/>
+ <Compile Include="SubtractScalar.Double.cs" />
<Compile Include="Xor.Double.cs" />
<Compile Include="Xor.Byte.cs" />
<Compile Include="Xor.Int16.cs" />
@@ -169,6 +194,8 @@
<Compile Include="..\Shared\Program.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\ScalarUnOpTest_DataTable.cs" />
+ <Compile Include="Sse2Verify.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
index 6d96ca6eef..8c82568c0c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
@@ -36,6 +36,11 @@
<Compile Include="Add.UInt16.cs" />
<Compile Include="Add.UInt32.cs" />
<Compile Include="Add.UInt64.cs" />
+ <Compile Include="AddSaturate.Byte.cs"/>
+ <Compile Include="AddSaturate.SByte.cs"/>
+ <Compile Include="AddSaturate.Int16.cs"/>
+ <Compile Include="AddSaturate.UInt16.cs"/>
+ <Compile Include="AddScalar.Double.cs"/>
<Compile Include="And.Double.cs" />
<Compile Include="And.Byte.cs" />
<Compile Include="And.Int16.cs" />
@@ -54,6 +59,8 @@
<Compile Include="AndNot.UInt16.cs" />
<Compile Include="AndNot.UInt32.cs" />
<Compile Include="AndNot.UInt64.cs" />
+ <Compile Include="Average.Byte.cs"/>
+ <Compile Include="Average.UInt16.cs"/>
<Compile Include="CompareEqual.Double.cs" />
<Compile Include="CompareEqual.Byte.cs" />
<Compile Include="CompareEqual.Int16.cs" />
@@ -79,6 +86,7 @@
<Compile Include="CompareOrdered.Double.cs" />
<Compile Include="CompareUnordered.Double.cs" />
<Compile Include="Divide.Double.cs" />
+ <Compile Include="DivideScalar.Double.cs" />
<Compile Include="Extract.Int16.1.cs" />
<Compile Include="Extract.UInt16.1.cs" />
<Compile Include="Extract.Int16.129.cs" />
@@ -90,10 +98,13 @@
<Compile Include="Max.Double.cs" />
<Compile Include="Max.Byte.cs" />
<Compile Include="Max.Int16.cs" />
+ <Compile Include="MaxScalar.Double.cs" />
<Compile Include="Min.Double.cs" />
<Compile Include="Min.Byte.cs" />
<Compile Include="Min.Int16.cs" />
+ <Compile Include="MinScalar.Double.cs" />
<Compile Include="Multiply.Double.cs" />
+ <Compile Include="MultiplyScalar.Double.cs" />
<Compile Include="Or.Double.cs" />
<Compile Include="Or.Byte.cs" />
<Compile Include="Or.Int16.cs" />
@@ -103,6 +114,15 @@
<Compile Include="Or.UInt16.cs" />
<Compile Include="Or.UInt32.cs" />
<Compile Include="Or.UInt64.cs" />
+ <Compile Include="SetAllVector128.Byte.cs" />
+ <Compile Include="SetAllVector128.SByte.cs" />
+ <Compile Include="SetAllVector128.Int16.cs" />
+ <Compile Include="SetAllVector128.UInt16.cs" />
+ <Compile Include="SetAllVector128.Int32.cs" />
+ <Compile Include="SetAllVector128.UInt32.cs" />
+ <Compile Include="SetAllVector128.Int64.cs" />
+ <Compile Include="SetAllVector128.UInt64.cs" />
+ <Compile Include="SetAllVector128.Double.cs" />
<Compile Include="ShiftLeftLogical.Int16.1.cs" />
<Compile Include="ShiftLeftLogical.UInt16.1.cs" />
<Compile Include="ShiftLeftLogical.Int32.1.cs" />
@@ -156,6 +176,11 @@
<Compile Include="Subtract.UInt16.cs" />
<Compile Include="Subtract.UInt32.cs" />
<Compile Include="Subtract.UInt64.cs" />
+ <Compile Include="SubtractSaturate.Byte.cs"/>
+ <Compile Include="SubtractSaturate.SByte.cs"/>
+ <Compile Include="SubtractSaturate.Int16.cs"/>
+ <Compile Include="SubtractSaturate.UInt16.cs"/>
+ <Compile Include="SubtractScalar.Double.cs" />
<Compile Include="Xor.Double.cs" />
<Compile Include="Xor.Byte.cs" />
<Compile Include="Xor.Int16.cs" />
@@ -169,6 +194,8 @@
<Compile Include="..\Shared\Program.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\ScalarUnOpTest_DataTable.cs" />
+ <Compile Include="Sse2Verify.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs
new file mode 100644
index 0000000000..be63a5ff6b
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs
@@ -0,0 +1,330 @@
+// 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 SubtractSaturateByte()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateByte();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateByte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Byte);
+ private const int Op2ElementCount = VectorSize / sizeof(Byte);
+ private const int RetElementCount = VectorSize / 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__SubtractSaturateByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractSaturateByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (byte)(random.Next(0, byte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SubtractSaturate(
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SubtractSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateByte();
+ var result = Sse2.SubtractSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SubtractSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[Op1ElementCount];
+ Byte[] inArray2 = new Byte[Op2ElementCount];
+ Byte[] outArray = new Byte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Byte[] inArray1 = new Byte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.SubtractSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.SubtractSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SubtractSaturate)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs
new file mode 100644
index 0000000000..6429111d9c
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs
@@ -0,0 +1,330 @@
+// 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 SubtractSaturateInt16()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateInt16();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateInt16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Int16);
+ private const int Op2ElementCount = VectorSize / sizeof(Int16);
+ private const int RetElementCount = VectorSize / 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__SubtractSaturateInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractSaturateInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (short)(random.Next(short.MinValue, short.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SubtractSaturate(
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SubtractSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateInt16();
+ var result = Sse2.SubtractSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SubtractSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[Op1ElementCount];
+ Int16[] inArray2 = new Int16[Op2ElementCount];
+ Int16[] outArray = new Int16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Int16[] inArray1 = new Int16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Int16[] left, Int16[] right, Int16[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.SubtractSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.SubtractSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SubtractSaturate)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs
new file mode 100644
index 0000000000..857f930dfa
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs
@@ -0,0 +1,330 @@
+// 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 SubtractSaturateSByte()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateSByte();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateSByte
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(SByte);
+ private const int Op2ElementCount = VectorSize / sizeof(SByte);
+ private const int RetElementCount = VectorSize / 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__SubtractSaturateSByte()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractSaturateSByte()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (sbyte)(random.Next(sbyte.MinValue, sbyte.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SubtractSaturate(
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SubtractSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateSByte();
+ var result = Sse2.SubtractSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SubtractSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[Op1ElementCount];
+ SByte[] inArray2 = new SByte[Op2ElementCount];
+ SByte[] outArray = new SByte[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ SByte[] inArray1 = new SByte[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.SubtractSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.SubtractSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SubtractSaturate)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs
new file mode 100644
index 0000000000..7f21b4b8f3
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs
@@ -0,0 +1,330 @@
+// 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 SubtractSaturateUInt16()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateUInt16();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateUInt16
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(UInt16);
+ private const int Op2ElementCount = VectorSize / sizeof(UInt16);
+ private const int RetElementCount = VectorSize / 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__SubtractSaturateUInt16()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractSaturateUInt16()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (ushort)(random.Next(ushort.MinValue,ushort.MaxValue)); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SubtractSaturate(
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.SubtractSaturate(
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractSaturate), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SubtractSaturate(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractSaturateUInt16();
+ var result = Sse2.SubtractSaturate(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SubtractSaturate(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
+ UInt16[] inArray2 = new UInt16[Op2ElementCount];
+ UInt16[] outArray = new UInt16[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ UInt16[] inArray1 = new UInt16[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(UInt16[] left, UInt16[] right, UInt16[] result, [CallerMemberName] string method = "")
+ {
+ if (Sse2Verify.SubtractSaturate(left[0], right[0], result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (Sse2Verify.SubtractSaturate(left[i], right[i], result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SubtractSaturate)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.cs
deleted file mode 100644
index b1c5b5c89b..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.cs
+++ /dev/null
@@ -1,127 +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.SubtractSaturate);
-
- if (Sse2.IsSupported)
- {
- using (var shortTable = TestTableSse2<short>.Create(testsCount))
- using (var ushortTable = TestTableSse2<ushort>.Create(testsCount))
- using (var sbyteTable = TestTableSse2<sbyte>.Create(testsCount))
- using (var byteTable = TestTableSse2<byte>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<short>, Vector128<short>, Vector128<short>) value = shortTable[i];
- var result = Sse2.SubtractSaturate(value.Item1, value.Item2);
- shortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<ushort>, Vector128<ushort>, Vector128<ushort>) value = ushortTable[i];
- var result = Sse2.SubtractSaturate(value.Item1, value.Item2);
- ushortTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<sbyte>, Vector128<sbyte>, Vector128<sbyte>) value = sbyteTable[i];
- var result = Sse2.SubtractSaturate(value.Item1, value.Item2);
- sbyteTable.SetOutArray(result);
- }
-
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<byte>, Vector128<byte>, Vector128<byte>) value = byteTable[i];
- var result = Sse2.SubtractSaturate(value.Item1, value.Item2);
- byteTable.SetOutArray(result);
- }
-
- CheckMethod<short> checkInt16 = (short x, short y, short z, ref short a) =>
- {
- int value = (int)x - y;
- value = Math.Max(value, short.MinValue);
- value = Math.Min(value, short.MaxValue);
- a = (short) value;
- return a == z;
- };
-
- if (!shortTable.CheckResult(checkInt16))
- {
- PrintError(shortTable, methodUnderTestName, "(short x, short y, short z, ref short a) => (a = (short)(x - y)) == z", checkInt16);
- testResult = Fail;
- }
-
- CheckMethod<ushort> checkUInt16 = (ushort x, ushort y, ushort z, ref ushort a) =>
- {
- int value = (int)x - y;
- value = Math.Max(value, 0);
- value = Math.Min(value, ushort.MaxValue);
- a = (ushort) value;
- return a == z;
- };
-
- if (!ushortTable.CheckResult(checkUInt16))
- {
- PrintError(ushortTable, methodUnderTestName, "(ushort x, ushort y, ushort z, ref ushort a) => (a = (ushort)(x & y)) == z", checkUInt16);
- testResult = Fail;
- }
-
- CheckMethod<sbyte> checkSByte = (sbyte x, sbyte y, sbyte z, ref sbyte a) =>
- {
- int value = (int)x - y;
- value = Math.Max(value, sbyte.MinValue);
- value = Math.Min(value, sbyte.MaxValue);
- a = (sbyte) value;
- return a == z;
- };
-
- if (!sbyteTable.CheckResult(checkSByte))
- {
- PrintError(sbyteTable, methodUnderTestName, "(sbyte x, sbyte y, sbyte z, ref sbyte a) => (a = (sbyte)(x & y)) == z", checkSByte);
- testResult = Fail;
- }
-
- CheckMethod<byte> checkByte = (byte x, byte y, byte z, ref byte a) =>
- {
- int value = (int)x - y;
- value = Math.Max(value, 0);
- value = Math.Min(value, byte.MaxValue);
- a = (byte) value;
- return a == z;
- };
-
- if (!byteTable.CheckResult(checkByte))
- {
- PrintError(byteTable, methodUnderTestName, "(byte x, byte y, byte z, ref byte a) => (a = (byte)(x & y)) == z", checkByte);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_r.csproj
deleted file mode 100644
index 3bcd3d3af2..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{03A382F5-1AC9-419C-8EA8-0387D5D50815}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="SubtractSaturate.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/SubtractSaturate_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_ro.csproj
deleted file mode 100644
index 7b21f7f7c0..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{E6D16C91-1AE1-455C-947B-A16955D90984}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="SubtractSaturate.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/SubtractScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs
new file mode 100644
index 0000000000..53953811af
--- /dev/null
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs
@@ -0,0 +1,330 @@
+// 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 SubtractScalarDouble()
+ {
+ var test = new SimpleBinaryOpTest__SubtractScalarDouble();
+
+ 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 works
+ test.RunLclFldScenario();
+
+ // Validates passing an instance member works
+ test.RunFldScenario();
+ }
+ else
+ {
+ // Validates we throw on unsupported hardware
+ test.RunUnsupportedScenario();
+ }
+
+ if (!test.Succeeded)
+ {
+ throw new Exception("One or more scenarios did not complete as expected.");
+ }
+ }
+ }
+
+ public sealed unsafe class SimpleBinaryOpTest__SubtractScalarDouble
+ {
+ private const int VectorSize = 16;
+
+ private const int Op1ElementCount = VectorSize / sizeof(Double);
+ private const int Op2ElementCount = VectorSize / sizeof(Double);
+ private const int RetElementCount = VectorSize / 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__SubtractScalarDouble()
+ {
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+ }
+
+ public SimpleBinaryOpTest__SubtractScalarDouble()
+ {
+ Succeeded = true;
+
+ var random = new Random();
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
+
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); }
+ for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (double)(random.NextDouble()); }
+ _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], VectorSize);
+ }
+
+ public bool IsSupported => Sse2.IsSupported;
+
+ public bool Succeeded { get; set; }
+
+ public void RunBasicScenario_UnsafeRead()
+ {
+ var result = Sse2.SubtractScalar(
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_Load()
+ {
+ var result = Sse2.SubtractScalar(
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunBasicScenario_LoadAligned()
+ {
+ var result = Sse2.SubtractScalar(
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_UnsafeRead()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr),
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr)
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_Load()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunReflectionScenario_LoadAligned()
+ {
+ var result = typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), new Type[] { typeof(Vector128<Double>), typeof(Vector128<Double>) })
+ .Invoke(null, new object[] {
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr)),
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr))
+ });
+
+ Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario()
+ {
+ var result = Sse2.SubtractScalar(
+ _clsVar1,
+ _clsVar2
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_UnsafeRead()
+ {
+ var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_Load()
+ {
+ var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclVarScenario_LoadAligned()
+ {
+ var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractScalar(left, right);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(left, right, _dataTable.outArrayPtr);
+ }
+
+ public void RunLclFldScenario()
+ {
+ var test = new SimpleBinaryOpTest__SubtractScalarDouble();
+ var result = Sse2.SubtractScalar(test._fld1, test._fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunFldScenario()
+ {
+ var result = Sse2.SubtractScalar(_fld1, _fld2);
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+
+ public void RunUnsupportedScenario()
+ {
+ Succeeded = false;
+
+ try
+ {
+ RunBasicScenario_UnsafeRead();
+ }
+ catch (PlatformNotSupportedException)
+ {
+ Succeeded = true;
+ }
+ }
+
+ private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[Op1ElementCount];
+ Double[] inArray2 = new Double[Op2ElementCount];
+ Double[] outArray = new Double[RetElementCount];
+
+ Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
+ Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ {
+ Double[] inArray1 = new Double[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), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), VectorSize);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), VectorSize);
+
+ ValidateResult(inArray1, inArray2, outArray, method);
+ }
+
+ private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
+ {
+ if (BitConverter.DoubleToInt64Bits(left[0] - right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
+ {
+ Succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if (BitConverter.DoubleToInt64Bits(left[i]) != BitConverter.DoubleToInt64Bits(result[i]))
+ {
+ Succeeded = false;
+ break;
+ }
+ }
+ }
+
+ if (!Succeeded)
+ {
+ Console.WriteLine($"{nameof(Sse2)}.{nameof(Sse2.SubtractScalar)}<Double>(Vector128<Double>, Vector128<Double>): {method} failed:");
+ Console.WriteLine($" left: ({string.Join(", ", left)})");
+ Console.WriteLine($" right: ({string.Join(", ", right)})");
+ Console.WriteLine($" result: ({string.Join(", ", result)})");
+ Console.WriteLine();
+ }
+ }
+ }
+}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.cs
deleted file mode 100644
index ee4aabdcd1..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-using System;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace IntelHardwareIntrinsicTest
-{
- internal static partial class Program
- {
- const int Pass = 100;
- const int Fail = 0;
-
- static unsafe int Main(string[] args)
- {
- int testResult = Pass;
- int testsCount = 21;
- string methodUnderTestName = nameof(Sse2.SubtractScalar);
-
- if (Sse2.IsSupported)
- {
- using (var doubleTable = TestTableScalarSse2<double, double>.Create(testsCount))
- {
- for (int i = 0; i < testsCount; i++)
- {
- (Vector128<double>, Vector128<double>) value = doubleTable[i];
- Vector128<double> result = Sse2.SubtractScalar(value.Item1, value.Item2);
- doubleTable.SetOutArray(result);
- }
-
- CheckMethodEight<double, double> checkDouble = (Span<double> x, Span<double> y, Span<double> z, Span<double> a) =>
- {
- a[0] = x[0] - y[0];
- a[1] = x[1];
- return a[0] == z[0] && a[1] == z[1];
- };
-
- if (!doubleTable.CheckResult(checkDouble))
- {
- PrintError(doubleTable, methodUnderTestName, "(Span<double> x, Span<double> y, Span<double> z, Span<double> a) => SubtractScalar", checkDouble);
- testResult = Fail;
- }
- }
- }
- else
- {
- Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
- }
-
- return testResult;
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_r.csproj
deleted file mode 100644
index 589bd513b4..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_r.csproj
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{DDE1DDD6-B6BD-42D2-9D49-5BCE2E707442}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>
- </Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="SubtractScalar.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/SubtractScalar_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_ro.csproj
deleted file mode 100644
index 3037bd7198..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar_ro.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{7B7FCE02-0D75-4BE2-80C0-29F2D410FDF3}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
- <DebugType>None</DebugType>
- <Optimize>True</Optimize>
- </PropertyGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="SubtractScalar.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/performance/Scenario/JitBench/Benchmarks/MusicStoreBenchmark.cs b/tests/src/performance/Scenario/JitBench/Benchmarks/WebAppBenchmarks.cs
index 57740004e6..bcfac7ab22 100644
--- a/tests/src/performance/Scenario/JitBench/Benchmarks/MusicStoreBenchmark.cs
+++ b/tests/src/performance/Scenario/JitBench/Benchmarks/WebAppBenchmarks.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -6,52 +7,75 @@ using Microsoft.Xunit.Performance.Api;
namespace JitBench
{
- class MusicStoreBenchmark : Benchmark
+ class MusicStoreBenchmark : WebAppBenchmark
{
- public MusicStoreBenchmark() : base("MusicStore")
+ public MusicStoreBenchmark() : base("MusicStore") { }
+
+ protected override string ExecutableName => "MusicStore.dll";
+
+ protected override string GetWebAppSrcDirectory(string outputDir)
+ {
+ return Path.Combine(GetJitBenchRepoRootDir(outputDir), "src", "MusicStore");
+ }
+ }
+
+ class AllReadyBenchmark : WebAppBenchmark
+ {
+ public AllReadyBenchmark() : base("AllReady") { }
+
+ protected override string ExecutableName => "AllReady.dll";
+
+ protected override string GetWebAppSrcDirectory(string outputDir)
+ {
+ return Path.Combine(GetJitBenchRepoRootDir(outputDir), "src", "AllReady");
+ }
+ }
+
+ abstract class WebAppBenchmark : Benchmark
+ {
+ private static readonly HashSet<int> DefaultExitCodes = new HashSet<int>(new[] { 0 });
+
+ public WebAppBenchmark(string name) : base(name)
{
+ ExePath = ExecutableName;
}
+ protected abstract string ExecutableName { get; }
+
public override async Task Setup(DotNetInstallation dotNetInstall, string outputDir, bool useExistingSetup, ITestOutputHelper output)
{
if(!useExistingSetup)
{
using (var setupSection = new IndentedTestOutputHelper("Setup " + Name, output))
{
- await DownloadAndExtractJitBenchRepo(outputDir, setupSection);
+ await CloneAspNetJitBenchRepo(outputDir, setupSection);
await CreateStore(dotNetInstall, outputDir, setupSection);
await Publish(dotNetInstall, outputDir, setupSection);
}
}
- string musicStoreSrcDirectory = GetMusicStoreSrcDirectory(outputDir);
+ string webAppSrcDirectory = GetWebAppSrcDirectory(outputDir);
string tfm = DotNetSetup.GetTargetFrameworkMonikerForFrameworkVersion(dotNetInstall.FrameworkVersion);
- ExePath = "MusicStore.dll";
- WorkingDirPath = GetMusicStorePublishDirectory(dotNetInstall, outputDir, tfm);
- EnvironmentVariables.Add("DOTNET_SHARED_STORE", GetMusicStoreStoreDir(outputDir));
+ WorkingDirPath = GetWebAppPublishDirectory(dotNetInstall, outputDir, tfm);
+ EnvironmentVariables.Add("DOTNET_SHARED_STORE", GetWebAppStoreDir(outputDir));
}
- async Task DownloadAndExtractJitBenchRepo(string outputDir, ITestOutputHelper output)
+ async Task CloneAspNetJitBenchRepo(string outputDir, ITestOutputHelper output)
{
// If the repo already exists, we delete it and extract it again.
string jitBenchRepoRootDir = GetJitBenchRepoRootDir(outputDir);
FileTasks.DeleteDirectory(jitBenchRepoRootDir, output);
- string localJitBenchRepo = GetLocalJitBenchRepoDirectory();
- if (localJitBenchRepo == null)
- {
- var url = $"{JitBenchRepoUrl}/archive/{JitBenchCommitSha1Id}.zip";
- FileTasks.DeleteDirectory(jitBenchRepoRootDir + "_temp", output);
- await FileTasks.DownloadAndUnzip(url, jitBenchRepoRootDir+"_temp", output);
- FileTasks.MoveDirectory(Path.Combine(jitBenchRepoRootDir + "_temp", $"JitBench-{JitBenchCommitSha1Id}"), jitBenchRepoRootDir, output);
- }
- else
- {
- if (!Directory.Exists(localJitBenchRepo))
- {
- throw new Exception("Local JitBench repo " + localJitBenchRepo + " does not exist");
- }
- FileTasks.DirectoryCopy(localJitBenchRepo, jitBenchRepoRootDir, output);
- }
+ await ExecuteGitCommand($"clone {JitBenchRepoUrl} {jitBenchRepoRootDir}", output);
+ await ExecuteGitCommand($"checkout {JitBenchCommitSha1Id}", output, workingDirectory: jitBenchRepoRootDir);
+ await ExecuteGitCommand($"submodule update --init --recursive", output, workingDirectory: jitBenchRepoRootDir);
+ }
+
+ async Task ExecuteGitCommand(string arguments, ITestOutputHelper output, string workingDirectory = null)
+ {
+ int exitCode = await new ProcessRunner("git", arguments).WithLog(output).WithWorkingDirectory(workingDirectory).Run();
+
+ if (!DefaultExitCodes.Contains(exitCode))
+ throw new Exception($"git {arguments} has failed, the exit code was {exitCode}");
}
private static async Task CreateStore(DotNetInstallation dotNetInstall, string outputDir, ITestOutputHelper output)
@@ -69,27 +93,27 @@ namespace JitBench
.Run();
}
- private static async Task<string> Publish(DotNetInstallation dotNetInstall, string outputDir, ITestOutputHelper output)
+ private async Task<string> Publish(DotNetInstallation dotNetInstall, string outputDir, ITestOutputHelper output)
{
string tfm = DotNetSetup.GetTargetFrameworkMonikerForFrameworkVersion(dotNetInstall.FrameworkVersion);
- string publishDir = GetMusicStorePublishDirectory(dotNetInstall, outputDir, tfm);
- string manifestPath = Path.Combine(GetMusicStoreStoreDir(outputDir), dotNetInstall.Architecture, tfm, "artifact.xml");
+ string publishDir = GetWebAppPublishDirectory(dotNetInstall, outputDir, tfm);
+ string manifestPath = Path.Combine(GetWebAppStoreDir(outputDir), dotNetInstall.Architecture, tfm, "artifact.xml");
if (publishDir != null)
{
FileTasks.DeleteDirectory(publishDir, output);
}
string dotNetExePath = dotNetInstall.DotNetExe;
await new ProcessRunner(dotNetExePath, $"publish -c Release -f {tfm} --manifest {manifestPath}")
- .WithWorkingDirectory(GetMusicStoreSrcDirectory(outputDir))
+ .WithWorkingDirectory(GetWebAppSrcDirectory(outputDir))
.WithEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
.WithEnvironmentVariable("JITBENCH_ASPNET_VERSION", "2.0")
.WithEnvironmentVariable("JITBENCH_TARGET_FRAMEWORK_MONIKER", tfm)
- .WithEnvironmentVariable("JITBENCH_TARGET_FRAMEWORK_VERSION", dotNetInstall.FrameworkVersion)
+ .WithEnvironmentVariable("JITBENCH_FRAMEWORK_VERSION", dotNetInstall.FrameworkVersion)
.WithEnvironmentVariable("UseSharedCompilation", "false")
.WithLog(output)
.Run();
- publishDir = GetMusicStorePublishDirectory(dotNetInstall, outputDir, tfm);
+ publishDir = GetWebAppPublishDirectory(dotNetInstall, outputDir, tfm);
if (publishDir == null)
{
throw new DirectoryNotFoundException("Could not find 'publish' directory");
@@ -179,7 +203,7 @@ namespace JitBench
/// <summary>
/// When serializing the result data to benchview this is called to determine if any of the metrics should be reported differently
- /// than they were collected. MusicStore uses this to collect several measurements in each iteration, then present those measurements
+ /// than they were collected. Both web apps use this to collect several measurements in each iteration, then present those measurements
/// to benchview as if each was the Duration metric of a distinct scenario test with its own set of iterations.
/// </summary>
public override bool TryGetBenchviewCustomMetricReporting(Metric originalMetric, out Metric newMetric, out string newScenarioModelName)
@@ -204,25 +228,22 @@ namespace JitBench
return true;
}
- static string GetJitBenchRepoRootDir(string outputDir)
+ protected static string GetJitBenchRepoRootDir(string outputDir)
{
return Path.Combine(outputDir, "J");
}
- static string GetMusicStoreSrcDirectory(string outputDir)
- {
- return Path.Combine(GetJitBenchRepoRootDir(outputDir), "src", "MusicStore");
- }
+ protected abstract string GetWebAppSrcDirectory(string outputDir);
- static string GetMusicStorePublishDirectory(DotNetInstallation dotNetInstall, string outputDir, string tfm)
+ string GetWebAppPublishDirectory(DotNetInstallation dotNetInstall, string outputDir, string tfm)
{
- string dir = Path.Combine(GetMusicStoreSrcDirectory(outputDir), "bin", dotNetInstall.Architecture, "Release", tfm, "publish");
+ string dir = Path.Combine(GetWebAppSrcDirectory(outputDir), "bin", dotNetInstall.Architecture, "Release", tfm, "publish");
if (Directory.Exists(dir))
{
return dir;
}
- dir = Path.Combine(GetMusicStoreSrcDirectory(outputDir), "bin", "Release", tfm, "publish");
+ dir = Path.Combine(GetWebAppSrcDirectory(outputDir), "bin", "Release", tfm, "publish");
if (Directory.Exists(dir))
{
return dir;
@@ -231,7 +252,7 @@ namespace JitBench
return null;
}
- static string GetMusicStoreStoreDir(string outputDir)
+ static string GetWebAppStoreDir(string outputDir)
{
return Path.Combine(GetJitBenchRepoRootDir(outputDir), StoreDirName);
}
@@ -242,7 +263,7 @@ namespace JitBench
}
private const string JitBenchRepoUrl = "https://github.com/aspnet/JitBench";
- private const string JitBenchCommitSha1Id = "6e1327b633e2d7d45f4c13f498fc27698ea5735a";
+ private const string JitBenchCommitSha1Id = "6bee730486f272d31f23f1033225090511f856f3";
private const string EnvironmentFileName = "JitBenchEnvironment.txt";
private const string StoreDirName = ".store";
private readonly Metric StartupMetric = new Metric("Startup", "ms");
diff --git a/tests/src/performance/Scenario/JitBench/Runner/Benchmark.cs b/tests/src/performance/Scenario/JitBench/Runner/Benchmark.cs
index b6b18acc7f..206cd556da 100644
--- a/tests/src/performance/Scenario/JitBench/Runner/Benchmark.cs
+++ b/tests/src/performance/Scenario/JitBench/Runner/Benchmark.cs
@@ -84,7 +84,7 @@ namespace JitBench
BenchmarkRunResult result = new BenchmarkRunResult(this, config);
StringBuilder stderr = new StringBuilder();
StringBuilder stdout = new StringBuilder();
- var scenarioConfiguration = new ScenarioTestConfiguration(TimeSpan.FromMilliseconds(60000), startInfo)
+ var scenarioConfiguration = new ScenarioTestConfiguration(TimeSpan.FromMinutes(1), startInfo)
{
//XUnitPerformanceHarness writes files to disk starting with {runid}-{ScenarioBenchmarkName}-{TestName}
TestName = (Name + "-" + config.Name).Replace(' ', '_'),
@@ -142,6 +142,7 @@ namespace JitBench
"coreclr.dll",
"dotnet.exe",
"MusicStore.dll",
+ "AllReady.dll",
"ntoskrnl.exe",
"System.Private.CoreLib.dll",
"Unknown",